日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IO的生命周期

發布時間:2025/7/14 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IO的生命周期 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

●?將來自cache的數據封裝成bio

submit_bh->submit_bh_wbc

此時IO還在fs層

●?進入block IO層

submit_bh_wbc->submit_io-> generic_make_request

上面獲得的q是每個設備(block_device)的隊列。block_device有一個成員queue,所有針對該設備的請求都會放入其中,該queue不是后面將要說到的三類queue。

make_queue_fn的注冊在request queue初始化的時候:blk_init_queue->blk_init_allocated_queue

●?開始將bio合并到request:

generic_make_request->blk_queue_bio

blk_queue_bio實現了對bio的合并調度。它調用的函數elv_merge是關鍵函數,它尋找可以用來合并bio的request。

IO從塊設備層(block IO layer),到發送到塊設備驅動(device driver)整個過程經過三類隊列:

?????? 1)unplug request queue 屬于線程

?????? 2)elevator queue 調度隊列,不同的調度器,隊列不同

?????? 3)device request queue 派遣隊列,dispatch queue。(例如,在deadline_dispatch_requests中實現)

?

plug和unplug:目的是讓請求馬上被驅動程序處理。設備處于pluged狀態,設備不會被激活。處于unplugged狀態,被激活。

?

來自上層的請求,先嘗試合并入unplug 隊列,若不能合并,則調用elv_merge合并入調度隊列elevator queue。若找不到可合并的請求,則獲得一個空請求request,用該bio初始化該request,然后放到unplug隊列中。

此時bio(request)還在unplug 隊列中。

此時bio(request)在調度隊列中。

●?(若不能放入unplug隊列)調用elv_merge,找到可以合并bio的request。

blk_queue_bio->elv_merge

elv_merge的作用主要是,找到可以將bio合并的request。

這一步,是調用特定的調度器找到可以合并bio的request

?

●?將unplug 隊列中的request放到調度隊列

blk_queue_bio:

通過blk_flush_plug_list(也可通過_elv_add_request)將unplug 請求隊列中的請求發送到調度隊列elevator queue。

add_acct_request->__elv_add_request

此時request在調度隊列中。

●?將調度隊列里的request發送到派遣隊列:

返回blk_queue_bio,然后blk_queue_bio-> add_acct_request-> __elv_add_request

?

此時,request在device request queue(派遣隊列)中。

這一步實現具體IO調度器對請求的派遣(發送到派遣隊列):

__elv_add_request->elv_drain_elevator->elevator_dispatch_fn

elevator_dispatch_fn將被注冊為具體調度器的派遣函數,例如deadline_dispatch_request

IO調度器的工作:合并,排序。

排序:使請求按扇區增長的方向有序排列。

CFQ:每個發起IO的進程都有一個隊列。

Deadline:有4個隊列,分為兩類sort_list和fifo_list。每類都有讀寫兩種隊列。

?????? sort_list 按請求起始扇區排序,fifo_list按請求生成的時間排序。

?

此時,請求在派遣隊列(device request queue)中。

●?進入驅動程序,并獲得一個request:

返回blk_queue_bio: blk_queue_bio-> __blk_run_queue-> __blk_run_queue_uncond->request_fn(scsi_request_fn)-> blk_peek_request->__elv_next_request

request_fn被注冊為scsi_request_fn,該函數是驅動程序的入口。

?

從device request queue中獲得一個請求,準備發送到scsi塊設備驅動(中間層)

●?將request轉化成scsi command:

在blk_peek_request中調用q->prep_rq_fn(注冊為scsi_prep_fn),將request轉化成scsi驅動能夠識別scsi command。

●?發送scsi command到scsi host:

回到scsi_request_fn,調用scsi_dispatch_cmd將scsi command發送給scsi host

●?DMA:

在scsi_dispatch_cmd中,調用queuecommand方法,將scsi command掛在自己的隊列中,然后啟動DMA,將scsi command發送到具體的磁盤。DMA完畢后,DMA控制器中斷CPU,告訴CPU DMA結束。并且在中斷上下文中,設置DMA結束的中斷下半部。DMA中斷處理程序返回之后,觸發軟中斷,執行scsi中斷下部。

驅動:scsi中間層(middle level driver) + ?scsi host driver。

scsi中間層抽象了scsi總線邏輯;scsi host driver控制scsi總線控制器,實現scsi數據的物理層傳輸。

queuecommand是這兩層之間的橋梁。它將被注冊為具體的物理塊設備的函數,例如megaraid_queue。

●?執行中斷下半部分,并返回:

在scsi中斷下部,調用scsi command結束的回調函數scsi_done:scsi_dispatch_cmd->scsi_done。scsi_done調用blk_complete_request結束請求。

?

轉載于:https://www.cnblogs.com/volcanorao/p/5977618.html

總結

以上是生活随笔為你收集整理的IO的生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。