如何確定可以用到 request_threaded_irq() ?
Linux kernel config 需要定義 CONFIG_GENERIC_HARDIQS kernel config 才有支援 threaded irq
原因是在 include/linux/interrupt.h
#ifdef CONFIG_GENERIC_HARDIRQS
函式定義位置在:
~linux/kernel/irq/manage.c
1306 int request_threaded_irq(unsigned int irq, irq_handler_t handler,
1307 irq_handler_t thread_fn, unsigned long irqflags,
1308 const char *devname, void *dev_id)
request_threaded_irq: kernel thread context ist
request_irq: direct function call from hardware IRQ isr
Moving interrupts to threads 介紹 request_threaded_irq() 的由來,從 realtime tree 移植而來,為了減少 kernel 因為要等每一個硬體中斷處理的時間,就另外交給 kernel thread 處理中斷後續處理。
優點:
- 減少 kernel 延遲時間
- 避免處理中斷時要分辨是在硬體中斷或軟體中斷?
- 更容易為 kernel 中斷處理除錯,可能可完全取代 tasklet
原本的中斷處理分上半部(硬體中斷處理,必須關閉中斷無法處理新的中斷)跟下半部(軟體中斷處理),因此上半部的硬體中斷處理必須盡可能簡短,讓系統反應速度更快。
request_threaded_irq 是在將上半部的硬體中斷處理更加縮短為,只確定硬體中斷來自我們要處理的裝置,喚醒 kernel thread 執行後續中斷處理。只有將 tasklet 跟 softirq 處理都放到 threaded_irq 的 kernel thread 中,才能發揮最大的系統效能增益。
原本在 reuqest_irq 的 handler 變成快速檢查用的 handler function,
缺點:
對於非處理 irq 中斷的 kernel threads ,需要在原本 task_struct 新增 struct irqaction 多佔 4/8 bytes 記憶體空間,linux kernel 2.6.29 之後(2.6.30)加入 request_threaded_irq
nested top halves?
jlokier 在回覆 Moving interrupts to threads 補充:跟傳統 top/bottom havles 的差異是 threaded_irq 受限於 Linux kernel system 的 process scheduling 控制。較不會發生寫錯的 bottom half 程式碼造成整個系統延遲的問題。
也可以透過 RT/non RT 跟 nice 等工具調整各個 thread 優先權,丟給使用率較低的 cpu 以及受惠於 kernel 原本可以對 threads 做的各種控制,包括但不限於 sleep, lock, allocate 新的記憶體區塊。
受惠最大的是 shared irq line 的多個中斷處理。除了可以加速共享中斷造成的延遲,threaded_irq 也可以降低在同一段程式碼處理多個裝置中斷的複雜度。
threaded irq 在使用性上也比 tasklet(接著 top half 直接執行,無法 sleep) /workqueue(kernel context?) 等需要在 top half 增加跟 bottom half 連結與溝通的麻煩。