亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 6068 | 回復(fù): 6
打印 上一主題 下一主題

塊設(shè)備的IO流程 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-08-09 11:06 |只看該作者 |倒序?yàn)g覽
1.正常的IO流程:
文件系統(tǒng)層的submit_bio :把相應(yīng)的讀寫標(biāo)志加到bio結(jié)構(gòu)中。
generic_make_request
檢查bio的合法性,每個bio里都有一個塊設(shè)備結(jié)構(gòu)bi_bdev,每個塊設(shè)備結(jié)構(gòu)都有個隊(duì)列
指針。如果bio指向的是相對分區(qū)的地址,即要轉(zhuǎn)換成整個硬盤的相對地址:
blk_partition_remap, 這之后到了q->make_request_fn.這個函數(shù)指針在創(chuàng)建初始化
queue的時候初始化成了:__make_request.為做不了DMA的page做彈性緩沖區(qū):
blk_queue_bounce,如果此bio為barrier,即為此bio單獨(dú)創(chuàng)建一個request.不合并不代
立刻下盤。如果不是,即調(diào)用電梯算法嘗試合并多個bio.
get_request_wait:獲取一個空的request;
init_request_from_bio:利用bio來初始化一個request.
如果已經(jīng)設(shè)置sync:__generic_unplug_device->blk_remove_plug->q->request_fn;

論壇徽章:
0
2 [報告]
發(fā)表于 2011-08-09 11:07 |只看該作者
回復(fù) 1# tacoe


    2. 電梯合并:elv_merge
如果之前已經(jīng)有合并,即last_merge不為NULL時,只要簡單計算sector就可以知道是否
可以前合并或者后合并。當(dāng)然還要比較相應(yīng)的標(biāo)志位。
每個不能合并的bio都會先組裝成一個rquest放到電梯中的hash[這里特指是deadline]
表中:add_request
如果last_merge為NULL即表示queue沒有合并的request,合并的物理段不能超過最大
段數(shù):q->max_phys_segments.如果超過即last_merge要重裝配置為NULL. 在
elv_insert的時候如果認(rèn)為該request是可merge的且last_merge是NULL時,該值指
向該request.
hash表的是以rq->sector+rq->nr_sectors 為key值為保存hash的,所以以bio的開始
扇區(qū)能在hash表中能找到相應(yīng)的request即表示此bio可以后合并的,前合并也是類似
的道理,當(dāng)然還要檢查相應(yīng)的標(biāo)志位,像讀寫要相同等。

論壇徽章:
0
3 [報告]
發(fā)表于 2011-08-09 11:07 |只看該作者
回復(fù) 2# tacoe


    scsi_request_fn
這個函數(shù)是在 scsi_alloc_queue 的時候初始化的,每一個scsi device設(shè)備都有一個
queue隊(duì)列,在創(chuàng)建scsi_alloc_sdev的時候創(chuàng)建此隊(duì)列,最開始創(chuàng)建scsi設(shè)備的函數(shù)
數(shù)是從驅(qū)動里開始的(mptsas_scan_sas_topology)里的scsi_add_device。
這個函數(shù)即[q->request_fn(q)],可能在電梯調(diào)度算法中被調(diào)用,也可能在文件
ll_rw_blk.c 中被調(diào)用:__generic_unplug_device/blk_start_queue/blk_run_queue
/blk_insert_request.
io下盤的兩條路徑:
(1)
submit_bio->generic_make_request->__make_request->elv_insert->
__blk_run_queue->scsi_request_fn
(2)線程路徑:
kthread->journald->journal_commit_transaction->out_of_line_wait_on_bit->
__wait_on_bit->sync_buffer->gerneric_unplug_device->scsi_request_fn
3毫秒定時器unplug:blk_unplug_timeout
在blk_plug_device函數(shù)中設(shè)置QUEUE_FLAG_PLUGGED標(biāo)志時加入定時器,3毫秒如果還
沒有unplug的話,定時器函數(shù)會調(diào)用下IO。blk_unplug_work

scsi_dispatch_cmd
主要是在command下發(fā)到驅(qū)動的時候做的一些預(yù)處理。

queuecommand
這個實(shí)際是在驅(qū)動里執(zhí)行了,每個IOC HAB 的處理都不同。這個函數(shù)里傳入了一個重
要的函數(shù)指針scsi_done.把該函數(shù)指針放到scsi_cmnd結(jié)構(gòu)中,最后會在中斷中調(diào)用
這個函數(shù)。

scsi_done
該函數(shù)的功能是觸發(fā)軟件中斷。異步通知此IO已經(jīng)完成。

論壇徽章:
0
4 [報告]
發(fā)表于 2011-08-09 11:08 |只看該作者
回復(fù) 3# tacoe


    blk_done_softirq
這個是軟件中斷處理函數(shù),它從隊(duì)列中取出已經(jīng)完成的request,再調(diào)用相應(yīng)queue中的
softirq_done_fn, 每個request中都有一個queue結(jié)構(gòu)。
同樣這個函數(shù)指針也是在創(chuàng)建queue的時候初始化到queue結(jié)構(gòu)中的。
通用的為:scsi_softirq_done,它主要處理的是命令的完成情況。
根據(jù)相應(yīng)的標(biāo)志,做出三種反應(yīng)a.正常完成。b.需要重新入隊(duì)。c.不能正常完成,
request 中止。

正;蛘叱鲥e的scsi_finish_command: 最終會調(diào)用scsi_cmnd 中的done,注意這里的
done與scsi_done的區(qū)別。
非讀寫的done:
[./drivers/scsi/scsi_lib.c:1170: cmd->done = scsi_blk_pc_done;]
讀寫的done:
sd_rw_intr 具體的塊設(shè)備不相同, 這個函數(shù)在sd_init_command函數(shù)里初始化。
這是scsi_driver結(jié)構(gòu)體中的函數(shù)。
最后會回到scsi中層函數(shù):scsi_io_completion,在這個函數(shù)里可能會根據(jù)sensekey
再做相應(yīng)的處理,或者重新入隊(duì)。

論壇徽章:
0
5 [報告]
發(fā)表于 2011-08-09 11:08 |只看該作者
回復(fù) 4# tacoe


    2.電梯算法結(jié)構(gòu)[struct elevator_type]中各個函數(shù)的功能:
.elevator_merge_fn:判斷bio是否可以合并,是前合并還是后合并。
.elevator_merged_fn:合并后的后續(xù)處理。
.elevator_merge_req_fn:合并request時,算法對兩個request所做的處理.
.elevator_dispatch_fn:找到最適合的request放到q->head后面。
.elevator_add_req_fn:算法把request加到具體自己的結(jié)構(gòu)隊(duì)列中
.elevator_queue_empty_fn:查看算法隊(duì)列中是否還有request
.elevator_former_req_fn:前merge時所要取的request.
.elevator_latter_req_fn:后merge時所要取的request.
.elevator_set_req_fn:
.elevator_put_req_fn:
.elevator_init_fn:塊設(shè)備調(diào)用,初始化與算法相關(guān)的具體數(shù)據(jù)結(jié)構(gòu),或者與queue
相關(guān)。
.elevator_exit_fn,上面函數(shù)的反操作。

論壇徽章:
0
6 [報告]
發(fā)表于 2011-08-09 11:09 |只看該作者
回復(fù) 5# tacoe


    3.deadline IO調(diào)度算法:
模塊注冊:elv_register,即只是把elevator_type結(jié)構(gòu)add到全局鏈表elv_list中,以
便后期調(diào)用可以被找到。
塊設(shè)備如何找到調(diào)度算法:塊設(shè)備在初始化隊(duì)列的時候,[blk_init_queue_node] 調(diào)
用了elevator_init. 每個隊(duì)列里都有一個struct elevator_queue,這個結(jié)構(gòu)里有個
重要的結(jié)構(gòu)hash表,用來存放request的。
塊設(shè)備的隊(duì)列與具體的調(diào)度算法聯(lián)系起來:elevator_attach,因?yàn)槊總設(shè)備都都有一
個獨(dú)立的queue,所以每個獨(dú)立的設(shè)備可以對應(yīng)一個獨(dú)立的調(diào)度算法。
26 struct deadline_data {
27     /*
28      * run time data
29      */
30
31     /*
32      * requests (deadline_rq s) are present on both sort_list and fifo_list
33      */
34     struct rb_root sort_list[2]; 讀寫紅黑樹,作用:
35     struct list_head fifo_list[2]; 讀寫fifo,作用:
36
37     /*
38      * next in sort order. read, write or both are NULL
39      */
40     struct request *next_rq[2]; 什么時候填充?
41     unsigned int batching;      /* number of sequential requests made */
42     sector_t last_sector;       /* head position */
43     unsigned int starved;       /* times reads have starved writes */
44
45     /*
46      * settings that change how the i/o scheduler behaves
47      */
48     int fifo_expire[2];
49     int fifo_batch;
50     int writes_starved;
51     int front_merges;
52 };
add_request按序把相應(yīng)的request加入到相應(yīng)的讀或者寫rbtree中。如果rbtree已經(jīng)
有鍵值一樣的節(jié)點(diǎn),如何處理?從rbtree及fifo中刪除再dispatch到隊(duì)列中去。為什
新的request沒有加到rbtree中了呢???,新的request只放到fifo中而沒有放到
rbtree中。是認(rèn)為再也沒有合并的必要了嗎?
hash表中存放的是有可能merge的request,如果rq_mergeable()為假即從hash表中刪除
可以從hash表中查找可以后merge的request.前merge即從rbtree 中找,看
deadline_merge.

elv_merged_request:已經(jīng)合并后所作的處理,如果是前merge即重新計算rbtree,以
request的[__secto]r為鍵值,即開始位置為鍵值。如果是后merge即重新調(diào)整hash表中
的位置。以開始位置+它的大小[即塊的終點(diǎn)]為鍵值.
所以rbtree中查找的是前合并的,而hash表查找的是后合并的。

論壇徽章:
0
7 [報告]
發(fā)表于 2011-08-09 11:10 |只看該作者
本帖最后由 tacoe 于 2011-08-09 11:17 編輯

回復(fù) 6# tacoe


    4.cfq IO調(diào)度算法
.elevator_merge_fn:
每個線程都有一個struct cfq_queue結(jié)構(gòu)。
每個線程結(jié)構(gòu)struct task_struct 中都保存有一個struct io_context成員。
struct cfq_io_context 中有兩個struct cfq_queue隊(duì)列,分別是同步和異步。
從io_context結(jié)構(gòu)可以找到cfq_io_context結(jié)構(gòu),再根據(jù)bio的類型可以找到
cfq_queue結(jié)構(gòu)。同樣cfq_queue中有紅黑樹鏈表。根據(jù)bio的sector計算是否可以前
merge.

--------------
在看代碼中的一些筆記,還有很多沒看,歡迎指教。。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP