block: prevent merging of requests with different priorities
authorDamien Le Moal <damien.lemoal@wdc.com>
Tue, 20 Nov 2018 01:52:37 +0000 (10:52 +0900)
committerJens Axboe <axboe@kernel.dk>
Tue, 20 Nov 2018 02:03:49 +0000 (19:03 -0700)
Growing in size a high priority request by merging it with a lower
priority BIO or request will increase the request execution time. This
is the opposite result of the desired effect of high I/O priorities,
namely getting low I/O latencies. Prevent merging of requests and BIOs
that have different I/O priorities to fix this.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-core.c
block/blk-merge.c

index 4450d3c08f255170c432a176c3f4ae05e0fbe234..dde30b08aa1418bd5858ff05f234ded0709efa41 100644 (file)
@@ -662,7 +662,6 @@ bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
        req->biotail->bi_next = bio;
        req->biotail = bio;
        req->__data_len += bio->bi_iter.bi_size;
-       req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
        blk_account_io_start(req, false);
        return true;
@@ -686,7 +685,6 @@ bool bio_attempt_front_merge(struct request_queue *q, struct request *req,
 
        req->__sector = bio->bi_iter.bi_sector;
        req->__data_len += bio->bi_iter.bi_size;
-       req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
        blk_account_io_start(req, false);
        return true;
@@ -706,7 +704,6 @@ bool bio_attempt_discard_merge(struct request_queue *q, struct request *req,
        req->biotail->bi_next = bio;
        req->biotail = bio;
        req->__data_len += bio->bi_iter.bi_size;
-       req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
        req->nr_phys_segments = segments + 1;
 
        blk_account_io_start(req, false);
index b1df622cbd85c378bc0957223e8309928b3b8dbc..6be04ef8da5b758d051c74f3698ab6f7e9ff6d14 100644 (file)
@@ -752,6 +752,9 @@ static struct request *attempt_merge(struct request_queue *q,
        if (req->write_hint != next->write_hint)
                return NULL;
 
+       if (req->ioprio != next->ioprio)
+               return NULL;
+
        /*
         * If we are allowed to merge, then append bio list
         * from next to rq and release next. merge_requests_fn
@@ -807,8 +810,6 @@ static struct request *attempt_merge(struct request_queue *q,
         */
        blk_account_io_merge(next);
 
-       req->ioprio = ioprio_best(req->ioprio, next->ioprio);
-
        /*
         * ownership of bio passed from next to req, return 'next' for
         * the caller to free
@@ -883,6 +884,9 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
        if (rq->write_hint != bio->bi_write_hint)
                return false;
 
+       if (rq->ioprio != bio_prio(bio))
+               return false;
+
        return true;
 }