Chapter 7:Bottom Halves and Deferring Work

12
1 Chapter 7:Bottom Halves and Deferring Work Zhang Xiang-bo WMN Lab

description

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 - PowerPoint PPT Presentation

Transcript of Chapter 7:Bottom Halves and Deferring Work

Page 1: Chapter 7:Bottom Halves and Deferring Work

1

Chapter 7:Bottom Halves and Deferring Work

Zhang Xiang-boWMN Lab

Page 2: Chapter 7:Bottom Halves and Deferring Work

2

Bottom Halves The job of bottom halves is to perform any interrupt-related

work not performed by the interrupt handler itself.

Main process

interrupt

top

bottom

1.If the work is time sensitive2.If the work is related to the hardware itself3.If the work needs to ensure that another interrupt does not interrupt it

For everything else

Page 3: Chapter 7:Bottom Halves and Deferring Work

3

Why we divide the interrupt into two parties? Interrupt handlers run asynchronously and thus interrupt oth

er 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

Page 4: Chapter 7:Bottom Halves and Deferring Work

4

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.

Page 5: Chapter 7:Bottom Halves and Deferring Work

5

Executing Softirqs u32 pending = softirq_pending(cp

u); if (pending) { struct softirq_action *h = softirq_v

ec; softirq_pending(cpu) = 0; do { if (pending & 1) h->action(h); h++; pending >>= 1; } while (pending); }

1 1 1

0

31

Bitmap

①Pending = 100101

② Pending = 001010

③ Pending = 010100

④ Pending = 101000

⑤ Pending = 010000

⑥ Pending = 100000

1 0 010 1

Page 6: Chapter 7:Bottom Halves and Deferring Work

6

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.

Page 7: Chapter 7:Bottom Halves and Deferring Work

7

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) */};

File: include\interrupt.h

enum{

TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */TASKLET_STATE_RUN /* Tasklet is running (SMP only) */

};

Page 8: Chapter 7:Bottom Halves and Deferring Work

8

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 i

t at the proper time.

Page 9: Chapter 7:Bottom Halves and Deferring Work

9

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.

Page 10: Chapter 7:Bottom Halves and Deferring Work

10

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)

Page 11: Chapter 7:Bottom Halves and Deferring Work

11

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.

Page 12: Chapter 7:Bottom Halves and Deferring Work

12

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.