close
貼一下最近發生的糗事,因為之前不知道這個function的差別,所以一直以為有一個driver在interrupt context裏面做了很多會sleep的動作,一開始還嘖嘖稱奇說為什麼這樣的driver會動
結果是我們沒見過世面,這算是書本上還來不及更新的知識吧,再這幾年linux新增進來的function,讓irq handle能更簡潔快速,一些會sleep的動作可以在一開始request irq 的時候就指定好要由kernel thread來執行
也因為是在kernel context下執行,所以他不受interrupt context的atomic限制,可以有sleep的動作(像是i2c,spi和semaphore)
傳統的irq handle只能用worqueue或是tasklet等來處理bottom half的部份,top half 就考量到hw interrupt不能咬住太久所以要馬上放掉
這種新的threaded irq 能夠再hw irq上得到更快速的處理吧
然後interrupt process的pid 其實不存在,他顯示的是interrupt進來前被中斷的process的pid,所以你會看到interrupt process可能並沒有固定pid的原因就是這個
p.s 要確定你寫code的地方是不是atomic可以用might_sleep() 來確定,如果再的地方是atomic 也就是不能sleep和preempt的地方,在log裏面你會看到他會顯示isatomic &call stack
注意這個isatomic不會狂吐,他是有timer固定一段時間吐一下的
Linux request_threaded_irq() 與 request_irq() 差異
一開始看到有 driver 用 request_threaded_irq() 以為是 request_irq() 誤植,Google 查
詢後才知道是 Linux kernel 2.6.30 之後新加的 irq handler API
如何確定可以用到 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() 的由來
http://lwn.net/Articles/302043/
從 realtime tree 移植而來,為了減少 kernel 因為要等每一個硬體中斷處理的時間
,就另外交給 kernel thread 處理中斷後續處理。
優點:
1 減少 kernel 延遲時間
2 避免處理中斷時要分辨是在硬體中斷或軟體中斷?
3 更容易為 kernel 中斷處理除錯,可能可完全取代 tasklet
原本的中斷處理分上半部(硬體中斷處理,必須關閉中斷無法處理新的中斷)跟下半部(
詢後才知道是 Linux kernel 2.6.30 之後新加的 irq handler API
如何確定可以用到 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() 的由來
http://lwn.net/Articles/302043/
從 realtime tree 移植而來,為了減少 kernel 因為要等每一個硬體中斷處理的時間
,就另外交給 kernel thread 處理中斷後續處理。
優點:
1 減少 kernel 延遲時間
2 避免處理中斷時要分辨是在硬體中斷或軟體中斷?
3 更容易為 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 補充:http://lwn.net/Articles/302553/
跟傳統 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 連結與溝通
的麻煩。
全站熱搜