DOC PREVIEW
USF CS 635 - Kernel timing issues

This preview shows page 1-2-3-25-26-27 out of 27 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 27 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 27 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 27 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 27 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 27 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 27 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 27 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

Kernel timing issuesKernel timersjiffiesjiffies overflowKernel timer syntaxA kernel-timer caution‘trytimer.c’Delaying workProgramming syntax‘tryworkq.c’ and ‘defermsg.c’Applying these ideasReducing CPU’s usageIn-class exerciseImplementation hintsDeferring work‘sizeof’ and ‘offsetof’A ‘struct’ exampleThe ‘container_of()’ macroUsing ‘container_of()’Slide 20‘workqueue’ syntax‘tryworkq.c’An improved example‘timer’ verses ‘workqueue’If ‘dowork()’ needs data…‘defermsg.c’Summary of tonight’s demosKernel timing issuesAn introduction to the use of kernel timers and work queuesKernel timers•Linux offers a facility that lets drivers put a process to sleep until a fixed amount of time has elapsed (as measured in jiffies)•When the timer expires, a driver-defined action will be performed, which can ‘wake up’ the process that was put to sleep, or could perform some alternative action (for example, the kernel timer could re-start)jiffies•unsigned long volatile jiffies; •global kernel variable (used by scheduler)•initialized to zero when system reboots•gets incremented during a timer interrupt•so it counts ‘clock-ticks’ since cpu restart•‘tick-frequency’ is a ‘configuration’ option•On our machines: HZ=250 (in ‘.config’)jiffies overflow•Won’t overflow for at least 16 months•Linux kernel got modified to ‘fix’ overflow•Now the declaration is in ‘linux/jiffies.h’:unsigned long long jiffies_64; and a new instruction in ‘do_timer()’ (*(u64*)&jiffies_64)++;which compiles to assembly language asadd $1, jiffies+0adc $0, jiffies+4Kernel timer syntax•Declare a timer: struct timer_list mytimer;•Initialize this timer: init_timer( &mytimer );mytimer.func = mytimeraction;mytimer.data = (unsigned long)mydata;mytimer.expires = <number-of-jiffies>•Install this timer: add_timer( &mytimer );•Modify this timer: mod_timer( &mytimer, <jifs> );•Delete this timer: del_timer( &mytimer );•Delete it safely: del_timer_sync( &mytimer);A kernel-timer caution•A kernel timer’s timeout-action cannot do anything that could cause the current task to ‘sleep’ (such as copying data between user-space and kernel-space, or trying to allocate more kernel memory)•However, to aid debugging, a timer CAN use ‘printk()’ within its timeout-routine‘trytimer.c’•We have posted an example that shows how a Linux kernel timer can be used to perform a periodic action (such as using ‘printk()’ to issue a message every time the time expires, then restart the timer •Notice that our demo is not able to issue messages directly to the console – its timer-function executes without a ‘tty’Delaying work•If a device-driver needs to perform actions that require using process resources (like a tty), or that may possibly ‘sleep’, then it can defer that work – using a ‘workqueue’Programming syntax•Declare: struct workqueue_struct *myqueue; struct work_struct thework; •Define: void dowork( void *data ) { /* actions */ };•Initialize: myqueue = create_singlethread_workqueue( “mywork” );INIT_WORK( &thework, dowork, <data-pointer> );•Schedule: queue_dalayed_work( myqueue, &thework, <delay> );•Cleanup: if ( !cancel_delayed_work( &thework ) )flush_workqueue( myqueue );destroy_workqueue( myqueue );‘tryworkq.c’ and ‘defermsg.c’•We have posted demo-modules that show the use of workqueues to perform actions later, either as soon as a ‘process context’ is available, or after a prescribed time •Further details on the options for using an existing kernel workqueue or a workqueue of your own creation may be found in our textbook (Chapter 7 of LDD3)Applying these ideas•To demonstrate a programming situation in which using kernel timers is valuable, we created the ‘foo.c’ device-driver, plus an application that uses it (‘watchfoo.cpp’)•You can compile and install the module, then execute the application: $ watchfoo•But you will notice there are two ‘problems’ (excess cpu usage and loop-termination)Reducing CPU’s usage •The ‘watchfoo’ program rereads ‘/dev/foo’ constantly (numerous times per second), much faster than the human eye can see•If you run the ‘top’ utility, you will see that a high percentage of the available CPU time is being consumed by ‘watchfoo’•You can add a kernel timer to the ‘foo.c’ driver to curtail this excessive readingIn-class exercise•Modify ‘foo.c’ (call it ‘timedfoo.c’) as follows•Create an integer flag-variable (‘ready’) as a global object in your module•When your ‘read()’ function gets called, it should sleep until ‘ready’ equals TRUE; it should set ‘ready’ equal to FALSE when it awakens, but should set a timer to expire after 1/10 seconds •Your timer’s action-function should set ‘ready’ back to TRUE, then wake up any sleeping tasksImplementation hints•You need a wait-queue (so your driver’s ‘reader’ tasks can sleep on it)•You need a timer action-function•You need to organize your timer-function’s data-items into a single structure (because the timer-function has only one argument)•Your timer-function must do two things:–Change ‘ready’ to TRUE–Wake up any ‘sleepers’Deferring work•Linux supports a ‘workqueue’ mechanism which allows the kernel to defer specified work until some later point in time•This mechanism has been ‘reworked’ in a major way since our texts were published•So any device-driver has to be modified if it made any use of a kernel ‘workqueue’ •Changes require grasp of some ‘macros’‘sizeof’ and ‘offsetof’•Our GNU compilers permit use of these C/C++ operators on object types•The ‘sizeof’ operator returns the number of bytes of memory the compiler allocated for storing the specified object •The ‘offsetof’ operator returns the number of bytes in a structure which precede the specified structure-memberA ‘struct’ examplestruct mystruct {char w;short x;long y;long long z;} my_instance;You can use the ‘sizeof’ operator to find out how much memory gets allocated to any ‘struct mystruct’ object, like this:int nbytes = sizeof( my_instance );You can use the ‘offsetof’’ operator to find out where within a given structure a particular field occurs, like this:int offset_z = offsetof( struct mystruct, z );The ‘container_of()’


View Full Document

USF CS 635 - Kernel timing issues

Download Kernel timing issues
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Kernel timing issues and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Kernel timing issues 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?