- 論壇徽章:
- 0
|
回復(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表查找的是后合并的。 |
|