大內(nèi)核鎖(BKL)現(xiàn)在已經(jīng)成為了一個(gè)遙遠(yuǎn)的記憶,但在那么多年里,它都是內(nèi)核開(kāi)發(fā)社區(qū)面臨的一項(xiàng)棘手問(wèn)題。然而 BKL 的終結(jié)并不意味著內(nèi)核沒(méi)有其他有問(wèn)題的鎖。近來(lái),已經(jīng)有一些關(guān)注轉(zhuǎn)向了軟中斷鎖(software-interrupt lock)或“下半部鎖”(bottom half lock),因?yàn)樗赡軙?huì)在實(shí)時(shí)系統(tǒng)上導(dǎo)致延遲。Frederic Weisbecker 正在采取最新行動(dòng)來(lái)減小這個(gè)鎖的影響范圍,該方法就是基于移除 BKL 時(shí)所采取的方法。
最初,Linux 內(nèi)核是在單處理器系統(tǒng)上開(kāi)發(fā)的 —— 當(dāng)然可以理解,因?yàn)槟菚r(shí)我們手頭只有這種系統(tǒng) —— 因此,代碼在很大程度上基于這樣的假設(shè):它在 CPU 上運(yùn)行,完全不存在其他的 CPU。于是 BKL 最終需要被引入,才能讓 Linux 能夠運(yùn)行在那些產(chǎn)業(yè)分析師向我們保證的未來(lái)將會(huì)大行其道的多處理器機(jī)器上。它確保了只有一個(gè) CPU 在任何給定時(shí)間內(nèi)運(yùn)行內(nèi)核代碼,從而避免了各種并發(fā)問(wèn)題,但是顯著地犧牲了性能,尤其是隨著 CPU 數(shù)量的增加而更加明顯。人們很快意識(shí)到 BKL 必須被移除。
在許多子系統(tǒng)中采取的方法是將 BKL 下移至系統(tǒng)的更底層級(jí)別。不再是在調(diào)用每個(gè)驅(qū)動(dòng)程序的 open()函數(shù)時(shí)就申請(qǐng)持有 BKL,而是修改每個(gè)驅(qū)動(dòng)程序來(lái)自行獲取 BKL。然后,open()函數(shù)可以在不持有 BKL 的情況下安全地得到調(diào)用了,每個(gè)驅(qū)動(dòng)程序可以在需要時(shí)進(jìn)行獨(dú)立的審查(audit)和修復(fù),之后可以刪除其對(duì) BKL 的使用。這種把 BKL 下移的動(dòng)作將一個(gè)大問(wèn)題分解成了許多較小且更易處理的問(wèn)題。經(jīng)過(guò)多年的努力,BKL 終于在 2011 年被移除了。
軟中斷(software interrupt)是一種延后執(zhí)行的方法,用于執(zhí)行一些是緊急但又無(wú)法直接在硬件中斷上下文中執(zhí)行的工作。當(dāng)有這種工作要做時(shí),子系統(tǒng)會(huì)通過(guò)設(shè)置一個(gè) flag 來(lái)觸發(fā)軟中斷;這會(huì)使得在下一個(gè)合適的時(shí)機(jī)會(huì)調(diào)用其處理程序,通常是在硬件中斷處理完成后就立即調(diào)用,或在從系統(tǒng)調(diào)用返回到用戶空間之前調(diào)用。如果處理時(shí)間過(guò)長(zhǎng),相關(guān)處理也可以推送到專門的 ksoftirqd 線程中。
軟中斷有許多使用者,包括 tasklets、網(wǎng)絡(luò)、塊設(shè)備子系統(tǒng)、讀-拷貝-更新(RCU)以及內(nèi)核定時(shí)器。在某些工作場(chǎng)景中,軟中斷處理可能成為 CPU 總負(fù)載的一個(gè)重要部分;它可能會(huì)運(yùn)行相當(dāng)長(zhǎng)的時(shí)間,從而對(duì)運(yùn)行在用戶空間中的軟件導(dǎo)致延遲。會(huì)禁用軟中斷處理的那些內(nèi)核代碼(為了避免與處理程序的產(chǎn)生 race condition)會(huì)變成不可搶占的,這也會(huì)導(dǎo)致出現(xiàn)不太愉快的延遲??傊?,與 BKL 一樣,軟中斷反映了幾十年前很適用但是現(xiàn)在存在問(wèn)題的一種設(shè)計(jì)。
其中一個(gè)設(shè)計(jì)上的決策是,軟中斷處理程序需要互斥;在任何給定的 CPU 上,只能執(zhí)行一個(gè)軟中斷處理程序。因此,如果塊設(shè)備的軟中斷處理程序運(yùn)行時(shí)間很長(zhǎng),那么網(wǎng)絡(luò)和定時(shí)器處理程序可能就會(huì)被無(wú)限期地延遲。即使不同類型的軟中斷處理程序之間很少出現(xiàn)競(jìng)爭(zhēng),情況仍然是如此。沒(méi)有確切的方法可以確定同時(shí)運(yùn)行兩個(gè)處理程序是否安全,因此人們不會(huì)這樣做。
Weisbecker 的 patch set 旨在通過(guò)在定時(shí)器子系統(tǒng)中采用 BKL 方式的遷移到更底層實(shí)現(xiàn)的方法來(lái)解決這個(gè)問(wèn)題。定時(shí)器函數(shù)會(huì)在內(nèi)核的各個(gè)地方被放到隊(duì)列里等待調(diào)用;它們往往是互相獨(dú)立的,與其他軟中斷處理程序并不會(huì)產(chǎn)生并發(fā)問(wèn)題。幾乎所有的定時(shí)器函數(shù)都可以與其他軟中斷處理完全并發(fā)地運(yùn)行 —— 但是這里說(shuō)的是“幾乎”。在沒(méi)有確定每個(gè)定時(shí)器函數(shù)的安全性的情況下,使定時(shí)器處理完全獨(dú)立于軟中斷處理可能會(huì)引入很難調(diào)試的問(wèn)題。
相反,Weisbecker 采取了分成兩步的方法來(lái)增加定時(shí)器處理的并發(fā)性。第一步是允許單個(gè)軟中斷向量在不完全禁用軟中斷處理的情況下被禁用。這個(gè) patch set 的目的是允許定時(shí)器函數(shù)與其他軟中斷并發(fā)運(yùn)行,但它們?nèi)匀徊粫?huì)跟彼此并發(fā)運(yùn)行。通過(guò)禁用定時(shí)器事件的處理(在本地 CPU 上),定時(shí)器處理程序可以安全地重新啟用軟中斷處理,而無(wú)需擔(dān)心會(huì)再次調(diào)用它。
第二步是允許單個(gè) timer 函數(shù)來(lái)通知到定時(shí)器(timer)子系統(tǒng),說(shuō)它們可以跟其他軟中斷處理并發(fā)運(yùn)行。任何不會(huì)與軟中斷處理程序競(jìng)爭(zhēng)、或者在需要時(shí)得執(zhí)行自己的軟中斷禁用代碼的定時(shí)器函數(shù),都可以在設(shè)置其定時(shí)器事件時(shí)添加 TIMER_SOFTINTERRUPTIBLE flag 來(lái)標(biāo)記。當(dāng)定時(shí)器子系統(tǒng)看到此標(biāo)志時(shí),就會(huì)在該定時(shí)器函數(shù)運(yùn)行時(shí)重新啟用軟中斷處理。因此,如果出現(xiàn)更重要的工作的話,這個(gè) timer 函數(shù)就可以被搶占。
在 patch set 中只有一個(gè)定時(shí)器函數(shù) process_timeout()是以這種方式標(biāo)記的。然而,Weisbecker 期待著“幾年后”的一天內(nèi)核的所有定時(shí)器函數(shù)都已經(jīng)過(guò) audit,并可以安全地與軟中斷處理程序并發(fā)運(yùn)行;在那時(shí),將可以完全從軟中斷機(jī)制中移除定時(shí)器處理。這樣以來(lái)就是朝著最終消除軟中斷的一個(gè)小步驟。
顯然,需要進(jìn)行相當(dāng)多的工作才能達(dá)到這一點(diǎn)。即使這個(gè) patch set 也需要“更多微調(diào)”,以使可以中斷的 timer 函數(shù)能夠搶占其他軟中斷處理程序,這是解決問(wèn)題的重要部分。但是,如果這項(xiàng)工作能夠進(jìn)入 mainline 的話,它可能就能代表著朝著這個(gè)方向邁出了一步。Weisbecker 現(xiàn)在已經(jīng)嘗試了幾次解決軟中斷的問(wèn)題,但沒(méi)有取得太大的成功。然而最終,就像 BKL 一樣,正確的方法將會(huì)被找到,長(zhǎng)期存在的問(wèn)題終將得到解決。
審核編輯:劉清
-
處理器
+關(guān)注
關(guān)注
68文章
20265瀏覽量
252735 -
cpu
+關(guān)注
關(guān)注
68文章
11288瀏覽量
225241 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3368瀏覽量
123841 -
LINUX內(nèi)核
+關(guān)注
關(guān)注
1文章
321瀏覽量
23225 -
軟中斷
+關(guān)注
關(guān)注
0文章
9瀏覽量
3241
原文標(biāo)題:LWN:把軟中斷鎖放到更底層去!
文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
請(qǐng)問(wèn)TC39x如何將變量放到自定義的段中去呢?
已解決_緊急救助-如何把貼片元件放到底層
轉(zhuǎn)第16章 FreeRTOS調(diào)度鎖,任務(wù)鎖和中斷鎖
第11章 臨界段,任務(wù)鎖和中斷鎖
面向嵌入式Linux系統(tǒng)的軟中斷設(shè)計(jì)與實(shí)現(xiàn)
軟中斷程序設(shè)計(jì)
什么是CDMA的"更軟切換"?
什么是CDMA的"更軟切換"
關(guān)于FPGA中的PLL等價(jià)于MCU中的軟中斷指令
Linux 2.4.x內(nèi)核軟中斷機(jī)制
如何制作一個(gè)軟鎖存電路
自旋鎖和互斥鎖的區(qū)別有哪些
軟中斷與硬中斷介紹
互斥鎖和自旋鎖的區(qū)別 自旋鎖臨界區(qū)可以被中斷嗎?
CPU中斷程序:從硬件看什么是中斷?
為什么要把軟中斷鎖放到更底層去呢?
評(píng)論