Linux kernel之Block IO系統(tǒng)

1.背景

1.1 block device 處理流程

image.png
  • VFS
    VFS 將調(diào)用用戶系統(tǒng)調(diào)用API read() 處理轉(zhuǎn)換成對(duì)應(yīng)的內(nèi)核系統(tǒng)調(diào)用服務(wù)程序陡蝇,并將對(duì)應(yīng)的read 操作重定向到具體的文件系統(tǒng)的操作實(shí)現(xiàn)比驻。
  • FS
    本質(zhì)上棋蚌,文件系統(tǒng)最小訪問單位為block, 對(duì)于文件系統(tǒng)來說,文件由一個(gè)個(gè)block 構(gòu)成璃诀,文件系統(tǒng)通過file block number定位數(shù)據(jù)在文件中的位置(相對(duì)于文件的起始位置)弧可。而磁盤同樣有一個(gè)個(gè)固定大小的block 構(gòu)成,文件系統(tǒng)通過logical block number(相對(duì)于磁盤開始位置)定位磁盤的位置劣欢。
    1)FS根據(jù)文件系統(tǒng)最小可訪問單位block size棕诵,確定訪問的數(shù)據(jù)的內(nèi)容的 file block number(相對(duì)于文件起始位置);
    2)根據(jù)1)要訪問的數(shù)據(jù)的file block number凿将,調(diào)用具體文件系統(tǒng)的函數(shù)校套,確定要訪問的數(shù)據(jù)映射在磁盤中的位置logical block number(相對(duì)于磁盤);
  • Block layer
    block layer 為所有類型的塊設(shè)備建立統(tǒng)一的模型,抽象底層HW 的細(xì)節(jié)牧抵,為塊設(shè)備提供一個(gè)通用的視角笛匙。block layer 接收上層(文件系統(tǒng))對(duì)塊設(shè)備的磁盤操作請(qǐng)求,最終發(fā)送IO 情況
  • device driver
    通過發(fā)送對(duì)應(yīng)的command 給HW 以驅(qū)動(dòng)實(shí)際數(shù)據(jù)的傳輸犀变。

1.2 block layer

  • block layer 可劃分為兩層:bio layer , request layer
    image.png

2. block layer 工作原理

2.0 IO處理

i. 數(shù)據(jù)組織數(shù)據(jù)結(jié)構(gòu):bio/bio_vec
ii. bio 的處理
(1)bio 的 split 和 merge妹孙;
(2)bio 的bounce;
(3)bio 包裝成 request获枝;
iii. request 的處理
(1)request 的分配和獲却勒;
(2)request 的 plug/unplug省店;
(3)request 的下發(fā)机隙;

2.1 核心數(shù)據(jù)結(jié)構(gòu) bio/bio_vec

bio :
i. main unit of I/O for the block layer and lower layers (ie drivers and stacking drivers)(官方解釋)
ii. bio結(jié)構(gòu)體用于表示IO 請(qǐng)求(1)數(shù)據(jù)在內(nèi)存和磁盤的位置, (2)數(shù)據(jù)大小以及(3)IO完成情況
iii. bio 中重要的數(shù)據(jù)結(jié)構(gòu):bio_vec和bi_iter
bio_vec:描述了IO數(shù)據(jù)在內(nèi)存中的組織
bi_iter: 描述了IO數(shù)據(jù)在磁盤中位置以及當(dāng)前IO數(shù)據(jù)的完成情況

bio/bio_vec/bi_iter圖示.png

struct bio_vec {
    struct page *bv_page;
    unsigned int    bv_len;
    unsigned int    bv_offset;
};

struct bvec_iter {
    sector_t        bi_sector;  /* device address in 512 byte
                           sectors */
    unsigned int        bi_size;    /* residual I/O count */

    unsigned int        bi_idx;     /* current index into bvl_vec */

    unsigned int            bi_bvec_done;   /* number of bytes completed in
                           current bvec */
};

iiii. bio 和request 之間的關(guān)系
request:可由在硬盤位置連續(xù)的bio鏈接起來的

image.png

2.2 bio 的remap

i. 特定分區(qū)的bio 的bi_sector 會(huì)重映射remap 到 整個(gè)磁盤設(shè)備的 IO偏移;
ii. 另外DM 設(shè)備 mapped device 的bio 根據(jù)其映射規(guī)則需要remap 到target device的 bio.

/*
 * Remap block n of partition p to block n+start(p) of the disk.
 */
static int blk_partition_remap(struct bio *bio)
{
    struct block_device *p = bio->bi_bdev;

    if (unlikely(should_fail_request(p, bio->bi_iter.bi_size)))
        return -EIO;
    if (bio_sectors(bio)) {
        bio->bi_iter.bi_sector += p->bd_start_sect;
        trace_block_bio_remap(bio, p->bd_dev,
                      bio->bi_iter.bi_sector -
                      p->bd_start_sect);
    }
    bio_set_flag(bio, BIO_REMAPPED);
    return 0;
}

2.3 bio 的 split 和 merge

2.3.1 基本概念
bio的切分:將一個(gè)bio分成兩個(gè)bio萨西;
bio的合并:將bio與IO請(qǐng)求request進(jìn)行合并。
2.3.2 切分的依據(jù)
(1)q->limits.max_segments
表示請(qǐng)求隊(duì)列request-queue中每個(gè)IO請(qǐng)求request的最大segment數(shù)目
(2)q->limits.max_segment_size
表示請(qǐng)求隊(duì)列request-queue中每個(gè)segment最大的數(shù)據(jù)大小
(3)q->limits.max_sectors
表示請(qǐng)求隊(duì)列支持一次傳輸request的最大扇區(qū)數(shù)目即IO請(qǐng)求最大size旭旭。

image.png

2.3.3 拆分圖示

拆分前.png

拆分后.png

2.3.4 合并類型

前向合并.png

后向合并.png

2.3.5 合并過程-兩種機(jī)制的合并
(1)與plug/unplug 機(jī)制的plug->mq_list中的request進(jìn)行合并谎脯。
(2)與 IO調(diào)度器機(jī)制的schedule list (定義IO調(diào)度器)或block mq的軟件queue機(jī)制ctx->rq_lists(沒有定義IO調(diào)度器)上request進(jìn)行合并。

2.4 bio 包裝成 request

經(jīng)過bio split 和bio merge持寄, bio 還在的話源梭,會(huì)將bio 封裝到request 中娱俺,后續(xù)操作的對(duì)象由bio 轉(zhuǎn)向 request。

2.5 request 的分配和獲取

2.5.1 request 的分配
i. request 分配: 在初始化階段就分配好
ii. request 申請(qǐng): runtime 時(shí)通過申請(qǐng)一個(gè)空閑的tag獲取一個(gè)空閑的request 废麻。
iii. tag 和 request 一一對(duì)應(yīng)荠卷。
xi. tag 管理:通過sbitmap_queue 管理
2.5.2 tag 管理-sbitmap_queue
sbitmap_queue 在bitmap 基礎(chǔ)之上增加
(1)bitmap分組管理的功能(sbitmap);
(2)等待功能烛愧,即在沒有無空閑bit時(shí)油宜,會(huì)讓隊(duì)列一直等待
2.5.3 request 分配
i. 初始化階段,根據(jù)硬件的queue 數(shù)量和隊(duì)列深度怜姿,分配nr_hw_queues 個(gè)hctx, 每個(gè)hctx 對(duì)應(yīng)一套blk_mq_tags,
ii. 每個(gè)HCTX慎冤,存在total_tags和reserved_tags兩個(gè)sbitmap,分別用于分配和釋放tags以及reserved_tags及與之對(duì)應(yīng)的request沧卢。
iii. static_rq指向提前分配的request(包括(nvme/scsi)command以及底層驅(qū)動(dòng)的私有結(jié)構(gòu))蚁堤。提前分配的靜態(tài)request數(shù)目為nr_hw_queues * queue_depth。

image.png

2.5.4 request 獲取
先申請(qǐng)空閑的tag,若沒有空閑的tag,則通過等待機(jī)制等空閑的tag, 然后找到對(duì)應(yīng)的request,

2.6 request 的 plug/unplug

i. plug/unplug機(jī)制但狭,通過request的延遲下發(fā)披诗,為后續(xù)的IO增加合并和排序操作的可能,以減少request 數(shù)量立磁。類似于蓄流和泄流呈队。
ii. 工作流程:在開啟機(jī)制后,request 會(huì)放置到plug list中(plug過程)息罗,當(dāng)達(dá)到某個(gè)條件時(shí)會(huì)將request 統(tǒng)一下發(fā)(unplug過程)掂咒。
iii. plug的時(shí)機(jī)
plug 通過block_start_plug()開啟的。對(duì)于每個(gè)線程描述符task_struct迈喉,存在成員blk_plug绍刮,若為空表示沒有使能PLUG,否則表示已使能PLUG挨摸。函數(shù)blk_start_plug()進(jìn)行成員初始化孩革,同時(shí)給task_struct->plug賦值。
在開啟BLOCK PLUG后得运,可以將通過函數(shù)blk_add_rq_to_plug()將IO請(qǐng)求加入到plug->mq_list中膝蜈,且判斷所包含的IO請(qǐng)求是否來自多個(gè)隊(duì)列(通過成員multiple_queues)。
xi. unplug的時(shí)機(jī)
unplug的時(shí)機(jī)有三種:
(1)所積攢的IO數(shù)目達(dá)到BLK_MAX_REQUEST_COUNT(16)
(2)或遇到的IO大小超過BLK_PLUG_FLUSH_SIZE (128K)時(shí)熔掺;
(3)使用blk_finish_plug()主動(dòng)沖刷饱搏;

2.7 IO 的下發(fā)路徑

IO 下發(fā)處理路徑
路徑一:使能了plug/unplug機(jī)制,此時(shí)會(huì)等待plug池中存取足夠的IO后統(tǒng)一往調(diào)度器插入IO置逻,并選取IO下發(fā)推沸;
路徑二:沒有使能plug/unplug機(jī)制,此時(shí)會(huì)將IO插入調(diào)度器中,并選取IO下發(fā)鬓催;
路徑三:跳過調(diào)度層肺素,直接下發(fā)IO;

image.png

參考block layer 系列文章:https://blog.csdn.net/flyingnosky/article/details/121341392

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宇驾,一起剝皮案震驚了整個(gè)濱河市倍靡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌课舍,老刑警劉巖塌西,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異布卡,居然都是意外死亡雨让,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門忿等,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栖忠,“玉大人,你說我怎么就攤上這事贸街♀帜” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵薛匪,是天一觀的道長(zhǎng)捐川。 經(jīng)常有香客問我,道長(zhǎng)逸尖,這世上最難降的妖魔是什么古沥? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮娇跟,結(jié)果婚禮上岩齿,老公的妹妹穿的比我還像新娘。我一直安慰自己苞俘,他們只是感情好盹沈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吃谣,像睡著了一般乞封。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岗憋,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天肃晚,我揣著相機(jī)與錄音,去河邊找鬼仔戈。 笑死陷揪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悍缠,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼耐量!你這毒婦竟也來了飞蚓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤廊蜒,失蹤者是張志新(化名)和其女友劉穎趴拧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體山叮,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡著榴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屁倔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脑又。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖锐借,靈堂內(nèi)的尸體忽然破棺而出问麸,到底是詐尸還是另有隱情,我是刑警寧澤钞翔,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布严卖,位于F島的核電站,受9級(jí)特大地震影響布轿,放射性物質(zhì)發(fā)生泄漏哮笆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一汰扭、第九天 我趴在偏房一處隱蔽的房頂上張望稠肘。 院中可真熱鬧,春花似錦东且、人聲如沸启具。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲁冯。三九已至,卻和暖如春色查,著一層夾襖步出監(jiān)牢的瞬間薯演,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工秧了, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跨扮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像衡创,于是被迫代替她去往敵國(guó)和親帝嗡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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