我正在研究 Linux IO 调度程序。Linux Deadline IO Scheduler 使用'front_merges' 属性来决定请求是前合并还是后合并。但我无法理解它是如何工作的,因为它只在一个地方设置了“front_merges”属性,并且它只设置为 1,如下所示。
dd->front_merges = 1;
我想知道 Deadline IO Scheduler 如何在其他地方设置“front_merges”。如果没有,截止日期前合并算法的场景是什么?
谢谢..
首先,Deadline 不使用 'front_merges' 属性来决定请求是前合并还是后合并,它只是关于 Deadline 是否可以进行前合并。如果设置为 0,Deadline 只允许反向合并。
截止前合并的场景是当一个生物进入块层时,它将调用电梯合并fn接口尝试合并到一个已经位于电梯队列中的请求中,如果设备的调度程序被指定为截止时间,那么电梯合并fn被实例化为deadline_merge ,见下文
static int
deadline_merge(struct request_queue *q, struct request **req, struct
bio *bio)
{
struct deadline_data *dd = q->elevator->elevator_data;
struct request *__rq;
int ret;
/*
* check for front merge
*/
if (dd->front_merges) {
sector_t sector = bio_end_sector(bio);
__rq = elv_rb_find(&dd->sort_list[bio_data_dir(bio)], sector);
if (__rq) {
BUG_ON(sector != blk_rq_pos(__rq));
if (elv_rq_merge_ok(__rq, bio)) {
ret = ELEVATOR_FRONT_MERGE;
goto out;
}
}
}
return ELEVATOR_NO_MERGE;
out:
*req = __rq;
return ret;
}
函数的调用栈可以是: submit_bio -> generic_make_request -> blk_queue_bio -> elv_merge -> lift_merge_fn(deadline_merge)。 因此,如果您启用了 front_merges,则 bio 有机会合并到请求的前面。
截止日期调度程序声明front_merges
为DD_ATTR:
static struct elv_fs_entry ort_deadline_attrs[] = {
DD_ATTR(read_expire),
DD_ATTR(write_expire),
DD_ATTR(writes_starved),
DD_ATTR(front_merges),
__ATTR_NULL
}
它使用STORE_FUNCTION
用户空间的宏来更改它。您可以在/sys/block/sda/queue/iosched等目录下找到它们:
$ ls /sys/block/sda/queue/iosched
=> fifo_batch front_merges read_expire write_expire writes_starved