Верхняя половина - функция, которая непосредственно вызывается при генерации прерывания, по сути - interrupt service routine(isr). В этот момент задача этой функции совершить минимум действий и возвратить управление коду ядра с того момента, как этот код был прерван.
Нижняя половина - тоже функция(не странно ли? =) ), которая выполняется уже не в контексте прерывания(хотя некоторые говорят, что во время прерывания контекст остутсвует), а после возврата из прерывания. Обычно (генерируется|планируется) из isr.
В ядре Линукс реализация нижних половин представлена следующим многообразием - bottom half - устарело и не используется, оставлено для совместимости; softirq(он же механизм отложенных прерываний, не путать с napi), tasklets, workqueue.
Пример на сетевой подсистеме ядра Линукс:
В ядре Линукс сетевая подсистема реализована через механизм отложенных прерываний(softirq).
- берем драйвер drivers/net/e1000e/netdev.c,
- там есть функция e1000_intr_msi - это и есть isr в режиме MSI/MSI-X compatible,
- если посмотреть, в теле этой функции есть вызов функции __napi_schedule(&adapter->napi) - это обертка для реализации NAPI, и \
генерации отоженного прерывания через __raise_softirq_irqoff(NET_RX_SOFTIRQ);
- после генерации отложенного прерывания, оно может быть выполнено непосредственно после возврата из прерывания, либо в контекстве ядерного thread'а ksoftirqd
Как то так.