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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

硬中断、软中断和信号

發(fā)布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 硬中断、软中断和信号 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

硬中斷:

1. 硬中斷是由硬件產(chǎn)生的,比如,像磁盤,網(wǎng)卡,鍵盤,時鐘等。每個設(shè)備或設(shè)備集都有它自己的IRQ(中斷請求)。基于IRQ,CPU可以將相應(yīng)的請求分發(fā)到對應(yīng)的硬件驅(qū)動上(注:硬件驅(qū)動通常是內(nèi)核中的一個子程序,而不是一個獨立的進(jìn)程)。

2. 處理中斷的驅(qū)動是需要運(yùn)行在CPU上的,因此,當(dāng)中斷產(chǎn)生的時候,CPU會中斷當(dāng)前正在運(yùn)行的任務(wù),來處理中斷。在有多核心的系統(tǒng)上,一個中斷通常只能中斷一顆CPU(也有一種特殊的情況,就是在大型主機(jī)上是有硬件通道的,它可以在沒有主CPU的支持下,可以同時處理多個中斷。)。

3. 硬中斷可以直接中斷CPU。它會引起內(nèi)核中相關(guān)的代碼被觸發(fā)。對于那些需要花費(fèi)一些時間去處理的進(jìn)程,中斷代碼本身也可以被其他的硬中斷中斷。

4. 對于時鐘中斷,內(nèi)核調(diào)度代碼會將當(dāng)前正在運(yùn)行的進(jìn)程掛起,從而讓其他的進(jìn)程來運(yùn)行。它的存在是為了讓調(diào)度代碼(或稱為調(diào)度器)可以調(diào)度多任務(wù)。

軟中斷:

1. 軟中斷的處理非常像硬中斷。然而,它們僅僅是由當(dāng)前正在運(yùn)行的進(jìn)程所產(chǎn)生的。

2. 通常,軟中斷是一些對I/O的請求。這些請求會調(diào)用內(nèi)核中可以調(diào)度I/O發(fā)生的程序。對于某些設(shè)備,I/O請求需要被立即處理,而磁盤I/O請求通常可以排隊并且可以稍后處理。根據(jù)I/O模型的不同,進(jìn)程或許會被掛起直到I/O完成,此時內(nèi)核調(diào)度器就會選擇另一個進(jìn)程去運(yùn)行。I/O可以在進(jìn)程之間產(chǎn)生并且調(diào)度過程通常和磁盤I/O的方式是相同。

3. 軟中斷僅與內(nèi)核相聯(lián)系。而內(nèi)核主要負(fù)責(zé)對需要運(yùn)行的任何其他的進(jìn)程進(jìn)行調(diào)度。一些內(nèi)核允許設(shè)備驅(qū)動的一些部分存在于用戶空間,并且當(dāng)需要的時候內(nèi)核也會調(diào)度這個進(jìn)程去運(yùn)行。

4. 軟中斷并不會直接中斷CPU。也只有當(dāng)前正在運(yùn)行的代碼(或進(jìn)程)才會產(chǎn)生軟中斷。這種中斷是一種需要內(nèi)核為正在運(yùn)行的進(jìn)程去做一些事情(通常為I/O)的請求。有一個特殊的軟中斷是Yield調(diào)用,它的作用是請求內(nèi)核調(diào)度器去查看是否有一些其他的進(jìn)程可以運(yùn)行。

問題解答:

1. 問:對于軟中斷,I/O操作是否是由內(nèi)核中的I/O設(shè)備驅(qū)動程序完成?

答:對于I/O請求,內(nèi)核會將這項工作分派給合適的內(nèi)核驅(qū)動程序,這個程序會對I/O進(jìn)行隊列化,以可以稍后處理(通常是磁盤I/O),或如果可能可以立即執(zhí)行它。通常,當(dāng)對硬中斷進(jìn)行回應(yīng)的時候,這個隊列會被驅(qū)動所處理。當(dāng)一個I/O請求完成的時候,下一個在隊列中的I/O請求就會發(fā)送到這個設(shè)備上。

2. 問:軟中斷所經(jīng)過的操作流程是比硬中斷的少嗎?換句話說,對于軟中斷就是:進(jìn)程 ->內(nèi)核中的設(shè)備驅(qū)動程序;對于硬中斷:硬件->CPU->內(nèi)核中的設(shè)備驅(qū)動程序?

答:是的,軟中斷比硬中斷少了一個硬件發(fā)送信號的步驟。產(chǎn)生軟中斷的進(jìn)程一定是當(dāng)前正在運(yùn)行的進(jìn)程,因此它們不會中斷CPU。但是它們會中斷調(diào)用代碼的流程。

如果硬件需要CPU去做一些事情,那么這個硬件會使CPU中斷當(dāng)前正在運(yùn)行的代碼。而后CPU會將當(dāng)前正在運(yùn)行進(jìn)程的當(dāng)前狀態(tài)放到堆棧(stack)中,以至于之后可以返回繼續(xù)運(yùn)行。這種中斷可以停止一個正在運(yùn)行的進(jìn)程;可以停止正處理另一個中斷的內(nèi)核代碼;或者可以停止空閑進(jìn)程。


轉(zhuǎn)自:?http://www.linuxidc.com/Linux/2014-03/98013.htm


硬中斷是外部設(shè)備對CPU的中斷,軟中斷是中斷底半部的一種處理機(jī)制,信號則是由內(nèi)核(或其他進(jìn)程)對某個進(jìn)程的中斷。

?

①硬中斷是由外部事件引起的因此具有隨機(jī)性和突發(fā)性; ?? 軟中斷是執(zhí)行中斷指令產(chǎn)生的,無面外部施加中斷請求信號,因此中斷的發(fā)生不是隨機(jī)的而是由程序安排好的。
②硬中斷的中斷響應(yīng)周期,CPU需要發(fā)中斷回合信號(NMI不需要);
?? 軟中斷的中斷響應(yīng)周期,CPU不需發(fā)中斷回合信號。
③硬中斷的中斷號是由中斷控制器提供的(NMI硬中斷中斷號系統(tǒng)指定為02H);
?? 軟中斷的中斷號由指令直接給出,無需使用中斷控制器。
④硬中斷是可屏蔽的(NMI硬中斷不可屏蔽);
?? 軟中斷不可屏蔽。

?????? 軟中斷是一種推后執(zhí)行的機(jī)制。定時器、網(wǎng)卡的數(shù)據(jù)的處理是很典型的軟中斷,這個和中斷向 量表里的中斷是完全不一樣的。以網(wǎng)絡(luò)數(shù)據(jù)的處理為例,當(dāng)網(wǎng)卡接到一個數(shù)據(jù)包后,其中斷處理程序只是把數(shù)據(jù)復(fù)制到緩沖區(qū),然后就告訴網(wǎng)卡,你可以再傳數(shù)據(jù)給 我了,也就是中斷返回。但在此之前,網(wǎng)卡的中斷處理程序要置一個標(biāo)志位,告訴操作系統(tǒng)有事要做,這個事就是軟中斷。但軟中斷只是很多中斷返回時要做的事情 之一,操作系統(tǒng)每次中斷返回時會檢查著個標(biāo)志位,看是否有事要做,如果有,就會去處理,象前面提到的網(wǎng)卡,這時候操作系統(tǒng)就回調(diào)用軟中斷的處理函數(shù)。網(wǎng)卡 的軟中斷程序就是做分析數(shù)據(jù)包啊,這個數(shù)據(jù)應(yīng)該傳給誰啊等這些工作,沒有,就返回了,除了必須的部分。


編寫兩個中斷服務(wù)函數(shù)的區(qū)別
1.軟中斷發(fā)生的時間是由程序控制的,而硬中斷發(fā)生的時間是隨機(jī)的?
2.軟中斷是由程序調(diào)用發(fā)生的,而硬中斷是由外設(shè)引發(fā)的?
3.硬件中斷處理程序要確保它能快速地完成它的任務(wù),這樣程序執(zhí)行時才不會等侍較長時間?
編寫這兩類的中斷處理程序我感覺區(qū)別不太大

轉(zhuǎn)自:?http://blog.csdn.net/u010820757/article/details/48930303




本文主要內(nèi)容:硬中斷 / 軟中斷的原理和實現(xiàn)

內(nèi)核版本:2.6.37

Author:zhangskd @ csdn blog

?

概述

?

從本質(zhì)上來講,中斷是一種電信號,當(dāng)設(shè)備有某種事件發(fā)生時,它就會產(chǎn)生中斷,通過總線把電信號發(fā)送給中斷控制器。

如果中斷的線是激活的,中斷控制器就把電信號發(fā)送給處理器的某個特定引腳。處理器于是立即停止自己正在做的事,

跳到中斷處理程序的入口點,進(jìn)行中斷處理。

?

(1) 硬中斷

由與系統(tǒng)相連的外設(shè)(比如網(wǎng)卡、硬盤)自動產(chǎn)生的。主要是用來通知操作系統(tǒng)系統(tǒng)外設(shè)狀態(tài)的變化。比如當(dāng)網(wǎng)卡收到數(shù)據(jù)包

的時候,就會發(fā)出一個中斷。我們通常所說的中斷指的是硬中斷(hardirq)。

?

(2) 軟中斷

為了滿足實時系統(tǒng)的要求,中斷處理應(yīng)該是越快越好。linux為了實現(xiàn)這個特點,當(dāng)中斷發(fā)生的時候,硬中斷處理那些短時間

就可以完成的工作,而將那些處理事件比較長的工作,放到中斷之后來完成,也就是軟中斷(softirq)來完成。

?

(3) 中斷嵌套

Linux下硬中斷是可以嵌套的,但是沒有優(yōu)先級的概念,也就是說任何一個新的中斷都可以打斷正在執(zhí)行的中斷,但同種中斷

除外。軟中斷不能嵌套,但相同類型的軟中斷可以在不同CPU上并行執(zhí)行。

?

(4) 軟中斷指令

int是軟中斷指令。

中斷向量表是中斷號和中斷處理函數(shù)地址的對應(yīng)表。

int n - 觸發(fā)軟中斷n。相應(yīng)的中斷處理函數(shù)的地址為:中斷向量表地址 + 4 * n。

?

(5)硬中斷和軟中斷的區(qū)別

軟中斷是執(zhí)行中斷指令產(chǎn)生的,而硬中斷是由外設(shè)引發(fā)的。

硬中斷的中斷號是由中斷控制器提供的,軟中斷的中斷號由指令直接指出,無需使用中斷控制器。

硬中斷是可屏蔽的,軟中斷不可屏蔽。

硬中斷處理程序要確保它能快速地完成任務(wù),這樣程序執(zhí)行時才不會等待較長時間,稱為上半部。

軟中斷處理硬中斷未完成的工作,是一種推后執(zhí)行的機(jī)制,屬于下半部。?

?

開關(guān)

?

(1) 硬中斷的開關(guān)

簡單禁止和激活當(dāng)前處理器上的本地中斷:

local_irq_disable();

local_irq_enable();

保存本地中斷系統(tǒng)狀態(tài)下的禁止和激活:

unsigned long flags;

local_irq_save(flags);

local_irq_restore(flags);

?

(2) 軟中斷的開關(guān)

禁止下半部,如softirq、tasklet和workqueue等:

local_bh_disable();

local_bh_enable();

需要注意的是,禁止下半部時仍然可以被硬中斷搶占。

?

(3) 判斷中斷狀態(tài)

#define in_interrupt() (irq_count())?// 是否處于中斷狀態(tài)(硬中斷或軟中斷)

#define in_irq()?(hardirq_count()) // 是否處于硬中斷

#define in_softirq() (softirq_count()) // 是否處于軟中斷

?

硬中斷

?

(1) 注冊中斷處理函數(shù)

注冊中斷處理函數(shù):

[java]?view plain?copy ?
  • /**?
  • ?*?irq:?要分配的中斷號?
  • ?*?handler:?要注冊的中斷處理函數(shù)?
  • ?*?flags:?標(biāo)志(一般為0)?
  • ?*?name:?設(shè)備名(dev->name)?
  • ?*?dev:?設(shè)備(struct?net_device?*dev),作為中斷處理函數(shù)的參數(shù)?
  • ?*?成功返回0?
  • ?*/??
  • ??
  • int?request_irq(unsigned?int?irq,?irq_handler_t?handler,?unsigned?long?flags,???
  • ????const?char?*name,?void?*dev);??
  • ?

    中斷處理函數(shù)本身:

    [java]?view plain?copy ?
  • typedef?irqreturn_t?(*irq_handler_t)?(int,?void?*);??
  • ??
  • /**?
  • ?*?enum?irqreturn?
  • ?*?@IRQ_NONE:?interrupt?was?not?from?this?device?
  • ?*?@IRQ_HANDLED:?interrupt?was?handled?by?this?device?
  • ?*?@IRQ_WAKE_THREAD:?handler?requests?to?wake?the?handler?thread?
  • ?*/??
  • enum?irqreturn?{??
  • ????IRQ_NONE,??
  • ????IRQ_HANDLED,??
  • ????IRQ_WAKE_THREAD,??
  • };??
  • typedef?enum?irqreturn?irqreturn_t;??
  • #define?IRQ_RETVAL(x)?((x)?!=?IRQ_NONE)??
  • ?

    (2) 注銷中斷處理函數(shù)

    [java]?view plain?copy ?
  • /**?
  • ?*?free_irq?-?free?an?interrupt?allocated?with?request_irq?
  • ?*?@irq:?Interrupt?line?to?free?
  • ?*?@dev_id:?Device?identity?to?free?
  • ?*?
  • ?*?Remove?an?interrupt?handler.?The?handler?is?removed?and?if?the?
  • ?*?interrupt?line?is?no?longer?in?use?by?any?driver?it?is?disabled.?
  • ?*?On?a?shared?IRQ?the?caller?must?ensure?the?interrupt?is?disabled?
  • ?*?on?the?card?it?drives?before?calling?this?function.?The?function?does?
  • ?*?not?return?until?any?executing?interrupts?for?this?IRQ?have?completed.?
  • ?*?This?function?must?not?be?called?from?interrupt?context.?
  • ?*/??
  • ??
  • void?free_irq(unsigned?int?irq,?void?*dev_id);??
  • ?

    軟中斷

    ?

    (1) 定義

    軟中斷是一組靜態(tài)定義的下半部接口,可以在所有處理器上同時執(zhí)行,即使兩個類型相同也可以。

    但一個軟中斷不會搶占另一個軟中斷,唯一可以搶占軟中斷的是硬中斷。

    ?

    軟中斷由softirq_action結(jié)構(gòu)體表示:

    [java]?view plain?copy ?
  • struct?softirq_action?{??
  • ????void?(*action)?(struct?softirq_action?*);?/*?軟中斷的處理函數(shù)?*/??
  • };??
  • ?

    目前已注冊的軟中斷有10種,定義為一個全局?jǐn)?shù)組:

    [java]?view plain?copy ?
  • static?struct?softirq_action?softirq_vec[NR_SOFTIRQS];??
  • ??
  • enum?{??
  • ????HI_SOFTIRQ?=?0,?/*?優(yōu)先級高的tasklets?*/??
  • ????TIMER_SOFTIRQ,?/*?定時器的下半部?*/??
  • ????NET_TX_SOFTIRQ,?/*?發(fā)送網(wǎng)絡(luò)數(shù)據(jù)包?*/??
  • ????NET_RX_SOFTIRQ,?/*?接收網(wǎng)絡(luò)數(shù)據(jù)包?*/??
  • ????BLOCK_SOFTIRQ,?/*?BLOCK裝置?*/??
  • ????BLOCK_IOPOLL_SOFTIRQ,??
  • ????TASKLET_SOFTIRQ,?/*?正常優(yōu)先級的tasklets?*/??
  • ????SCHED_SOFTIRQ,?/*?調(diào)度程序?*/??
  • ????HRTIMER_SOFTIRQ,?/*?高分辨率定時器?*/??
  • ????RCU_SOFTIRQ,?/*?RCU鎖定?*/??
  • ????NR_SOFTIRQS?/*?10?*/??
  • };??
  • ?

    (2) 注冊軟中斷處理函數(shù)

    [java]?view plain?copy ?
  • /**?
  • ?*?@nr:?軟中斷的索引號?
  • ?*?@action:?軟中斷的處理函數(shù)?
  • ?*/??
  • ??
  • void?open_softirq(int?nr,?void?(*action)?(struct?softirq_action?*))??
  • {??
  • ????softirq_vec[nr].action?=?action;??
  • }??
  • 例如:

    open_softirq(NET_TX_SOFTIRQ, net_tx_action);

    open_softirq(NET_RX_SOFTIRQ, net_rx_action);

    ?

    (3) 觸發(fā)軟中斷?

    調(diào)用raise_softirq()來觸發(fā)軟中斷。

    [java]?view plain?copy ?
  • void?raise_softirq(unsigned?int?nr)??
  • {??
  • ????unsigned?long?flags;??
  • ????local_irq_save(flags);??
  • ????raise_softirq_irqoff(nr);??
  • ????local_irq_restore(flags);??
  • }??
  • ??
  • /*?This?function?must?run?with?irqs?disabled?*/??
  • inline?void?rasie_softirq_irqsoff(unsigned?int?nr)??
  • {??
  • ????__raise_softirq_irqoff(nr);??
  • ??
  • ????/*?If?we're?in?an?interrupt?or?softirq,?we're?done?
  • ?????*?(this?also?catches?softirq-disabled?code).?We?will?
  • ?????*?actually?run?the?softirq?once?we?return?from?the?irq?
  • ?????*?or?softirq.?
  • ?????*?Otherwise?we?wake?up?ksoftirqd?to?make?sure?we?
  • ?????*?schedule?the?softirq?soon.?
  • ?????*/??
  • ????if?(!?in_interrupt())?/*?如果不處于硬中斷或軟中斷?*/??
  • ????????wakeup_softirqd(void);?/*?喚醒ksoftirqd/n進(jìn)程?*/??
  • }??

  • Percpu變量irq_cpustat_t中的__softirq_pending是等待處理的軟中斷的位圖,通過設(shè)置此變量

    即可告訴內(nèi)核該執(zhí)行哪些軟中斷。

    [java]?view plain?copy ?
  • static?inline?void?__rasie_softirq_irqoff(unsigned?int?nr)??
  • {??
  • ????trace_softirq_raise(nr);??
  • ????or_softirq_pending(1UL?<<?nr);??
  • }??
  • ??
  • typedef?struct?{??
  • ????unsigned?int?__softirq_pending;??
  • ????unsigned?int?__nmi_count;?/*?arch?dependent?*/??
  • }?irq_cpustat_t;??
  • ??
  • irq_cpustat_t?irq_stat[];??
  • #define?__IRQ_STAT(cpu,?member)?(irq_stat[cpu].member)??
  • #define?or_softirq_pending(x)?percpu_or(irq_stat.__softirq_pending,?(x))??
  • #define?local_softirq_pending()?percpu_read(irq_stat.__softirq_pending)??
  • ?

    喚醒ksoftirqd內(nèi)核線程處理軟中斷。

    [java]?view plain?copy ?
  • static?void?wakeup_softirqd(void)??
  • {??
  • ????/*?Interrupts?are?disabled:?no?need?to?stop?preemption?*/??
  • ????struct?task_struct?*tsk?=?__get_cpu_var(ksoftirqd);??
  • ??
  • ????if?(tsk?&&?tsk->state?!=?TASK_RUNNING)??
  • ????????wake_up_process(tsk);??
  • }??
  • ?

    在下列地方,待處理的軟中斷會被檢查和執(zhí)行:

    1. 從一個硬件中斷代碼處返回時

    2. 在ksoftirqd內(nèi)核線程中

    3. 在那些顯示檢查和執(zhí)行待處理的軟中斷的代碼中,如網(wǎng)絡(luò)子系統(tǒng)中

    ?

    而不管是用什么方法喚起,軟中斷都要在do_softirq()中執(zhí)行。如果有待處理的軟中斷,

    do_softirq()會循環(huán)遍歷每一個,調(diào)用它們的相應(yīng)的處理程序。

    在中斷處理程序中觸發(fā)軟中斷是最常見的形式。中斷處理程序執(zhí)行硬件設(shè)備的相關(guān)操作,

    然后觸發(fā)相應(yīng)的軟中斷,最后退出。內(nèi)核在執(zhí)行完中斷處理程序以后,馬上就會調(diào)用

    do_softirq(),于是軟中斷開始執(zhí)行中斷處理程序完成剩余的任務(wù)。

    ?

    下面來看下do_softirq()的具體實現(xiàn)。

    [java]?view plain?copy ?
  • asmlinkage?void?do_softirq(void)??
  • {??
  • ????__u32?pending;??
  • ????unsigned?long?flags;??
  • ??
  • ????/*?如果當(dāng)前已處于硬中斷或軟中斷中,直接返回?*/??
  • ????if?(in_interrupt())???
  • ????????return;??
  • ??
  • ????local_irq_save(flags);??
  • ????pending?=?local_softirq_pending();??
  • ????if?(pending)?/*?如果有激活的軟中斷?*/??
  • ????????__do_softirq();?/*?處理函數(shù)?*/??
  • ????local_irq_restore(flags);??
  • }??
  • [java]?view plain?copy ?
  • /*?We?restart?softirq?processing?MAX_SOFTIRQ_RESTART?times,?
  • ?*?and?we?fall?back?to?softirqd?after?that.?
  • ?*?This?number?has?been?established?via?experimentation.?
  • ?*?The?two?things?to?balance?is?latency?against?fairness?-?we?want?
  • ?*?to?handle?softirqs?as?soon?as?possible,?but?they?should?not?be?
  • ?*?able?to?lock?up?the?box.?
  • ?*/??
  • asmlinkage?void?__do_softirq(void)??
  • {??
  • ????struct?softirq_action?*h;??
  • ????__u32?pending;??
  • ????/*?本函數(shù)能重復(fù)觸發(fā)執(zhí)行的次數(shù),防止占用過多的cpu時間?*/??
  • ????int?max_restart?=?MAX_SOFTIRQ_RESTART;??
  • ????int?cpu;??
  • ??
  • ????pending?=?local_softirq_pending();?/*?激活的軟中斷位圖?*/??
  • ????account_system_vtime(current);??
  • ????/*?本地禁止當(dāng)前的軟中斷?*/??
  • ????__local_bh_disable((unsigned?long)__builtin_return_address(0),?SOFTIRQ_OFFSET);??
  • ????lockdep_softirq_enter();?/*?current->softirq_context++?*/??
  • ????cpu?=?smp_processor_id();?/*?當(dāng)前cpu編號?*/??
  • ??
  • restart:??
  • ????/*?Reset?the?pending?bitmask?before?enabling?irqs?*/??
  • ????set_softirq_pending(0);?/*?重置位圖?*/??
  • ????local_irq_enable();??
  • ????h?=?softirq_vec;??
  • ????do?{??
  • ????????if?(pending?&?1)?{??
  • ????????????unsigned?int?vec_nr?=?h?-?softirq_vec;?/*?軟中斷索引?*/??
  • ????????????int?prev_count?=?preempt_count();??
  • ????????????kstat_incr_softirqs_this_cpu(vec_nr);??
  • ??
  • ????????????trace_softirq_entry(vec_nr);??
  • ????????????h->action(h);?/*?調(diào)用軟中斷的處理函數(shù)?*/??
  • ????????????trace_softirq_exit(vec_nr);??
  • ??
  • ????????????if?(unlikely(prev_count?!=?preempt_count()))?{??
  • ????????????????printk(KERN_ERR?"huh,?entered?softirq?%u?%s?%p"?"with?preempt_count?%08x,"??
  • ????????????????????"exited?with?%08x?\n",?vec_nr,?softirq_to_name[vec_nr],?h->action,?prev_count,??
  • ????????????????????preempt_count());??
  • ????????????}??
  • ????????????rcu_bh_qs(cpu);??
  • ????????}??
  • ????????h++;??
  • ????????pending?>>=?1;??
  • ????}?while(pending);??
  • ??
  • ????local_irq_disable();??
  • ????pending?=?local_softirq_pending();??
  • ????if?(pending?&?--max_restart)?/*?重復(fù)觸發(fā)?*/??
  • ????????goto?restart;??
  • ??
  • ????/*?如果重復(fù)觸發(fā)了10次了,接下來喚醒ksoftirqd/n內(nèi)核線程來處理?*/??
  • ????if?(pending)??
  • ????????wakeup_softirqd();???
  • ??
  • ????lockdep_softirq_exit();??
  • ????account_system_vtime(current);??
  • ????__local_bh_enable(SOFTIRQ_OFFSET);??
  • }??
  • ?

    (4) ksoftirqd內(nèi)核線程

    內(nèi)核不會立即處理重新觸發(fā)的軟中斷。

    當(dāng)大量軟中斷出現(xiàn)的時候,內(nèi)核會喚醒一組內(nèi)核線程來處理。

    這些線程的優(yōu)先級最低(nice值為19),這能避免它們跟其它重要的任務(wù)搶奪資源。

    但它們最終肯定會被執(zhí)行,所以這個折中的方案能夠保證在軟中斷很多時用戶程序不會

    因為得不到處理時間而處于饑餓狀態(tài),同時也保證過量的軟中斷最終會得到處理。

    ?

    每個處理器都有一個這樣的線程,名字為ksoftirqd/n,n為處理器的編號。

    [java]?view plain?copy ?
  • static?int?run_ksoftirqd(void?*__bind_cpu)??
  • {??
  • ????set_current_state(TASK_INTERRUPTIBLE);??
  • ????current->flags?|=?PF_KSOFTIRQD;?/*?I?am?ksoftirqd?*/??
  • ??
  • ????while(!?kthread_should_stop())?{??
  • ????????preempt_disable();??
  • ??
  • ????????if?(!?local_softirq_pending())?{?/*?如果沒有要處理的軟中斷?*/??
  • ????????????preempt_enable_no_resched();??
  • ????????????schedule();??
  • ????????????preempt_disable():??
  • ????????}??
  • ??
  • ????????__set_current_state(TASK_RUNNING);??
  • ??
  • ????????while(local_softirq_pending())?{??
  • ????????????/*?Preempt?disable?stops?cpu?going?offline.?
  • ?????????????*?If?already?offline,?we'll?be?on?wrong?CPU:?don't?process.?
  • ?????????????*/??
  • ?????????????if?(cpu_is_offline(long)__bind_cpu))/*?被要求釋放cpu?*/??
  • ?????????????????goto?wait_to_die;??
  • ??
  • ????????????do_softirq();?/*?軟中斷的統(tǒng)一處理函數(shù)?*/??
  • ??
  • ????????????preempt_enable_no_resched();??
  • ????????????cond_resched();??
  • ????????????preempt_disable();??
  • ????????????rcu_note_context_switch((long)__bind_cpu);??
  • ????????}??
  • ??
  • ????????preempt_enable();??
  • ????????set_current_state(TASK_INTERRUPTIBLE);??
  • ????}??
  • ??
  • ????__set_current_state(TASK_RUNNING);??
  • ????return?0;??
  • ??
  • wait_to_die:??
  • ????preempt_enable();??
  • ????/*?Wait?for?kthread_stop?*/??
  • ????set_current_state(TASK_INTERRUPTIBLE);??
  • ????while(!?kthread_should_stop())?{??
  • ????????schedule();??
  • ????????set_current_state(TASK_INTERRUPTIBLE);??
  • ????}??
  • ??
  • ????__set_current_state(TASK_RUNNING);??
  • ????return?0;??
  • } ?

  • 轉(zhuǎn)自:?http://blog.csdn.net/zhangskd/article/details/21992933

    總結(jié)

    以上是生活随笔為你收集整理的硬中断、软中断和信号的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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