0

I'm working on a research on Linux IO Schedulers. Linux Deadline IO Scheduler uses 'front_merges' property to decide the request is front or back merge. But I couldn't understand how can it work because of it sets 'front_merges' property just in one place and it is only set to 1 as follows.

dd->front_merges = 1;

I want to know how can Deadline IO Scheduler sets the 'front_merges' somewhere else. If it doesn't, what is the scenario of deadline front merge algorithm?

Thanks..

ABDULLAH
  • 21
  • 3

2 Answers2

0

The deadline scheduler declares front_merges as a 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
}

And it uses STORE_FUNCTION macro for userspace to change it. You can find them under directory such as /sys/block/sda/queue/iosched:

  $ ls /sys/block/sda/queue/iosched
  => fifo_batch  front_merges  read_expire  write_expire  writes_starved
D.Fux
  • 356
  • 2
  • 11
0

Firstly, Deadline doesn't use 'front_merges' property to decide the request is front or back merge, it's only about whether Deadline could do front merge. if it was set to 0, Deadline only allowed back merge.

The scenario of deadline front merge is that when a bio gets into block layer it will call elevator_merge_fn interface to try to get merged into a request which has already lied in elevator queue, the elevator_merge_fn was instanced to deadline_merge if the device's scheduler was specified to Deadline, seeing bellow

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;
}

The call stack of function could be: submit_bio -> generic_make_request -> blk_queue_bio -> elv_merge -> elevator_merge_fn(deadline_merge). So if you have enabled front_merges, the bio has the chance to merge to the front of a request.