- 论坛徽章:
- 0
|
回复 5# tacoe
3.deadline IO调度算法:
模块注册:elv_register,即只是把elevator_type结构add到全局链表elv_list中,以
便后期调用可以被找到。
块设备如何找到调度算法:块设备在初始化队列的时候,[blk_init_queue_node] 调
用了elevator_init. 每个队列里都有一个struct elevator_queue,这个结构里有个
重要的结构hash表,用来存放request的。
块设备的队列与具体的调度算法联系起来:elevator_attach,因为每个设备都都有一
个独立的queue,所以每个独立的设备可以对应一个独立的调度算法。
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按序把相应的request加入到相应的读或者写rbtree中。如果rbtree已经
有键值一样的节点,如何处理?从rbtree及fifo中删除再dispatch到队列中去。为什
新的request没有加到rbtree中了呢???,新的request只放到fifo中而没有放到
rbtree中。是认为再也没有合并的必要了吗?
hash表中存放的是有可能merge的request,如果rq_mergeable()为假即从hash表中删除
可以从hash表中查找可以后merge的request.前merge即从rbtree 中找,看
deadline_merge.
elv_merged_request:已经合并后所作的处理,如果是前merge即重新计算rbtree,以
request的[__secto]r为键值,即开始位置为键值。如果是后merge即重新调整hash表中
的位置。以开始位置+它的大小[即块的终点]为键值.
所以rbtree中查找的是前合并的,而hash表查找的是后合并的。 |
|