日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux内核:关于中断你需要知道的【转】

發(fā)布時間:2025/1/21 linux 107 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux内核:关于中断你需要知道的【转】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉自:http://blog.csdn.net/duqi_2009/article/details/38009717

1、中斷處理程序與其他內(nèi)核函數(shù)真正的區(qū)別在于,中斷處理程序是被內(nèi)核調(diào)用來相應中斷的,而它們運行于中斷上下文(原子上下文)中,在該上下文中執(zhí)行的代碼不可阻塞。中斷就是由硬件打斷操作系統(tǒng)。

2、異常與中斷不同,它在產(chǎn)生時必須考慮與處理器時鐘同步。異常被稱為同步中斷,例如:除0、缺頁異常、陷入內(nèi)核(trap)引起系統(tǒng)調(diào)用處理程序異常。

3、不同的設備對應的中斷不同,而每個中斷都通過一個唯一的數(shù)字(中斷號)標識。

4、既想讓中斷處理程序運行得快,又想中斷處理程序完成的工作量多,為了在這兩個相悖的目標之間達到一種平衡,一般把中斷處理分為兩個部分。中斷處理程序是上半部(top half):接收到一個中斷,它就立刻開始執(zhí)行,但只做有嚴格時限的工作,例如對接受的中斷進行應答或者復位硬件,這些工作都是在中斷被禁止的情況下完成的(上半部情況下,中斷被禁止);另一部分是下半部(bottom half):能夠被允許稍后完成的工作會推遲到下半部。

(1)為什么要用下半部?

中斷處理程序執(zhí)行的時候,當前中斷號對應的中斷在所有處理器上都會被屏蔽;更糟糕的是,如果處理器程序是IRQF_DISABLED類型,它執(zhí)行的時候會把本地的所有中斷都屏蔽。然而,縮短中斷被屏蔽的時間對系統(tǒng)的響應能力和性能都至關重要,所以,我們應該盡力縮短中斷處理程序的時間,辦法就是把一些工作放到以后去做。關鍵是:在下半部運行的時候,允許響應所有中斷

(2)劃分中斷上半部和下半部的借鑒原則:

?

  • 如果一個任務對時間非常敏感,將其放在中斷處理程序中執(zhí)行
  • 如果一個任務和硬件相關,將其放在中斷處理程序中執(zhí)行。
  • 如果一個任務要保證部被其他中斷(特別是相同的中斷)打斷,將其放置在中斷處理程序中執(zhí)行。
  • 其他所有任務,考慮放置在下半部執(zhí)行

?

5、例子,網(wǎng)卡驅動程序,當網(wǎng)卡接收到來自網(wǎng)路的數(shù)據(jù)包時,需要通知內(nèi)核數(shù)據(jù)包到了。中斷處理程序(top half)立即開始執(zhí)行:通知硬件,拷貝最新的網(wǎng)絡數(shù)據(jù)到內(nèi)存,然后讀取網(wǎng)卡更多的數(shù)據(jù)包,這些工作非常緊迫,因為網(wǎng)卡上接受數(shù)據(jù)包的緩存大小固定;下半部:執(zhí)行處理和操作數(shù)據(jù)包的其他工作。

6、Linux提供的實現(xiàn)下半部的機制:(上半部的實現(xiàn)機制只有一種:中斷處理程序)

在Linux內(nèi)核2.6中,內(nèi)核提供了三種不同形式的下半部實現(xiàn)機制:軟中斷、tasklet和工作隊列。這三種機制從2.3開始引入。軟中斷用的比較少,tasklet是下半部更常用的一種形式,但是,tasklet是基于軟中斷實現(xiàn)的。

(1)如果你想加入一個新的軟中斷,首先應該問問自己為什么用tasklet實現(xiàn)不了,目前只有兩個子系統(tǒng)(網(wǎng)絡和SCSI)直接使用軟中斷。軟中斷只有在那些執(zhí)行頻率很高和連續(xù)性很高的情況下才需要使用。如果不需要擴展到多個處理器,那么就使用tasklet吧。tasklet本質(zhì)上也是軟中斷,只不過同一個處理器程序的多個實例不能再多個處理器上同時運行。

下半部何時調(diào)用?內(nèi)核在執(zhí)行完中斷處理器程序以后,do_softirq()函數(shù),于是軟中斷開始執(zhí)行中斷處理程序留給它去完成的剩余任務。大部分tasklet和軟中斷都是在中斷處理程序中被設置成待處理狀態(tài),所以最近一個中斷返回的時候就是執(zhí)行do_softirq()的最佳時機。

(2)tasklet_action()和tasklet_hi_action()是tasklet處理的核心。

(3)ksoftirqd輔助線程:每個處理器都有一組輔助處理軟中斷(和tasklet)的內(nèi)核線程,當內(nèi)核中出現(xiàn)大量軟中斷的時候,這些內(nèi)核進程就會輔助處理它們。當一個軟中斷正在執(zhí)行時,可能會再次觸發(fā)它自己,內(nèi)核目前采取的方案是:不會立即處理重新觸發(fā)的軟中斷,在大量軟中斷出現(xiàn)的時候,內(nèi)核會喚醒一組內(nèi)核線程(nice值是19)來處理這些負載。

?

[cpp]?view plaincopy print?
  • for(;;)??
  • {??
  • ?????if(!softirq_pending(cpu))?//如果沒有軟中斷,則調(diào)用schedule()??
  • ?????????schedule();??
  • ???????
  • ?????set_current_state(TASK_RUNNING);??
  • ???????
  • ?????while(softirq_pending(cpu)){??
  • ???????????do_softirq();??
  • ???????????if(need_resched())?//如有必要重新調(diào)度,每次迭代之后都會schedule()以便讓更重要的進程得到處理機會??
  • ?????????????????schedule();??
  • ?????}??
  • ??
  • ??????set_current_state(TASK_INTERRUPTIBLE);??
  • }??
  • ?

    (4)工作隊列(work queue)是另一種將工作任務推后的方式,與軟中斷和tasklet都不相同。工作隊列把工作交給一個內(nèi)核線程去執(zhí)行——這個下半部總是在進程上下文中執(zhí)行,最重要的,工作隊列允許重新調(diào)度甚至睡眠。所以,如果推后執(zhí)行的任務需要睡眠,那么就選擇工作隊列;如果推后的任務不需要睡眠,那么就選擇軟件中斷或者tasklet。如果需要使用一個可以重新調(diào)度的實體來執(zhí)行當前中斷的下半部任務,就應該使用工作隊列。工作隊列是唯一能在進程上下文中運行的下半部實現(xiàn)機制,也只有它才可以睡眠(關鍵是看你的任務是否需要睡眠)。盡管工作隊列的操作處理函數(shù)運行在進程上下文中,但是它不能訪問用戶空間,因為該內(nèi)核線程在用戶空間沒有相關的內(nèi)存映射。

    注意:mmc驅動中用到了工作隊列~

    Notice:通常在發(fā)生系統(tǒng)調(diào)用時,內(nèi)核會代表用戶空間的進程運行,此時它才能訪問用戶空間,也只有在此時它才會映射用戶空間的內(nèi)存。

    (5)下半部機制的選擇

    ?

    對下半部機制的比較
    下半部上下文順序執(zhí)行保障
    軟中斷中斷沒有
    tasklet中斷同類型不能同時執(zhí)行
    工作隊列進程沒有(和進程上下文一樣被調(diào)度)

    ?

    ?

    從易用性角度來看:工作隊列 > tasklet > 軟中斷

    總結:驅動程序的編寫者,需要做兩個選擇。首先,你是不是需要一個可調(diào)度的實體來執(zhí)行需要推后完成的工作——從根本上來說,你需要推后的工作任務有休眠的需要嗎?要是有,那么工作隊列就是唯一的選擇;否則最好用tasklet。其次,如果必須專注于性能的提高,那么就考慮軟中斷吧~

    (6)使用下半部機制時,即使是在一個單處理器的系統(tǒng)上,避免共享數(shù)據(jù)的訪問也是至關重要的。禁止下半部的函數(shù)有l(wèi)ocal_bh_disable()和local_bh_enable(),這兩個函數(shù)只能禁止和激活本地處理器的軟中斷和tasklet。因為工作隊列是在進程上下文中運行的,不會涉及異步執(zhí)行的問題,所以也就沒必要禁止它們執(zhí)行。

    ?

    7、在驅動程序中,要申請中斷(注冊中斷處理程序)

    ?

    [cpp]?view plaincopy print?
  • request_threaded_irq(unsigned?int?irq,?irq_handler_t?handler,??
  • ?????????????irq_handler_t?thread_fn,??
  • ?????????????unsigned?long?flags,?const?char?*name,?void?*dev);??

  • ??irq? 需要申請的irq編號,對于ARM體系,irq編號通常在平臺級的代碼中事先定義好,有時候也可以動態(tài)申請。

    ?

    ?

    ??handler? 中斷服務回調(diào)函數(shù),該回調(diào)運行在中斷上下文中,并且cpu的本地中斷處于關閉狀態(tài),所以該回調(diào)函數(shù)應該只是執(zhí)行需要快速響應的操作,執(zhí)行時間應該盡可能短小,耗時的工作最好留給下面的thread_fn回調(diào)處理。

    ??thread_fn? 如果該參數(shù)不為NULL,內(nèi)核會為該irq創(chuàng)建一個內(nèi)核線程,當中斷發(fā)生時,如果handler回調(diào)返回值是IRQ_WAKE_THREAD,內(nèi)核將會激活中斷線程,在中斷線程中,該回調(diào)函數(shù)將被調(diào)用,所以,該回調(diào)函數(shù)運行在進程上下文中,允許進行阻塞操作

    ??flags? 控制中斷行為的位標志,IRQF_XXXX,例如:IRQF_TRIGGER_RISING,IRQF_TRIGGER_LOW,IRQF_SHARED等,在include/linux/interrupt.h中定義。

    ??name? 申請本中斷服務的設備名稱,同時也作為中斷線程的名稱,該名稱可以在/proc/interrupts文件中顯示。

    ??dev? 當多個設備的中斷線共享同一個irq時,它會作為handler的參數(shù),用于區(qū)分不同的設備。free_irq()函數(shù)調(diào)用的時候,dev的作用就體現(xiàn)出來了。

    8、irq_handler_t的類型定義如下:

    ?

    [cpp]?view plaincopy print?
  • typedef?irqreturn_t??(*irq_handler_t)(int,void*);??
  • ?

    用typedef 定義了一個函數(shù)指針類型irq_handler_t,指向的函數(shù)原型返回類型為 irqreturn_t ?;它接收的參數(shù)類型就是int 和void* 兩個參數(shù)

    9、request_threaded_irq()函數(shù)是可以睡眠的,因為request_threaded_irq()-->proc_mkdir()-->proc_create()-->kmalloc(),而kmalloc()是可以睡眠的。所以,不能在中斷上下文中調(diào)用該函數(shù)。

    10、先初始化硬件,然后再注冊中斷處理程序,以防止中斷處理程序在設備初始化完成之前就開始執(zhí)行。

    11、free_irq():如果在給定的中斷線上沒有中斷處理程序,則注銷響應的處理程序,并禁用其中斷線。

    12、中斷處理程序即使什么工作也不做,至少需要知道產(chǎn)生中斷的設備,告訴它已經(jīng)收到中斷了;對于復雜的設備,可能還需要在中斷處理器程序中發(fā)送和接收數(shù)據(jù),以及執(zhí)行一些擴充的工作。這些擴充的工作盡可能被推遲到下半部(bottom half)去完成。

    13、中斷線和中斷號是兩個相同的概念,irq

    14、Linux中的中斷處理程序是無需重入的,當一個給定的中斷處理程序正在執(zhí)行時,相應的中斷號在所有處理器上都是被屏蔽掉;所以,同一個中斷處理程序絕對不會被同時調(diào)用以處理嵌套中斷。

    15、進程上下文:一種內(nèi)核所處的操作模式,此時內(nèi)核代表進程執(zhí)行——例如,執(zhí)行系統(tǒng)調(diào)用或者運行內(nèi)核線程。在進程上下文中,可以通過current宏關聯(lián)當前進程。又因為進程是以進程上下文的形式連接到內(nèi)核的,因此,進程上下文可以睡眠,也可以調(diào)用調(diào)度程序

    16、中斷上下文:與進程沒什么關系,與current宏也沒有關系,所以中斷上下文不可以睡眠,在中斷上下文中不可以調(diào)用任何可能睡眠的函數(shù)。

    17、中斷處理程序打斷了其他的代碼的執(zhí)行,所以中斷上下文中的代碼應該簡潔、迅速,盡可能把工作從中斷處理程序中分離出來,放在下半部執(zhí)行。

    18、中斷處理程序棧的設置是一個內(nèi)核配置項,如果有的話,是1頁大小,即4KB

    19、控制中斷系統(tǒng)的原因歸根結底是需要提供同步。禁止中斷提供保護機制,防止來自其他中斷程序的并發(fā)訪問,也能夠禁止內(nèi)核搶占;提供保護機制,防止來自其他處理器的并發(fā)訪問(SMP系統(tǒng)需要考慮)

    轉載于:https://www.cnblogs.com/sky-heaven/p/5531416.html

    總結

    以上是生活随笔為你收集整理的Linux内核:关于中断你需要知道的【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。