Планировщик ввода-вывода крайнего срока сценарий front_merges
Я работаю над исследованием Linux IO Schedulers. Linux Deadline IO Scheduler использует свойство 'front_merges', чтобы решить, является ли запрос фронтальным или обратным слиянием. Но я не мог понять, как он может работать, потому что он устанавливает свойство 'front_merges' только в одном месте, а оно устанавливается в 1 следующим образом.
dd->front_merges = 1;
Я хочу знать, как Deadline IO Scheduler может установить 'front_merges' где-нибудь еще. Если это не так, каков сценарий алгоритма слияния фронта крайнего срока?
Спасибо..
2 ответа
Планировщик крайнего срока объявляет 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
Во-первых, Deadline не использует свойство 'front_merges', чтобы определить, является ли запрос фронтальным или обратным слиянием, это только вопрос, может ли Deadline выполнить фронтальное слияние. если было установлено значение 0, крайний срок допускал только обратное слияние.
Сценарий слияния фронта крайнего срока состоит в том, что, когда био попадает в слой блока, он вызывает интерфейс elevator_merge_fn, чтобы попытаться объединиться с запросом, который уже находится в очереди лифта, а elevator_merge_fn был преобразован в deadline_merge, если планировщик устройства был задан как Deadline видя ниже
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 -> elevator_merge_fn (deadline_merge). Так что, если вы включили front_merges, у биографии есть шанс слиться с фронтом запроса.