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.