The following mechanisms are available in the kernel to defer work to a bottom half: softirqs, tasklets, and work queues .
Softirqs are the basic bottom half mechanism and have strong locking requirements. They are used only by a
few performance-sensitive subsystems such as the networking layer, SCSI layer, and kernel timers.
Tasklets are built on top of softirqs and are easier to use. It's recommended to use tasklets unless you have crucial
scalability or speed requirements.
A primary difference between a softirq and a tasklet is that the former is reentrant whereas the latter isn't. Different instances of a softirq can run simultaneously on different processors, but that is not the case with tasklets.
Work queues are a third way to defer work from interrupt handlers. They execute in process context and are
allowed to sleep , so they can use drowsy functions such as mutexes.