最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

一文解析Multi-queue 架構(gòu)

2023-05-06 16:28 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

Linux上傳統(tǒng)的塊設(shè)備層(Block Layer)和IO調(diào)度器(如cfq)主要是針對HDD(hard disk drivers)設(shè)計(jì)的。我們知道,HDD設(shè)備的隨機(jī)IO性能很差,吞吐量大約是幾百IOPS(IOs per second),延遲在毫秒級,所以當(dāng)時(shí)IO性能的瓶頸在硬件,而不是內(nèi)核。但是,隨著高速SSD(Solid State Disk)的出現(xiàn)并展現(xiàn)出越來越高的性能,百萬級甚至千萬級IOPS的數(shù)據(jù)訪問已成為一大趨勢,傳統(tǒng)的塊設(shè)備層已無法滿足這么高的IOPS需求,逐漸成為系統(tǒng)IO性能的瓶頸。

為了適配現(xiàn)代存設(shè)備(高速SSD等)高IOPS、低延遲的IO特征,新的塊設(shè)備層框架Block multi-queue(blk-mq)應(yīng)運(yùn)而生。本文就帶大家來了解下Linux 塊設(shè)備層的blk-mq框架和代碼實(shí)現(xiàn)。


一、單隊(duì)列框架和存在的問題

Linux上傳統(tǒng)塊設(shè)備層使用單隊(duì)列(Single-queue/SQ)架構(gòu),如圖1所示。簡單來說,塊設(shè)備層負(fù)責(zé)管理從用戶進(jìn)程到存儲設(shè)備的IO請求,一方面為上層提供訪問不同存儲設(shè)備的統(tǒng)一接口,隱藏存儲設(shè)備的復(fù)雜性和多樣性;另一方面,為存儲設(shè)備驅(qū)動程序提供通用服務(wù),讓這些驅(qū)動程序以最適合的方式接收來自上層的IO請求。Linux Block Layer主要提供以下幾個(gè)方面的功能:

  • bio的提交和完成處理,上層通過bio來統(tǒng)一描述發(fā)往塊設(shè)備的IO請求

  • IO請求暫存,如合并、排序等

  • IO調(diào)度,如noop、cfq、deadline等

  • IO記賬,如統(tǒng)計(jì)提交到塊設(shè)備的IO總量,IO延遲等信息

圖1. 單隊(duì)列的Linux block layer設(shè)計(jì)

圖片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》

由于采用單隊(duì)列(每個(gè)塊設(shè)備1個(gè)請求隊(duì)列--Requst Queue)的設(shè)計(jì),傳統(tǒng)的Block Layer對多核體系的可擴(kuò)展性(scalability)不佳。當(dāng)系統(tǒng)配備現(xiàn)代高速存儲器件時(shí),單隊(duì)列引入的軟件開銷變得突出(在多socket體系中尤為嚴(yán)重),成為IO性能的瓶頸。多核體系中blk-sq的軟件開銷主要來自三個(gè)方面:

  • 請求隊(duì)列鎖競爭:blk-sq使用spinlock(q->queue_lock)來同步IO請求隊(duì)列的訪問,每次往請求隊(duì)列中插入或刪除IO請求,必須先獲取此鎖;IO提交時(shí)如果操作請求隊(duì)列,必須先獲取此鎖;IO排序和調(diào)度操作時(shí),也必須先獲取此鎖。這一系列操作繼續(xù)之前,必須先獲得請求隊(duì)列鎖,在高IOPS場景(多個(gè)線程同時(shí)提交IO請求)下,勢必引起劇烈的鎖競爭,帶來不可忽視的軟件開銷。從圖2中可以看到,Linux- 2.6.32 中scsi+blk-sq,高IOPS場景下,約80%的cpu時(shí)間耗費(fèi)在鎖獲取上。

圖2. 高IOPS場景下cpu熱點(diǎn)數(shù)據(jù)

圖片引用自《High Performance Storage with blk-mq and scsi-mq》

  • 硬件中斷:高的IOPS意味著高的中斷數(shù)量。在多數(shù)情況下,完成一次IO需要兩次中斷,一次是存儲器件觸發(fā)的硬件中斷,另一次是IPI核間中斷用于觸發(fā)其他cpu上的軟中斷。

  • 遠(yuǎn)端內(nèi)存訪問:如果提交IO請求的cpu不是接收硬件中斷的cpu且這兩個(gè)cpu沒有共享緩存,那么獲取請求隊(duì)列鎖的過程中還存在遠(yuǎn)端內(nèi)存訪問問題。


圖3. blk-sq IOPS吞吐量隨cpu數(shù)量的變化曲線,blk-sq支持的最高吞吐量大概在1MIOPS

圖片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》


二、多隊(duì)列框架和解決的問題

針對blk-sq存在的問題,Jens Axboe (Linux內(nèi)核Block Layer Maintainer)提出了多隊(duì)列(multi-queue/MQ)的塊設(shè)備層架構(gòu)(blk-mq),如圖4所示:



圖4. 兩層隊(duì)列的Block Layer設(shè)計(jì)

圖片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》

blk-mq中使用了兩層隊(duì)列,將單個(gè)請求隊(duì)列鎖的競爭分散多個(gè)隊(duì)列中,極大的提高了Block Layer并發(fā)處理IO的能力。兩層隊(duì)列的設(shè)計(jì)分工明確:

  • 軟件暫存隊(duì)列(Software Staging Queue):blk-mq中為每個(gè)cpu分配一個(gè)軟件隊(duì)列,bio的提交/完成處理、IO請求暫存(合并、排序等)、IO請求標(biāo)記、IO調(diào)度、IO記賬都在這個(gè)隊(duì)列上進(jìn)行。由于每個(gè)cpu有單獨(dú)的隊(duì)列,所以每個(gè)cpu上的這些IO操作可以同時(shí)進(jìn)行,而不存在鎖競爭問題

  • 硬件派發(fā)隊(duì)列(Hardware Dispatch Queue):blk-mq為存儲器件的每個(gè)硬件隊(duì)列(目前多數(shù)存儲器件只有1個(gè))分配一個(gè)硬件派發(fā)隊(duì)列,負(fù)責(zé)存放軟件隊(duì)列往這個(gè)硬件隊(duì)列派發(fā)的IO請求。在存儲設(shè)備驅(qū)動初始化時(shí),blk-mq會通過固定的映射關(guān)系將一個(gè)或多個(gè)軟件隊(duì)列映射(map)到一個(gè)硬件派發(fā)隊(duì)列(同時(shí)保證映射到每個(gè)硬件隊(duì)列的軟件隊(duì)列數(shù)量基本一致),之后這些軟件隊(duì)列上的IO請求會往對應(yīng)的硬件隊(duì)列上派發(fā)。

MQ架構(gòu)解決了SQ架構(gòu)中請求隊(duì)列鎖競爭和遠(yuǎn)端內(nèi)存訪問問題,極大的提高了Block Layer的IOPS吞吐量。從圖5中,我們可以看到Linux 3.17-rc3 中scsi-mq+blk-mq,與圖2相同的高IOPS場景下僅3%的cpu時(shí)間耗費(fèi)在鎖獲取上。


圖5. scsi-mq_+blk-mq高IOPS場景下cpu熱點(diǎn)數(shù)據(jù)

圖片引用自《High Performance Storage with blk-mq and scsi-mq》


圖6. IOPS吞吐量隨cpu數(shù)量的變化曲線,blk-mq更加接近raw設(shè)備的性能

圖片引用自《Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems》



【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)??


三、多隊(duì)列框架代碼分析

blk-mq代碼在Linux-3.13(2014)內(nèi)核中合入主線,在Linux-3.16中成為內(nèi)核的一個(gè)完整特性,在Linux-5.0內(nèi)核中,blk-sq代碼(包括基于blk-sq的IO調(diào)度器,如cfq、noop)已被完全移除,MQ成為Linux Block layer的默認(rèn)選項(xiàng)。下面基于Linux-5.6.0內(nèi)核介紹blk-mq代碼和關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。


request和tag分配

blk-mq中,request和tag是綁定的。首先,我們來看下兩個(gè)與tag分配有關(guān)的重要數(shù)據(jù)結(jié)構(gòu)--blk_mq_tags和blk_mq_tag_set。

  • blk_mq_tags,用于描述tag和request的集合,它的主要成員如下:


  • blk_mq_tag_set,用于描述與存儲器件相關(guān)的tag集合,抽象了存儲器件的IO特征,它的主要成員如下:


與SQ框架一樣,MQ框架中使用request結(jié)構(gòu)體來描述IO請求;不同的是,SQ使用內(nèi)存池來分配request結(jié)構(gòu)體(參見__get_request),在request往驅(qū)動派發(fā)時(shí)分配tag(參見blk_queue_start_tag),MQ中request和tag分配是綁定在一起的(參見blk_mq_get_request), 具體表現(xiàn)為:

  • request內(nèi)存分配在塊設(shè)備驅(qū)動初始化時(shí)完成(通過調(diào)用blk_mq_alloc_tag_set),避免IO發(fā)生時(shí)request內(nèi)存分配帶來的開銷

  • tag 作為request(static_rqs/rqs數(shù)組)的索引

blk_mq_alloc_tag_set: 為一個(gè)或者多個(gè)請求隊(duì)列分配tag和request集合(tag set可以是多個(gè)request queue共享的,例如UFS設(shè)備,一個(gè)host controller只有一個(gè)tag set,但器件可能劃分成多個(gè)LU--Logical Unit,每個(gè)LU有單獨(dú)的request queue, 這些不同的request queue共享一個(gè)tag set),主要流程如下:

  • 設(shè)置硬件隊(duì)列數(shù)量(nr_hw_queues)和映射表數(shù)量(nr_maps)

  • 調(diào)用blk_mq_realloc_tag_set_tag 根據(jù)硬件隊(duì)列數(shù)量擴(kuò)展tags數(shù)組

  • 調(diào)用blk_mq_update_queue_map更新映射表(map: cpu id->hw queue id)

  • 調(diào)用blk_mq_alloc_rq_maps分配request和tag(隊(duì)列深度可能會根據(jù)內(nèi)存狀態(tài)下調(diào))

圖7. scsi-mq驅(qū)動初始化時(shí)tag set分配流程

blk_mq_get_request: 為bio分配request。MQ中request占用的內(nèi)存在塊設(shè)備驅(qū)動初始化時(shí)分配完成(tags->static_rqs), tag作為數(shù)組的索引獲取對應(yīng)的request,因此MQ中分配request即分配tag(使用sbitmap標(biāo)記對應(yīng)tag的是否已被使用)。該函數(shù)的主要流程如下:

  • 調(diào)用blk_mq_get_ctx 獲取當(dāng)前cpu的軟件隊(duì)列(ctx)

  • 調(diào)用blk_mq_map_queue 找到軟件隊(duì)列(ctx)對應(yīng)的硬件派發(fā)隊(duì)列(hctx)

  • 對于配置了調(diào)度器的隊(duì)列,調(diào)用limit_depth限制隊(duì)列深度(影響tag獲取);對于無調(diào)度器的隊(duì)列,更新tag set的當(dāng)前活躍隊(duì)列數(shù)量(用于均分tag到不同request_queue)

  • 調(diào)用blk_mq_get_tag獲取tag, 可能因當(dāng)前無可用tag進(jìn)入iowait狀態(tài)

  • 調(diào)用blk_mq_rq_ctx_init 初始化tag對應(yīng)的request(tags->static_rqs[tag])

圖8. blk-mq bio提交時(shí)request分配流程


request_queue初始化

基于blk-mq的塊設(shè)備驅(qū)動初始化時(shí),通過調(diào)用blk_mq_init_queue初始化IO請求隊(duì)列(request_queue)。例如,scsi-mq驅(qū)動中,每次添加scsi設(shè)備(scsi_device)時(shí)都會調(diào)用blk_mq_init_queue接口來初始化scsi設(shè)備的請求隊(duì)列。
blk_mq_init_queue:初始化IO請求隊(duì)列--request_queue。函數(shù)的主要流程如下:

  • 調(diào)用blk_alloc_queue_node分配請求隊(duì)列的內(nèi)存,分配的內(nèi)存節(jié)點(diǎn)與設(shè)備連接的NUMA節(jié)點(diǎn)一致,避免遠(yuǎn)端內(nèi)存訪問問題。

  • 調(diào)用blk_mq_init_allocated_queue初始化分配的請求隊(duì)列(request_queue),blk-mq的request_queue中包含兩層隊(duì)列,即percpu的軟件隊(duì)列(ctx)和與塊設(shè)備硬件隊(duì)列一一對應(yīng)的硬件派發(fā)隊(duì)列(hctx)。這個(gè)初始化過程主要包含下面幾步:

1.設(shè)置隊(duì)列的mq_ops(q->mq_ops)為set->ops (例如scsi對應(yīng)的實(shí)現(xiàn)是scsi_mq_ops)

2.設(shè)置request超時(shí)時(shí)間,初始化timeout_work(處理函數(shù)是blk_mq_timeout_work)

3.設(shè)置隊(duì)列的make_request回調(diào)為blk_mq_make_request (bio的提交時(shí)會用到)

4.分配和初始化percpu軟件隊(duì)列(ctx)

5.關(guān)聯(lián)request_queue和塊設(shè)備的tag set

6.更新軟件隊(duì)列(ctx)到硬件派發(fā)隊(duì)列(hctx)的映射關(guān)系(map: ctx->hctx)


圖9. scsi-mq驅(qū)動創(chuàng)建scsi device時(shí)初始化requst_queue流程


IO的提交(submit)


blk-mq中,通過調(diào)用blk_mq_make_request將上層提交的bio封裝成request并提交到塊設(shè)備層,它的主要流程如下:

  • 嘗試與當(dāng)前線程plug list(如果當(dāng)前線程正在做IO plug)中的IO request合并

  • 嘗試與當(dāng)前cpu軟件隊(duì)列中的IO request合并(如果使能調(diào)度器,且調(diào)度器實(shí)現(xiàn)bio_merge接口,則調(diào)用這個(gè)接口嘗試與調(diào)度器隊(duì)列中的IO request合并)

  • 嘗試IO請求的QoS(Quality of Service)限流(目前實(shí)現(xiàn)的QoS策略有wbt, io-latency cgroup, io-cost cgroup三種)

圖10.? blk-mq中IO提交流程

  • 獲取request,并將bio添加到request

  • 生成request后,將request插入請求隊(duì)列中,分下面幾種情況

1.如果是fua/flush請求,則將request插入到flush隊(duì)列,并調(diào)用blk_mq_run_hw_queue 啟動請求派發(fā)

2.如果當(dāng)前線程正在做IO plug且塊設(shè)備是硬件單隊(duì)列的(nr_hw_queues=1),則將request插入到當(dāng)前線程的plug list

3.如果配置了調(diào)度器,則調(diào)用blk_mq_sched_insert_request將請求插入調(diào)度器隊(duì)列(如果沒有實(shí)現(xiàn)insert_requests接口,則插入到當(dāng)前cpu的軟件隊(duì)列中)

4.如果是硬件多隊(duì)列塊設(shè)備上的同步IO請求,則調(diào)用blk_mq_try_issue_directly嘗試將request直接派發(fā)到塊設(shè)備驅(qū)動

5.其他情況,則調(diào)用blk_mq_sched_insert_request插入request(同case 3)


IO的派發(fā)(dispatch)

blk-mq中通過調(diào)用blk_mq_run_hw_queue派發(fā)IO請求到塊設(shè)備驅(qū)動,MQ框架中存在很多的點(diǎn)會觸發(fā)IO請求往塊設(shè)備驅(qū)動派發(fā),主要如下:



blk_mq_run_hw_queue: 啟動硬件隊(duì)列派發(fā)IO請求,可以是同步/異步的執(zhí)行的。如果隊(duì)列不在靜默狀態(tài)(quiesced)且有IO請求pending,則啟動派發(fā):

  • 如果是同步派發(fā),且當(dāng)前cpu的軟件隊(duì)列映射到此硬件隊(duì)列,則調(diào)用__blk_mq_run_hw_queue在當(dāng)前線程上下文中執(zhí)行IO請求派發(fā)

  • 如果是異步派發(fā),則啟動延遲任務(wù)(hctx->run_work)執(zhí)行IO請求派發(fā)

圖11. blk-mq啟動硬件隊(duì)列派發(fā)IO請求的流程

無論是同步還是異步的派發(fā)模式,最終都會調(diào)用__blk_mq_run_hw_queue派發(fā)IO請求,這個(gè)函數(shù)先檢查執(zhí)行的上下文,然后調(diào)用blk_mq_sched_dispatch_requests派發(fā)IO請求到塊設(shè)備驅(qū)動,這個(gè)函數(shù)的主要流程如下:


圖12. blk-mq派發(fā)IO請求的流程

  • 如果硬件派發(fā)隊(duì)列(hctx->dispatch)非空, 則先調(diào)用blk_mq_dispatch_rq_list派發(fā)這個(gè)隊(duì)列中的IO請求

  • 如果配置了調(diào)度器,則調(diào)用blk_mq_do_dispatch_sched 從調(diào)度隊(duì)列中派發(fā)IO請求

  • 如果隊(duì)列繁忙(dispatch_busy記錄繁忙狀態(tài)),則調(diào)用blk_mq_do_dispatch_ctx 從軟件隊(duì)列(軟件隊(duì)列選取采用Round-Robin策略)中取1個(gè)IO請求派發(fā)

  • 否則,取映射到這個(gè)硬件隊(duì)列的所有軟件隊(duì)列上的IO請求,調(diào)用blk_mq_dispatch_rq_list派發(fā)

上述4種情況都會調(diào)用blk_mq_dispatch_rq_list 將IO請求派發(fā)到塊設(shè)備驅(qū)動,這個(gè)函數(shù)使用塊設(shè)備驅(qū)動實(shí)現(xiàn)的幾個(gè)接口完成派發(fā)邏輯:



IO的完成(complete)

下面以UFS+scsi-mq驅(qū)動為例,講解IO完成處理的過程,主要流程如圖13所示:


圖13. ufs+scsi-mq驅(qū)動中一個(gè)IO的完成流程

  • UFS設(shè)備完成一個(gè)IO請求之后,觸發(fā)中斷, ufshc(UFS host controller)驅(qū)動負(fù)責(zé)處理這個(gè)中斷(服務(wù)例程是ufshc_intr),通過中斷狀態(tài)寄存器(REG_INTERRUPT_STATUS)判斷是否有IO請求完成(UTP_TRANSFER_REQ_COMPL位),通過對比門鈴寄存器(REG_UTP_TRANSFER_REQ_DOOR_BELL)和outstanding_reqs的值(異或操作)取得完成的IO請求。對于每個(gè)完成的IO請求,調(diào)用scsi_done進(jìn)入scsi 命令的完成處理流程

  • scsi-mq驅(qū)動中scsi_done的實(shí)現(xiàn)是scsi_mq_done,這個(gè)函數(shù)會調(diào)用blk-mq中的接口blk_mq_complete_request 進(jìn)入塊設(shè)備層的request完成處理流程

  • Block Layer對于request完成處理有4種方式,具體如下:

1.對于硬件單隊(duì)列的塊設(shè)備,調(diào)用__blk_complete_request處理。如果發(fā)起IO請求的cpu就是當(dāng)前cpu或者和當(dāng)前cpu共享緩存,則發(fā)起當(dāng)前cpu上的block軟中斷,在block軟中斷中繼續(xù)request完成處理流程

2.對于硬件單隊(duì)列的塊設(shè)備,如果不滿足case 1的條件,則通過IPI(inter-processor interrupt)發(fā)起其他cpu上的block軟中斷,在block軟中斷繼續(xù)request完成處理流程

3.對于硬件多隊(duì)列設(shè)備,如果當(dāng)前cpu與發(fā)起IO請求的cpu不共享緩存(且不是高優(yōu)先級的IO請求),則調(diào)用__blk_mq_complete_request_remote發(fā)起遠(yuǎn)端cpu上的request完成處理流程(IPI)

4.對于硬件多隊(duì)列設(shè)備,非上述情況,直接在當(dāng)前cpu上(硬件中斷上下文)繼續(xù)request完成處理流程

  • 上述4種情況,最后都會調(diào)用mq_ops->complete 繼續(xù)處理request的完成,對于scsi-mq驅(qū)動,這個(gè)接口的實(shí)現(xiàn)是scsi_softirq_done,經(jīng)過一系列過程調(diào)用后(參見圖13),由req_bio_endio 完成bio


四、多隊(duì)列IO調(diào)度器

事實(shí)上,在blk-mq框架一開始是不支持IO調(diào)度器的(Linux-3.13)。由于高速存儲器件IO特征是高IOPS,低延遲,我們希望IO的軟件開銷盡可能低,而IO調(diào)度會增加軟件開銷,所以專門針對這類器件設(shè)計(jì)的blk-mq在一開始并沒有加入IO調(diào)度的能力。

當(dāng)時(shí)的Linux塊設(shè)備層是SQ和MQ兩套框架共存的(SQ用于HDD這樣的慢速塊設(shè)備驅(qū)動,MQ用于nvme這樣的高速塊設(shè)備驅(qū)動)。Linux Block Layer的發(fā)展趨勢是希望能夠使用一套框架同時(shí)滿足慢速器件和高速器件的需求,所以blk-mq引入后,Linux上的塊設(shè)備驅(qū)動程序開始往MQ框架遷移,在Linux-5.0上,所有基于SQ的塊設(shè)備驅(qū)動都完成了向MQ框架的轉(zhuǎn)化,Block Layer的SQ框架和相關(guān)IO調(diào)度器被完全移除。

我們知道對于慢速器件(特別是旋轉(zhuǎn)磁盤,隨機(jī)IO性能很差)來講,IO調(diào)度是十分重要的,同時(shí)一些高速器件(特別是硬件單隊(duì)列的器件,如emmc,ufs)也有IO調(diào)度的需求。

因此在Linux-4.11上,Jens Axboe在MQ框架上增加了IO調(diào)度的能力,同SQ框架一樣,MQ中的IO調(diào)度器也是插件化的,框架提供一系列的接口,由具體的IO調(diào)度算法(如mq-deadline)實(shí)現(xiàn)這些接口:


目前基于blk-mq實(shí)現(xiàn)的IO調(diào)度器主要有下面幾個(gè):

  • mq-deadline: 根據(jù)IO請求的類型(read/write)分配不同的到期時(shí)間(deadline),并將IO請求按照deadline排序,同時(shí)支持IO合并,派發(fā)時(shí)優(yōu)先選擇deadline最小的IO請求,以此來控制IO的延遲。它在Linux-4.11上合入主線,是mq調(diào)度器的默認(rèn)選項(xiàng)。對這個(gè)調(diào)度器感興趣的同學(xué)可以閱讀參考資料8和源碼(mq-deadline.c)進(jìn)一步了解相關(guān)細(xì)節(jié)

  • bfq: budget fair queuing, 它在Linux-4.12上合入主線,主要針對的是慢速器件,如機(jī)械硬盤。它提供了IO排序、IO優(yōu)先級、按權(quán)重均勻分配IO帶寬和組調(diào)度的能力,它保證每個(gè)IO的最大延遲可控的同時(shí)充分利用器件IO帶寬。它的缺點(diǎn)是調(diào)度的軟件開銷比較高,例如Arm CortexTM-A53 8核系統(tǒng)中,最高只能支持80KIOPS,因此不適用于高速器件(如百萬級IOPS的SSD)。對這個(gè)調(diào)度器感興趣的同學(xué)可以閱讀參考資料9和源碼(bfq-iosched.c)進(jìn)一步了解相關(guān)細(xì)節(jié)

  • kyber: 它在Linux-4.12上合入主線,是一個(gè)真正意義上的mq調(diào)度器,適用于高速器件。它對不同類型的IO(read/write/discard/others)設(shè)置不同的延遲要求,分開調(diào)度,同時(shí)監(jiān)控每個(gè)IO調(diào)度域的延遲情況,如果某個(gè)IO調(diào)度域的延遲過高,則動態(tài)增加這個(gè)IO調(diào)度域的隊(duì)列深度,并減小延遲OK的IO調(diào)度域的隊(duì)列深度,以達(dá)到控制IO延遲的目的。本質(zhì)上這種調(diào)度算法傾向于優(yōu)先調(diào)度延遲要求高的IO(如read)。對這個(gè)調(diào)度器感興趣的同學(xué)可以閱讀參考資料10和源碼(kyber-iosched.c)進(jìn)一步了解相關(guān)細(xì)節(jié)


五、結(jié)語

本文主要介紹了blk-mq框架,基于這個(gè)框架,我們能夠?qū)崿F(xiàn)下面幾件事情:

  • 實(shí)現(xiàn)基于blk-mq的塊設(shè)備驅(qū)動程序(具體實(shí)現(xiàn)可以參考空設(shè)備驅(qū)動--null_blk)

  • 實(shí)現(xiàn)基于blk-mq的IO調(diào)度器,例如提供關(guān)鍵IO的優(yōu)先處理能力、IO限流等(具體實(shí)現(xiàn)可以參考kyber-iosched.c)

  • 改進(jìn)或者擴(kuò)展blk-mq框架,來達(dá)到業(yè)務(wù)的需求(事實(shí)上,在blk-mq演進(jìn)的過程中,許多想法都來自底層塊設(shè)備驅(qū)動,特別是nvme驅(qū)動和scsi-mq驅(qū)動)

原文作者:內(nèi)核工匠



一文解析Multi-queue 架構(gòu)的評論 (共 條)

分享到微博請遵守國家法律
三亚市| 仁化县| 德钦县| 新乡县| 西和县| 两当县| 来凤县| 荣昌县| 宁强县| 法库县| 宜兴市| 来宾市| 山东省| 武山县| 鄂伦春自治旗| 远安县| 枝江市| 平度市| 股票| 西青区| 共和县| 吉林省| 深圳市| 丹巴县| 贡觉县| 镇远县| 时尚| 无极县| 四平市| 东乌珠穆沁旗| 淮阳县| 石台县| 湖北省| 蒲江县| 怀柔区| 常山县| 孟村| 武强县| 西贡区| 许昌市| 衡南县|