2021-05-12 14:32:11
Linux中的中斷處理方法
1:中斷處理是需要注意的幾點
(1)在中斷上下文中,不能和使用者空間資料互動,也就是不能使用copy_to_user()和copy_from_user()。
(2)中斷上下文中,不能交出CPU(不能休眠、不能schedule、不能被打斷)。
(3)ISR執行時間盡可能短,越長則系統響應特性越差,為了節省中斷執行的時間,所以核心採用上半部分和下半部分的方式來處理中斷。
2:中斷上下半部的兩種解決方案
(1)為什麼要分上半部(top half,又叫頂半部,上半部分負責登記和記錄中斷,並啟用下半部,讓下半部得以執行)和下半部(bottom half,又叫底半部,下半部分主要負責真正的處理)。
(2)下半部處理策略1:tasklet(小任務)。
引入tasklet,最主要的是考慮支援SMP,提高SMP多個cpu的利用率;不同的tasklet可以在不同的cpu上執行。但是tasklet屬於中斷上下文,因此不能被阻塞,不能睡眠,不可被打斷。
(3)下半部處理策略2:workqueue(工作佇列)。
workqueue的突出特點是下半部會交給worker thead,因此下半部處於進程上下文,可以被重新排程,可以阻塞,也可以睡眠。workqueue的初始化方式有靜態和動態兩種。
靜態初始化:
呼叫宏DECLARE_WORK,初始化一個中斷的上半部,然後在中斷上半部呼叫schedule_work()啟動我們的中斷下半部
動態初始化
呼叫宏 INIT_WORK,初始化一個中斷的上半部,然後在中斷上半部呼叫queue_work()啟動我們的中斷下半部
簡單地說,一般的驅動程式的編寫者需要做兩個選擇。 首先,你是不是需要一個可排程的實體來執行需要推後完成的工作――從根本上來說,有休眠的需要嗎?要是有,工作佇列就是你的惟一選擇。 否則最好用tasklet。要是必須專注於效能的提高,那麼就考慮softirq。
3:中斷上下半部處理原則
(1)必須立即進行緊急處理的極少量任務放入在中斷的頂半部中,此時遮蔽了與自己同型別的中斷,由於任務量少,所以可以迅速不受打擾地處理完緊急任務。也就是要把執行時間短,緊急的任務放在上半部。
(2)需要較少時間的中等數量的急迫任務放在tasklet中。此時不會遮蔽任何中斷(包括與自己的頂半部同型別的中斷),所以不影響頂半部對緊急事務的處理;同時又不會進行使用者進程排程,從而保證了自己急迫任務得以迅速完成。也就是說,我們在上半部呼叫task_schedule去喚醒我們的下半部時,下半部並不是馬上被執行,系統會根據此時的CPU的使用情況,來選擇下半部是馬上被執行還是延時一段時間執行,假設在延時期間產生了一個上半部的中斷,那麼上半部就可以被先執行。
(3)需要較多時間且並不急迫(允許被作業系統剝奪執行權,也就是可以被呼叫)的大量任務放在workqueue中。此時作業系統會盡量快速處理完這個任務,但如果任務量太大,期間作業系統也會有機會排程別的使用者進程執行,從而保證不會因為這個任務需要執行時間將其它使用者進程無法進行。
(4)可能引起睡眠的任務放在workqueue中。因為在workqueue中睡眠是安全的。在需要獲得大量的記憶體時、在需要獲取號誌時,在需要執行阻塞式的I/O操作時,用workqueue很合適。
本文永久更新連結地址:http://www.linuxidc.com/Linux/2017-08/146264.htm
相關文章