140 likes | 353 Views
Chapter 7:Bottom Halves and Deferring Work. Zhang Xiang-bo WMN Lab. Bottom Halves. The job of bottom halves is to perform any interrupt-related work not performed by the interrupt handler itself. Main process. interrupt. 1.If the work is time sensitive
E N D
Chapter 7:Bottom Halves and Deferring Work Zhang Xiang-bo WMN Lab
Bottom Halves • The job of bottom halves is to perform any interrupt-related work not performed by the interrupt handler itself. Main process interrupt 1.If the work is time sensitive 2.If the work is related to the hardware itself 3.If the work needs to ensure that another interrupt does not interrupt it top bottom For everything else
Why we divide the interrupt into two parties? • Interrupt handlers run asynchronously and thus interrupt other potentially important code, including other interrupt handlers. Therefore, to avoid stalling the interrupted code for too long, interrupt handlers need to run as quickly as possible. • We hope to limit the amount of work you perform in an interrupt handler, so handle interrupt time is the less the better. • So in an interrupt handler only do some necessary work, and defer some of the work until later • Three methods : softirqs, tasklets, and work queues
Softirqs • A 32-entry array of software irq is declare in kernel/softirq.c • This is fixed – the max number of registered softirqs can not be dynamically changed. • It runs with all interrupt enabled. A softirq never preempts another softirq.The only event that can preempt a softirq is an interrupt handler. • Another softirq, even the same one can run on another processor.
Executing Softirqs • u32 pending = softirq_pending(cpu); • if (pending) { • struct softirq_action *h = softirq_vec; • softirq_pending(cpu) = 0; • do { • if (pending & 1) • h->action(h); • h++; • pending >>= 1; • } while (pending); • } ①Pending = 100101 ② Pending = 001010 ③ Pending = 010100 ④ Pending = 101000 ⑤ Pending = 010000 ⑥ Pending = 100000 0 1 0 0 1 0 1 Bitmap 31
Tasklets • Tasklets are implemented on top of softirqs, they are softirqs. • Tasklet is running only on one CPU simultaneously. Note: the softirq, even the same one can run on another processor. • Different tasklets may be run simultaneously on different CPUs. • If tasklet_schedule() is called, then tasklet is guaranteed to be executed on some cpu at least once after this. • Before running the tasklet, we have to know that the tasklet is not running elsewhere and has a zero count.
Tasklets structure struct tasklet_struct { struct tasklet_struct *next; unsigned long state; atomic_t count; /*reference count */ void (*func)(unsigned long); /*tasklet handler function*/ unsigned long data; /*argument to the tasklet function func(data) */ }; enum { TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ TASKLET_STATE_RUN /* Tasklet is running (SMP only) */ }; File: include\interrupt.h
Using tasklet • Writing your tasklet handler • void my_tasklet_fun (unsigned long data) • Declaring your tasklet • static DECLARE_TASKLET(my_tasklet,my_tasklet_func,data); • Scheduling your tasklet • tasklet_schedule(&my_tasklet) Register my_tasklet, and then allow the system schedule it at the proper time.
Work queue • Work queues defer work into a kernel thread – the work always runs in process context. • If the deferred work needs to sleep, work queues are used. If the deferred work need not sleep, softirq or tasklets are used. • Work queues are useful for situations where you need to allocate a lot of memory, obtain a semaphore, or perform block I/O.
Using Work queues • Work queues are really easy to use! • Create Work • Static DECLARE_WORK(name, void(*function)(viod*), void*data); • Scheduling Work • schedule_work(&work) • schedule_delayed_work(&work, delay) • Flushing Work • void flush_scheduled_work(void) • Cancel Work • int cancel_delayed_work(struct work_struct *work)
Which bottom half should I use? • By design, Softirqs, provide the least serialization. • This requires Softirq handlers to go through extra steps to ensure data is safe, as two or more softirqs of the same type may run concurrently on different processors. • Softirqs are the fastest alternative for timing-critical and high-frequency uses.
Tasklets make more sense if the code is not finely threaded. • Tasklets have a simpler interface and because two tasklets of the same type might not run concurrently, they are easier to implement. • If your deferred work needs to run in process context, your only choice is work queue.