From 26702d43cae64a0a71fd0ee0166125ac6e5478ae Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 27 Nov 2018 17:13:56 -0700 Subject: [PATCH 1485/2944] block: improve logic around when to sort a plug list fix #28871358 Only do it if we have requests for multiple queues in the same plug. Reviewed-by: Christoph Hellwig Signed-off-by: Jens Axboe Signed-off-by: Baolin Wang Reviewed-by: Joseph Qi --- block/blk-core.c | 1 + block/blk-mq.c | 20 +++++++++++++++++--- include/linux/blkdev.h | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 3349adf..28b6de8 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -3625,6 +3625,7 @@ void blk_start_plug(struct blk_plug *plug) INIT_LIST_HEAD(&plug->list); INIT_LIST_HEAD(&plug->mq_list); INIT_LIST_HEAD(&plug->cb_list); + plug->multiple_queues = false; /* * Store ordering should not be needed here, since a potential * preempt will imply a full memory barrier diff --git a/block/blk-mq.c b/block/blk-mq.c index fb20919..fae3f44 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1664,7 +1664,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule) list_splice_init(&plug->mq_list, &list); - list_sort(NULL, &list, plug_ctx_cmp); + if (plug->multiple_queues) + list_sort(NULL, &list, plug_ctx_cmp); this_q = NULL; this_ctx = NULL; @@ -1855,6 +1856,19 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, } } +static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq) +{ + list_add_tail(&rq->queuelist, &plug->mq_list); + if (!plug->multiple_queues && !list_is_singular(&plug->mq_list)) { + struct request *tmp; + + tmp = list_first_entry(&plug->mq_list, struct request, + queuelist); + if (tmp->q != rq->q) + plug->multiple_queues = true; + } +} + static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) { const int is_sync = op_is_sync(bio->bi_opf); @@ -1930,7 +1944,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) trace_block_plug(q); } - list_add_tail(&rq->queuelist, &plug->mq_list); + blk_add_rq_to_plug(plug, rq); } else if (plug && !blk_queue_nomerges(q)) { blk_mq_bio_to_request(rq, bio); @@ -1945,7 +1959,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) same_queue_rq = NULL; if (same_queue_rq) list_del_init(&same_queue_rq->queuelist); - list_add_tail(&rq->queuelist, &plug->mq_list); + blk_add_rq_to_plug(plug, rq); blk_mq_put_ctx(data.ctx); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 08776eb..34c0efd 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1348,6 +1348,7 @@ struct blk_plug { struct list_head list; /* requests */ struct list_head mq_list; /* blk-mq requests */ struct list_head cb_list; /* md requires an unplug callback */ + bool multiple_queues; }; #define BLK_MAX_REQUEST_COUNT 16 #define BLK_PLUG_FLUSH_SIZE (128 * 1024) -- 1.8.3.1