linuxcpu中斷
㈠ 如何指定CPU只運行特定任務,linux中斷interrupt
cpuset 允許把所有進程echo到一個cpuset目錄中,與指定的cpu綁定。
The following script which is a starting point for investigating willmove all the processes to a specific cpuset with one cpu.
if[!-d/sys/fs/cgroup];then
echo"cgroupnotsupportedbythekernel"
else
mkdir/sys/fs/cgroup/cpuset
mount-tcgroup-ocpusetcpuset/sys/fs/cgroup/cpuset
echo1>/sys/fs/cgroup/cpuset/cgroup.clone_children
mkdir/sys/fs/cgroup/cpuset/cpu0
mkdir/sys/fs/cgroup/cpuset/cpu1
#assignacpuforcgroupcpu0
echo0>/sys/fs/cgroup/cpuset/cpu0/cpuset.cpus
#moveoutselftothisnewcgroup
echo$$>/sys/fs/cgroup/cpuset/cpu0/tasks
foriin$(cat/sys/fs/cgroup/cpuset/tasks);do
echo$i>/sys/fs/cgroup/cpuset/cpu0/tasks||echo"failedtoaddpid$i/$(cat/proc/$i/comm)"
done
#assignacpuforcgroupcpu1
echo1>/sys/fs/cgroup/cpuset/cpu1/cpuset.cpus
#
#totheothercgroupwon'tuseit
echo1>/sys/fs/cgroup/cpuset/cpu1/cpuset.cpu_exclusive
fi
把系統中的進程與CPU0綁定,然後把CPU1設置 exclusive屬性,這樣其它cgroup不會使用這個CPU。
開啟stress壓力測試
在此基礎上再開啟一個CPUhot:
可見新啟動的任務不會佔用CPU1。
將CPUhot進程與 CPU1綁定:
此時觀察CPU使用率:
另外還有一個問題就是怎樣禁止一個中斷打斷cpu?
內核提供了中斷的affinity,但要使用這個還需要關閉 irq balancer 進程。
如下腳本可以設置中斷的cpu affinity。
for i in $(find /proc/irq -name "smp_affinity"); do echo 1 > $i; done
以上腳本把所有中斷的CPU Affinity都設置為CPU0。
這樣在/proc/irq目錄下的每一個中斷其CPU Affinity都被設置為CPU0。
此時仍有一系列的中斷會打斷CPU1:
Single function call interrupts
Local timer interrupts
另外要讓中斷的CPU Affinity起作用,irq balance 服務必須被關閉。但這樣中斷負載平衡就被打斷,能不能修改irq balance 代碼,讓其在規定的若干個CPU核心上負責中斷平衡
㈡ linux系統中的中斷指令是什麼
什麼是中斷
Linux 內核需要對連接到計算機上的所有硬體設備進行管理,毫無疑問這是它的份內事。如果要管理這些設備,首先得和它們互相通信才行,一般有兩種方案可實現這種功能:
輪詢(polling) 讓內核定期對設備的狀態進行查詢,然後做出相應的處理;中斷(interrupt) 讓硬體在需要的時候向內核發出信號(變內核主動為硬體主動)。
第一種方案會讓內核做不少的無用功,因為輪詢總會周期性的重復執行,大量地耗用 CPU 時間,因此效率及其低下,所以一般都是採用第二種方案 。
對於中斷的理解我們先看一個生活中常見的例子:QQ。第一種情況:你正在工作,然後你的好友突然給你發送了一個窗口抖動,打斷你正在進行的工作。第
二種情況:當然你有時候也會每隔 5 分鍾就去檢查一下 QQ
看有沒有好友找你,雖然這很浪費你的時間。在這里,一次窗口抖動就可以被相當於硬體的中斷,而你就相當於 CPU,你的工作就是 CPU
這在執行的進程。而定時查詢就被相當於 CPU 的輪詢。在這里可以看到:同樣作為 CPU 和硬體溝通的方式,中斷是硬體主動的方式,較輪詢(CPU
主動)更有效些,因為我們都不可能一直無聊到每隔幾分鍾就去查一遍好友列表。
CPU
有大量的工作需要處理,更不會做這些大量無用功。當然這只是一般情況下。好了,這里又有了一個問題,每個硬體設備都中斷,那麼如何區分不同硬體呢?不同設
備同時中斷如何知道哪個中斷是來自硬碟、哪個來自網卡呢?這個很容易,不是每個 QQ 號碼都不相同嗎?同樣的,系統上的每個硬體設備都會被分配一個
IRQ 號,通過這個唯一的 IRQ 號就能區別張三和李四了。
從物理學的角度看,中斷是一種電信號,由硬體設備產生,並直接送入中斷控制器(如
8259A)的輸入引腳上,然後再由中斷控制器向處理器發送相應的信號。處理器一經檢測到該信號,便中斷自己當前正在處理的工作,轉而去處理中斷。此後,
處理器會通知 OS 已經產生中斷。這樣,OS
就可以對這個中斷進行適當的處理。不同的設備對應的中斷不同,而每個中斷都通過一個唯一的數字標識,這些值通常被稱為中斷請求線。
㈢ 如何關閉linux smp中斷
在多 CPU 的環境中,還有一個中斷平衡的問題,比如,網卡中斷會教給哪個 CPU 處理,這個參數控制哪些 CPU 可以綁定 IRQ 中斷。其中的 {number} 是對應設備的中斷編號,可以用下面的命令找出:
cat /proc/interrupt
比如,一般 eth0 的 IRQ 編號是 16,所以控制 eth0 中斷綁定的 /proc 文件名是 /proc/irq/16/smp_affinity。上面這個命令還可以看到某些中斷對應的CPU處理的次數,預設的時候肯定是不平衡的。
設置其值的方法很簡單,smp_affinity 自身是一個位掩碼(bitmask),特定的位對應特定的 CPU,這樣,01 就意味著只有第一個 CPU 可以處理對應的中斷,而 0f(0x1111)意味著四個 CPU 都會參與中斷處理。
幾乎所有外設都有這個參數設置,可以關注一下。
這個數值的推薦設置,其實在很大程度上,讓專門的CPU處理專門的中斷是效率最高的,比如,給磁碟IO一個CPU,給網卡一個CPU,這樣是比較合理的。
現在的伺服器一般都是多核了,但是中斷很多時候都是只用一個核,如果有些中斷要求比較高,可以把它獨立分配給一個cpu使用。
㈣ Linux 系統中的中斷是不是沒有中斷優先順序
關於中斷嵌套:在linux內核里,如果驅動在申請注冊中斷的時候沒有特別的指定,do_irq在做中斷響應的時候,是開啟中斷的,如果在驅動的中斷處理函數正在執行的過程中,出現同一設備的中斷或者不同設備的中斷,這時候新的中斷會被立即處理,還是被pending,等當前中斷處理完成後,再做處理。在2.4和2.6內核里,關於這一塊是否有什麼不同。 一般申請中斷的時候都允許開中斷,即不使用SA_INTERRUPT標志。如果允許共享則加上 SA_SHIRQ,如果可以為內核熵池提供熵值(譬如你寫的驅動是ide之類的驅動),則再加上 SA_SAMPLE_RANDOM標志。這是普通的中斷請求過程。對於這種一般情況,只要發生中斷,就可以搶占內核,即使內核正在執行其他中斷函數。這里有兩點說明:一是因為linux不支持 中斷優先順序,因此任何中斷都可以搶占其他中斷,但是同種類型的中斷(即定義使用同一個 中斷線的中斷)不會發生搶占,他們會在執行本類型中斷的時候依次被調用執行。二是所謂 只要發生中斷,就可以搶占內核這句是有一定限制的,因為當中斷發生的時候系統由中斷門 進入時自動關中斷(對於x86平台就是將eflags寄存器的if位置為0),只有當中斷函數被執行 (handle_IRQ_event)的過程中開中斷之後才能有搶占。 對於同種類型的中斷,由於其使用同樣的idt表項,通過其狀態標志(IRQ_PENDING和 IRQ_INPROGRESS)可以防止同種類型的中斷函數執行(注意:是防止handle_IRQ_event被重入, 而不是防止do_IRQ函數被重入),對於不同的中斷,則可以自由的嵌套。因此,所謂中斷嵌套, 對於不同的中斷是可以自由嵌套的,而對於同種類型的中斷,是不可以嵌套執行的。以下簡單解釋一下如何利用狀態標志來防止同種類型中斷的重入:當某種類型的中斷第一次發生時,首先其idt表項的狀態位上被賦予IRQ_PENDING標志,表示有待處理。 然後將中斷處理函數action置為null,然後由於其狀態沒有IRQ_INPROGRESS標志(第一次),故將其狀態置上IRQ_INPROGRESS並去處IRQ_PENDING標志,同時將action賦予相應的中斷處理函數指針(這里是一個重點,linux很巧妙的用法,隨後說明)。這樣,後面就可以順利執行handle_IRQ_event進行中斷處理,當在handle_IRQ_event中開中斷後,如果有同種類型的中斷發生,則再次進入do_IRQ函數,然後其狀態位上加上IRQ_PENDING標志,但是由於前一次中斷處理中加上的IRQ_INPROGRESS沒有被清除,因此這里無法清除IRQ_PENDING標志,因此action還是為null,這樣就無法再次執行handle_IRQ_event函數。從而退出本次中斷處理,返回上一次的中斷處理函數中,即繼續執行handle_IRQ_event函數。當handle_IRQ_event返回時檢查IRQ_PENDING標志,發現存在這個標志,說明handle_IRQ_event執行過程中被中斷過,存在未處理的同類中斷,因此再次循環執行handle_IRQ_event函數。直到不存在IRQ_PENDING標志為止。2.4和2.6的差別,就我來看,主要是在2.6中一進入do_IRQ,多了一個關閉內核搶占的動作,同時在處理中多了一種對IRQ_PER_CPU類型的中斷的處理,其他沒有什麼太大的改變。這類IRQ_PER_CPU的中斷主要用在smp環境下將中斷綁定在某一個指定的cpu上。例如arch/ppc/syslib/open_pic.c中的openpic_init中初始化ipi中斷的時候。 其實簡單的說,中斷可以嵌套,但是同種類型的中斷是不可以嵌套的,因為在IRQ上發生中斷,在中斷響應的過程中,這個IRQ是屏蔽的,也就是這個IRQ的中斷是不能被發現的。 同時在內核的臨界區內,中斷是被禁止的 關於do_IRQ可能會丟失中斷請求:do_IRQ函數是通過在執行完handle_IRQ_event函數之後判斷status是否被設置了IRQ_PENDING標志來判斷是否還有沒有被處理的同一通道的中斷請求。 但是這種方法只能判斷是否有,而不能知道有多少個未處理的統一通道中斷請求。也就是說,假如在第一個中斷請求執行handle_IRQ_event函數的過程中來了同一通道的兩個或更多中斷請求,而這些中斷不會再來,那麼僅僅通過判斷status是否設置了IRQ_PENDING標志不知道到底有多少個未處理的中斷,handle_IRQ_event只會被再執行一次。這算不算是個bug呢? 不算,只要知道有中斷沒有處理就OK了,知道1個和知道N個,本質上都是一樣的。作為外設,應當能夠處理自己中斷未被處理的情況。不可能丟失的,在每一個中斷描述符的結構體內,都有一個鏈表,鏈表中存放著服務常式序關於中斷中使用的幾個重要概念和關系: 一、基本概念 1. 產生的位置 發生的時刻 時序 中斷 CPU外部 隨機 非同步 異常 CPU正在執行的程序 一條指令終止執行後 同步 2.由中斷或異常執行的代碼不是一個進程,而是一個內核控制路徑,代表中斷發生時正在運行的進程的執行 中斷處理程序與正在運行的程序無關 引起異常處理程序的進程正是異常處理程序運行時的當前進程 二、特點 (2)能以嵌套的方式執行,但是同種類型的中斷不可以嵌套 (3)盡可能地限制臨界區,因為在臨界區中,中斷被禁止 2.大部分異常發生在用戶態,缺頁異常是唯一發生於內核態能觸發的異常 缺頁異常意味著進程切換,因此中斷處理程序從不執行可以導致缺頁的操作 3.中斷處理程序運行於內核態 中斷發生於用戶態時,要把進程的用戶空間堆棧切換到進程的系統空間堆棧,剛切換時,內核堆棧是空的 中斷發生於內核態時, 不需要堆棧空間的切換 三、分類 1.中斷的分類:可屏蔽中斷、不可屏蔽中斷 2.異常的分類: 分類 解決異常的方法 舉例 故障 那條指令會被重新執行 缺頁異常處理程序 陷阱 會從下一條指令開始執行 調試程序
㈤ linux下怎麼解除中斷和cpu綁定
在多 CPU 的環境中,還有一個中斷平衡的問題,比如,網卡中斷會教給哪個 CPU 處理,這個參數控制哪些 CPU 可以綁定 IRQ 中斷。其中的 {number} 是對應設備的中斷編號,可以用下面的命令找出: cat /proc/interrupt 比如,一般 eth0 的 IRQ
㈥ linux 內核軟中斷 是在中斷狀態嗎
先說說環境
1.硬體:DELL R410
2.網卡:板載1000M BCM5709
2.OS: RHEL 5.5 x86_64
3.KERNEL: 2.6.18-194.el5
所出現的問題
1.網卡毫無徵兆的down掉,而且沒有任何log信息
2.當流量增大時,不到理論上限的1/3時機器出現網路延遲嚴重,伴隨大量的丟包
3.機器的cpu軟中斷不均衡,只有1個cpu處理軟中斷,並且該cpu的軟中斷周期性的達到100%
4.內外網網卡做nat丟包數據量不一致,差別很大,不在同一個數量級
想必第一個問題,大部分使用bcm網卡,rhel 5.3以後得機器都會遇到這種情況,網上的資料比較的多,我也不多啰嗦了,直接升級網卡驅動就可以解決了。第二,三,四其實是同一個問題都是由於網卡中斷過多,cpu處理不過來(准確的說,cpu分配不均衡,導致只有一個cpu處理,處理不過來),引起丟包,那麼為什麼兩個網卡丟包的數量級不一樣呢,下面從原理上進行解釋,既然是做nat多出口,那麼就有大量的路由信息,是一個網路應用,當一個數據包請求nat時,數據包先被網卡驅動的數據接收,網卡收到數據時,觸發中斷。在中斷執行常式中,把skb掛入輸入隊列,並觸發軟中斷。稍後的某個時刻,當軟中斷執行時,再從該隊列中把skb取下來,投遞給上層協議。
如果在這個過程當中cpu沒有及時處理完這個隊列導致網卡的buffer滿了,網卡將直接丟棄該數據包。這里牽涉到2個隊列,一個是tx,一個是rx,它的隊列的大小默認都是255,可以通過ethtool -g eth0(你指定的網卡),為了防止丟包,當時我通過ethtool -G eth0 rx xxx 把它調大了,但是調大以後,還是杯水車薪啊,通過ethtool -S eth0 |grep rx_fw_discards,發現數值還是不停的在增長,也就是說還在不停的丟包,cpu處理不過來,這時候找到網上有人在利用lvs時也遇到這個問題,cpu軟中斷分配不均衡,只有一個cpu處理軟中斷的問題,網上的資料五花八門,有建議使用修改設備中斷方式。即通過修改設置中斷/proc/irq/${網卡中斷號}/smp_affinit這時候,我也修改過,沒有什麼實質的效果,
從官方的bug報告,https://bugzilla.redhat.com/show_bug.cgi?id=520888,其中提到rhel5.6已經修復了這個bug,這其中也提到目前我們的版本可以升級內核到kernel-2.6.18-194.3.1.el5可以解決這個問題。
紅帽子官方修復報告中的說明如下:http://rhn.redhat.com/errata/RHSA-2010-0398.html,我們升級了這個內核算是解決單核處理軟中斷的問題,升級後各個cpu已經能夠平均的分配這個軟中斷,也不丟包了,那麼為什麼cpu處理不過來這個軟中斷呢,數據量並不是特別的大啊,上層應用接到這個數據包後,通過路由協議,找到某個出口給nat出去,找nat出口是需要查找路由表,查詢路由表是一件很耗時的工作,而每一個不同源地址,不同目的地址的數據包都得重新查找一次路由表,導致cpu處理不過來,為了提高路由查詢的效率。Linux內核引用了路由緩存,用於減少對路由表的查詢。Linux的路由緩存是被設計來與協議無關的獨立子系統,查看路由緩存可以通過命令route -Cn,由於路由緩存當中是採用hash演算法進行才找,它的查找速度非常之快,既然是cache就有超時這一概念。系統默認為10分鍾,可以通過這個文件進行查看和修改/proc/sys/net/ipv4/route/secret_interval。而當路由緩存當中未找到或者已經超時的路由信息才開始查找路由表,查詢到的結果保存在路由緩存中。如果路由表越大,那麼查詢的時間就越長,一個新的連接進來後或者是老連接cache超時後,佔用大量的cpu查詢時間,導致cpu周期性的軟中斷出現100%,而兩個網卡丟包的情況來看不均衡也是因為用戶的數據包是經過其中一個網卡進來後查詢路由表耗時過長,cpu處理不過來,導致那塊網卡的隊列滿了,丟包嚴重。當然在路由表變動不大的情況下可以加大cache的時間,修改上述內容後,從我監測的情況來看,扛流量能力得到了大大的提升。
㈦ linux中斷響應大概是多長時間
一、中斷處理為什麼要下半部? Linux在中斷處理中間中斷處理分了上半部和下半部,目的就是提高系統的響應能力和並發能力。通俗一點來講:當一個中斷產生,調用該中斷對應的處理程序(上半部)然後告訴系統,對應的後半部可以執行了。然後中斷處理程序就返回,下半部會在合適的時機有系統調用。這樣一來就大大的減少了中斷處理所需要的時間。 二、那些工作應該放在上半部,那些應該放在下半部? 沒有嚴格的規則,只有一些提示: 1、對時間非常敏感,放在上半部。 2、與硬體相關的,放在上半部。 3、不能被其他中斷打斷的工作,放在上半部。 以上三點之外的,考慮放在下半部。 三、下半部機制在Linux中是怎麼實現的? 下半部在Linux中有以下實現機制: 1、BH(在2.5中刪除) 2、任務隊列(task queue,在2.5刪除) 3、軟中斷(softirq,2.3開始。本文重點) 4、tasklet(2.3開始) 5、工作隊列(work queue,2.5開始) 四、軟中斷是怎麼實現的(以下代碼出自2.6.32)? 軟中斷不會搶占另外一個軟中斷,唯一可以搶占軟中斷的是中斷處理程序。 軟中斷可以在不同CPU上並發執行(哪怕是同一個軟中斷) 1、軟中斷是編譯期間靜態分配的,定義如下: struct softirq_action { void (*action)(struct softirq_action *); }; /* * PLEASE, avoid to allocate new softirqs, if you need not _really_ high * frequency threaded job scheling. For almost all the purposes * tasklets are more than enough. F.e. all serial device BHs et * al. should be converted to tasklets, not to softirqs. */ enum { HI_SOFTIRQ=0, TIMER_SOFTIRQ, NET_TX_SOFTIRQ, NET_RX_SOFTIRQ, BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS }; /* * map softirq index to softirq name. update 'softirq_to_name' in * kernel/softirq.c when adding a new softirq. */ extern char *softirq_to_name[NR_SOFTIRQS]; static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; 說明: (1)、軟中斷的個數書上說是32,看來到這個版本已經發生變化了。 (2)、void (*action)(struct softirq_action *);傳遞整個結構體指針在於當結構體成員發生變化是,介面不變。 2、系統執行軟中斷一個注冊的軟中斷必須被標記後才會執行(觸發軟中斷),通常中斷處理程序會在返回前標記它的軟中斷。在下列地方,待處理的軟中斷會被執行: (1)、從一個硬體中斷代碼處返回。 (2)、在ksoftirqd內核線程。 (3)、在那些顯示檢查和執行待處理的軟中斷代碼中。 ksoftirqd說明: 每個處理器都有一個這樣的線程。所有線程的名字都叫做ksoftirq/n,區別在於n,它對應的是處理器的編號。在一個雙CPU的機器上就有兩個這樣的線程,分別叫做ksoftirqd/0和ksoftirqd/1。為了保證只要有空閑的處理器,它們就會處理軟中斷,所以給每個處理器都分配一個這樣的線程。 執行軟中斷的代碼如下: asmlinkage void __do_softirq(void) { struct softirq_action *h; __u32 pending; int max_restart = MAX_SOFTIRQ_RESTART; int cpu; pending = local_softirq_pending(); account_system_vtime(current); __local_bh_disable((unsigned long)__builtin_return_address(0)); lockdep_softirq_enter(); cpu = smp_processor_id(); restart: /* Reset the pending bitmask before enabling irqs */ set_softirq_pending(0); local_irq_enable(); h = softirq_vec; do { if (pending & 1) { int prev_count = preempt_count(); kstat_incr_softirqs_this_cpu(h - softirq_vec); trace_softirq_entry(h, softirq_vec); h->action(h); trace_softirq_exit(h, softirq_vec); if (unlikely(prev_count != preempt_count())) { printk(KERN_ERR "huh, entered softirq %td %s %p" "with preempt_count %08x," " exited with %08x?\n", h - softirq_vec, softirq_to_name[h - softirq_vec], h->action, prev_count, preempt_count()); preempt_count() = prev_count; } rcu_bh_qs(cpu); } h++; pending >>= 1; } while (pending); local_irq_disable(); pending = local_softirq_pending(); if (pending && --max_restart) goto restart; if (pending) wakeup_softirqd(); lockdep_softirq_exit(); account_system_vtime(current); _local_bh_enable(); } 3、編寫自己的軟中斷 (1)、分配索引,在HI_SOFTIRQ與NR_SOFTIRQS中間添加自己的索引號。 (2)、注冊處理程序,處理程序:open_softirq(索引號,處理函數)。 (3)、觸發你的軟中斷:raise_softirq(索引號)。 4、軟中斷處理程序注意 (1)、軟中斷處理程序執行的時候,允許響應中斷,但自己不能休眠。 (2)、如果軟中斷在執行的時候再次觸發,則別的處理器可以同時執行,所以加鎖很關鍵。
㈧ Linux中斷與定時器
所謂中斷是指CPU在執行程序的過程中,出現了某些突發事件急待處理,CPU必須暫停當前程序的執行,轉去處理突發事件,處理完畢後又返回原程序被中斷的位置繼續執行。根據中斷的來源,中斷可分為內部中斷和外部中斷,內部中斷的中斷源來自CPU內部(軟體中斷指令、溢出、除法錯誤等,例如,操作系統從用戶態切換到內核態需藉助CPU內部的軟體中斷),外部中斷的中斷源來自CPU外部,由外設提出請求。根據中斷是否可以屏蔽,中斷可分為可屏蔽中斷與不可屏蔽中斷(NMI),可屏蔽中斷可以通過設置中斷控制器寄存器等方法被屏蔽,屏蔽後,該中斷不再得到響應,而不可屏蔽中斷不能被屏蔽。
根據中斷入口跳轉方法的不同,中斷可分為向量中斷和非向量中斷。採用向量中斷的CPU通常為不同的中斷分配不同的中斷號,當檢測到某中斷號的中斷到來後,就自動跳轉到與該中斷號對應的地址執行。不同中斷號的中斷有不同的入口地址。非向量中斷的多個中斷共享一個入口地址,進入該入口地址後,再通過軟體判斷中斷標志來識別具體是哪個中斷。也就是說,向量中斷由硬體提供中斷服務程序入口地址,非向量中斷由軟體提供中斷服務程序入口地址。
嵌入式系統以及x86PC中大多包含可編程中斷控制器(PIC),許多MCU內部就集成了PIC。如在80386中,PIC是兩片i8259A晶元的級聯。通過讀寫PIC的寄存器,程序員可以屏蔽/使能某中斷及獲得中斷狀態,前者一般通過中斷MASK寄存器完成,後者一般通過中斷PEND寄存器完成。定時器在硬體上也依賴中斷來實現,典型的嵌入式微處理器內可編程間隔定時器(PIT)的工作原理,它接收一個時鍾輸入,當時鍾脈沖到來時,將目前計數值增1並與預先設置的計數值(計數目標)比較,若相等,證明計數周期滿,並產生定時器中斷且復位目前計數值。
㈨ 在SMP系統中,Linux定義的處理機間中斷RESCEDULE_VECTOR:使被中斷CPU重新調
摘要 中斷讓外設能夠通知CPU他需要獲得服務(讓CPU執行指定的中斷服務常式ISR)。為了達到這個目的,首先要為中斷執行做好准備,完成初始化相關的操作。包括:
㈩ linux中斷的下半部機制有哪些
一、中斷處理為什麼要下半部?Linux在中斷處理中間中斷處理分了上半部和下半部,目的就是提高系統的響應能力和並發能力。通俗一點來講:當一個中斷產生,調用該中斷對應的處理程序(上半部)然後告訴系統,對應的後半部可以執行了。然後中斷處理程序就返回,下半部會在合適的時機有系統調用。這樣一來就大大的減少了中斷處理所需要的時間。
二、那些工作應該放在上半部,那些應該放在下半部?
沒有嚴格的規則,只有一些提示:
1、對時間非常敏感,放在上半部。
2、與硬體相關的,放在上半部。
3、不能被其他中斷打斷的工作,放在上半部。
以上三點之外的,考慮放在下半部。
三、下半部機制在Linux中是怎麼實現的?
下半部在Linux中有以下實現機制:
1、BH(在2.5中刪除)
2、任務隊列(task queue,在2.5刪除)
3、軟中斷(softirq,2.3開始。本文重點)
4、tasklet(2.3開始)
5、工作隊列(work queue,2.5開始)
四、軟中斷是怎麼實現的(以下代碼出自2.6.32)?
軟中斷不會搶占另外一個軟中斷,唯一可以搶占軟中斷的是中斷處理程序。
軟中斷可以在不同CPU上並發執行(哪怕是同一個軟中斷)
1、軟中斷是編譯期間靜態分配的,定義如下:
struct softirq_action { void (*action)(struct softirq_action *); };
/*
* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
* frequency threaded job scheling. For almost all the purposes
* tasklets are more than enough. F.e. all serial device BHs et
* al. should be converted to tasklets, not to softirqs.
*/
enum {
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS