34
votes

There are many ways to schedule work in the linux kernel: timers, tasklets, work queues, and kernel threads. What are the guidelines for when to use one vs another?

There are the obvious factors: timer functions and tasklets cannot sleep, so they cannot wait on mutexes, condition variables, etc.

What are the other factors in choosing which mechanism to us in a driver?

Which are the preferred mechanisms?

3

3 Answers

35
votes
softirqs : deferred work runs in interrupt context
tasklets : deferred work runs in interrupt context
work queues : deferred work runs in process context

softirqs : Softirqs of the same type can run concurrently on several CPUs.
tasklets : Tasklets of different types can run concurrently on several CPUs, but tasklets of the same type cannot.
work queues : can run simultaneously on different CPU's

softirqs : cannot go to sleep
tasklets : cannot go to sleep
work queues : can go to sleep

softirqs : cannot be preempted/schedule
tasklets : cannot be preempted/schedule
work queues : maybe be preempted/schedule

softirqs : not easy to use
tasklets : easy to use
work queues : easy to use
32
votes

As you said, it depends on the task at hand:

Work queues defer work into a kernel thread - your work will always run in process context. They are schedulable and can therefore sleep.

Normally, there is no debate between work queues or sotftirqs/tasklets; if the deferred work needs to sleep, work queues are used, otherwise softirqs or tasklets are used. Tasklets are also more suitable for interrupt handling (they are given certain assurances such as: a tasklet is never ran later than on the next tick, it's always serialized with regard to itself, etc.).

Kernel timers are good when you know exactly when you want something to happen, and do not want to interrupt/block a process in the meantime. They run outside process context, and they are also asynchronous with regard to other code, so they're the source of race conditions if you're not careful.

Hope this helps.

1
votes

Kernel threads form the basis for Work Queues. They are the only types of kernel helper routines that run within the process context.