Big Kernel Lock vs FIFO Ticket Spinlock in Linux


layout: post
title: "Big Kernel Lock vs FIFO Ticket Spinlock in Linux"
date: 2013-10-30 18:58
comments: true
categories: Linux
tag: [linux, kernel, spinlock, big kernel lock, baidu]
keywords: linux kernel, spinlock kernel lock
description: a item from 2014 baidu interview


這里先寫一篇基礎(chǔ)文章引入一下自旋鎖纹蝴、排隊(duì)自旋鎖和大內(nèi)核鎖扩所。

自旋鎖(Spinlock)是一種 Linux 內(nèi)核中廣泛運(yùn)用的底層同步機(jī)制。自旋鎖是一種工作于多處理器環(huán)境的特殊的鎖刻剥,在單處理環(huán)境中自旋鎖的操作被替換為空操作育灸。當(dāng)某個(gè)處理器上的內(nèi)核執(zhí)行線程申請(qǐng)自旋鎖時(shí)腻窒,如果鎖可用,則獲得鎖磅崭,然后執(zhí)行臨界區(qū)操作儿子,最后釋放鎖;{% img right http://image.zcool.com.cn/cover/20/23/1305391757594.jpg 328 268 %}如果鎖已被占用绽诚,線程并不會(huì)轉(zhuǎn)入睡眠狀態(tài)典徊,而是忙等待該鎖杭煎,一旦鎖被釋放恩够,則第一個(gè)感知此信息的線程將獲得鎖。

linux傳統(tǒng)的自旋鎖

本質(zhì)上用一個(gè)整數(shù)來(lái)表示羡铲,值為1代表鎖未被占用蜂桶。這種無(wú)序競(jìng)爭(zhēng)的本質(zhì)特點(diǎn)導(dǎo)致執(zhí)行線程無(wú)法保證何時(shí)能取到鎖,某些線程可能需要等待很長(zhǎng)時(shí)間也切。隨著計(jì)算機(jī)處理器個(gè)數(shù)的不斷增長(zhǎng)扑媚,這種“不公平”問(wèn)題將會(huì)日益嚴(yán)重。

排隊(duì)自旋鎖(FIFO Ticket Spinlock)是 Linux 內(nèi)核 2.6.25 版本引入的一種新型自旋鎖雷恃,它通過(guò)保存執(zhí)行線程申請(qǐng)鎖的順序信息解決了傳統(tǒng)自旋鎖的“不公平”問(wèn)題疆股。排隊(duì)自旋鎖的代碼由 Linux 內(nèi)核開(kāi)發(fā)者 Nick Piggin 實(shí)現(xiàn)。

傳統(tǒng)的Linux 內(nèi)核自旋鎖的底層數(shù)據(jù)結(jié)構(gòu) raw_spinlock_t 定義如下:

typedef struct {
    unsigned int slock;
} raw_spinlock_t;

slock 雖然被定義為無(wú)符號(hào)整數(shù)倒槐,但是實(shí)際上被當(dāng)作有符號(hào)整數(shù)使用旬痹。slock 值為 1 代表鎖未被占用,值為 0 或負(fù)數(shù)代表鎖被占用讨越。初始化時(shí) slock 被置為 1两残。
線程通過(guò)宏 spin_lock 申請(qǐng)自旋鎖。

盡管擁有使用簡(jiǎn)單方便把跨、性能好的優(yōu)點(diǎn)人弓,自旋鎖也存在自身的不足:

  1. 由于傳統(tǒng)自旋鎖無(wú)序競(jìng)爭(zhēng)的本質(zhì)特點(diǎn),內(nèi)核執(zhí)行線程無(wú)法保證何時(shí)可以取到鎖着逐,某些執(zhí)行線程可能需要等待很長(zhǎng)時(shí)間崔赌,導(dǎo)致“不公平”問(wèn)題的產(chǎn)生意蛀。這有兩方面的原因:
  • 隨著處理器個(gè)數(shù)的不斷增加,自旋鎖的競(jìng)爭(zhēng)也在加劇健芭,自然導(dǎo)致更長(zhǎng)的等待時(shí)間浸间。
  • 釋放自旋鎖時(shí)的重置操作將無(wú)效化所有其它正在忙等待的處理器的緩存,那么在處理器拓?fù)浣Y(jié)構(gòu)中臨近自旋鎖擁有者的處理器可能會(huì)更快地刷新緩存吟榴,因而增大獲得自旋鎖的機(jī)率魁蒜。
  1. 由于每個(gè)申請(qǐng)自旋鎖的處理器均在全局變量 slock 上忙等待,系統(tǒng)總線將因?yàn)樘幚砥鏖g的緩存同步而導(dǎo)致繁重的流量吩翻,從而降低了系統(tǒng)整體的性能兜看。

linux排隊(duì)自旋鎖

傳統(tǒng)自旋鎖的“不公平”問(wèn)題在鎖競(jìng)爭(zhēng)激烈的服務(wù)器系統(tǒng)中尤為嚴(yán)重,因此 Linux 內(nèi)核開(kāi)發(fā)者 Nick Piggin 在 Linux 內(nèi)核 2.6.25 版本中引入了排隊(duì)自旋鎖:通過(guò)保存執(zhí)行線程申請(qǐng)鎖的順序信息來(lái)解決“不公平”問(wèn)題狭瞎。

排隊(duì)自旋鎖仍然使用原有的 raw_spinlock_t 數(shù)據(jù)結(jié)構(gòu)细移,但是賦予 slock 域新的含義。為了保存順序信息熊锭,slock 域被分成兩部分弧轧,分別保存鎖持有者和未來(lái)鎖申請(qǐng)者的票據(jù)序號(hào)(Ticket Number),如下圖所示:

圖示:next和owner域

next和owner域
next和owner域

如果處理器個(gè)數(shù)不超過(guò) 256碗殷,則 Owner 域?yàn)?slock 的 0-7 位精绎,Next 域?yàn)?slock 的 8-15 位,slock 的高 16 位不使用锌妻;如果處理器個(gè)數(shù)超過(guò) 256代乃,則 Owner 和 Next 域均為 16 位,其中 Owner 域?yàn)?slock 的低 16 位仿粹「橄牛可見(jiàn)排隊(duì)自旋鎖最多支持 216=65536 個(gè)處理器.。
只有 Next 域與 Owner 域相等時(shí)吭历,才表明鎖處于未使用狀態(tài)(此時(shí)也無(wú)人申請(qǐng)?jiān)撴i)堕仔。排隊(duì)自旋鎖初始化時(shí) slock 被置為 0,即 Owner 和 Next 置為 0晌区。內(nèi)核執(zhí)行線程申請(qǐng)自旋鎖時(shí)摩骨,原子地將 Next 域加 1,并將原值返回作為自己的票據(jù)序號(hào)契讲。如果返回的票據(jù)序號(hào)等于申請(qǐng)時(shí)的 Owner 值仿吞,說(shuō)明自旋鎖處于未使用狀態(tài),則直接獲得鎖捡偏;否則唤冈,該線程忙等待檢查 Owner 域是否等于自己持有的票據(jù)序號(hào),一旦相等银伟,則表明鎖輪到自己獲取你虹。線程釋放鎖時(shí)绘搞,原子地將 Owner 域加 1 即可,下一個(gè)線程將會(huì)發(fā)現(xiàn)這一變化傅物,從忙等待狀態(tài)中退出夯辖。線程將嚴(yán)格地按照申請(qǐng)順序依次獲取排隊(duì)自旋鎖,從而完全解決了“不公平”問(wèn)題董饰。

linux大內(nèi)核鎖

大內(nèi)核鎖本質(zhì)上也是自旋鎖蒿褂,但是它又不同于自旋鎖,自旋鎖是不可以遞歸獲得鎖的卒暂,因?yàn)槟菢訒?huì)導(dǎo)致死鎖啄栓。但大內(nèi)核鎖可以遞歸獲得鎖。大內(nèi)核鎖用于保護(hù)整個(gè)內(nèi)核也祠,而自旋鎖用于保護(hù)非常特定的某一共享資源昙楚。進(jìn)程保持大內(nèi)核鎖時(shí)可以發(fā)生調(diào)度,具體實(shí)現(xiàn)是:在執(zhí)行schedule時(shí)诈嘿,schedule將檢查進(jìn)程是否擁有大內(nèi)核鎖堪旧,如果有,它將被釋放奖亚,以致于其它的進(jìn)程能夠獲得該鎖淳梦,而當(dāng)輪到該進(jìn)程運(yùn)行時(shí),再讓它重新獲得大內(nèi)核鎖遂蛀。注意在保持自旋鎖期間是不運(yùn)行發(fā)生調(diào)度的谭跨。

需要特別指出干厚,整個(gè)內(nèi)核只有一個(gè)大內(nèi)核鎖李滴,其實(shí)不難理解,內(nèi)核只有一個(gè)蛮瞄,而大內(nèi)核鎖是保護(hù)整個(gè)內(nèi)核的所坯,當(dāng)然有且只有一個(gè)就足夠了。

還需要特別指出的是挂捅,大內(nèi)核鎖是歷史遺留芹助,內(nèi)核中用的非常少,一般保持該鎖的時(shí)間較長(zhǎng)闲先,因此不提倡使用它状土。從2.6.11內(nèi)核起,大內(nèi)核鎖可以通過(guò)配置內(nèi)核使其變得可搶占(自旋鎖是不可搶占的)伺糠,這時(shí)它實(shí)質(zhì)上是一個(gè)互斥鎖蒙谓,使用信號(hào)量實(shí)現(xiàn)。

大內(nèi)核鎖的API包括:

void lock_kernel(void); 

該函數(shù)用于得到大內(nèi)核鎖训桶。它可以遞歸調(diào)用而不會(huì)導(dǎo)致死鎖累驮。

void unlock_kernel(void); 

該函數(shù)用于釋放大內(nèi)核鎖酣倾。當(dāng)然必須與lock_kernel配對(duì)使用,調(diào)用了多少次lock_kernel谤专,就需要調(diào)用多少次unlock_kernel躁锡。
大內(nèi)核鎖的API使用非常簡(jiǎn)單,按照以下方式使用就可以了:

lock_kernel();
//對(duì)被保護(hù)的共享資源的訪問(wèn)
…
unlock_kernel()置侍;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末映之,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蜡坊,更是在濱河造成了極大的恐慌惕医,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件算色,死亡現(xiàn)場(chǎng)離奇詭異抬伺,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)灾梦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門峡钓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人若河,你說(shuō)我怎么就攤上這事能岩。” “怎么了萧福?”我有些...
    開(kāi)封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵拉鹃,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我鲫忍,道長(zhǎng)膏燕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任悟民,我火速辦了婚禮坝辫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘射亏。我一直安慰自己近忙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布智润。 她就那樣靜靜地躺著及舍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窟绷。 梳的紋絲不亂的頭發(fā)上锯玛,一...
    開(kāi)封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音钾麸,去河邊找鬼更振。 笑死炕桨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肯腕。 我是一名探鬼主播献宫,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼实撒!你這毒婦竟也來(lái)了姊途?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤知态,失蹤者是張志新(化名)和其女友劉穎捷兰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體负敏,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贡茅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了其做。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顶考。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖妖泄,靈堂內(nèi)的尸體忽然破棺而出驹沿,到底是詐尸還是另有隱情,我是刑警寧澤蹈胡,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布渊季,位于F島的核電站,受9級(jí)特大地震影響罚渐,放射性物質(zhì)發(fā)生泄漏却汉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一搅轿、第九天 我趴在偏房一處隱蔽的房頂上張望病涨。 院中可真熱鬧,春花似錦璧坟、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至励两,卻和暖如春黎茎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背当悔。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工傅瞻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踢代,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓嗅骄,卻偏偏與公主長(zhǎng)得像胳挎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子溺森,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容