summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2018-10-30 11:31:51 -0600
committerJens Axboe <axboe@kernel.dk>2018-11-07 13:44:59 -0700
commit67cae4c948a5311121905a2a8740c50daf7f6478 (patch)
treee4d994179f16751b95f0080392844c6817a0e539 /block
parentea4f995ee8b8f0578b3319949f2edd5d812fdb0a (diff)
blk-mq: cleanup and improve list insertion
It's somewhat strange to have a list insertion function that relies on the fact that the caller has mapped things correctly. Pass in the hardware queue directly for insertion, which makes for a much cleaner interface and implementation. Reviewed-by: Keith Busch <keith.busch@intel.com> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/blk-mq-sched.c8
-rw-r--r--block/blk-mq-sched.h2
-rw-r--r--block/blk-mq.c25
3 files changed, 16 insertions, 19 deletions
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 641df3f00632..66fda19be5a3 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -395,17 +395,11 @@ run:
blk_mq_run_hw_queue(hctx, async);
}
-void blk_mq_sched_insert_requests(struct request_queue *q,
+void blk_mq_sched_insert_requests(struct blk_mq_hw_ctx *hctx,
struct blk_mq_ctx *ctx,
struct list_head *list, bool run_queue_async)
{
- struct blk_mq_hw_ctx *hctx;
struct elevator_queue *e;
- struct request *rq;
-
- /* For list inserts, requests better be on the same hw queue */
- rq = list_first_entry(list, struct request, queuelist);
- hctx = rq->mq_hctx;
e = hctx->queue->elevator;
if (e && e->type->ops.insert_requests)
diff --git a/block/blk-mq-sched.h b/block/blk-mq-sched.h
index 947f236b273d..7ff5671bf128 100644
--- a/block/blk-mq-sched.h
+++ b/block/blk-mq-sched.h
@@ -19,7 +19,7 @@ void blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx);
void blk_mq_sched_insert_request(struct request *rq, bool at_head,
bool run_queue, bool async);
-void blk_mq_sched_insert_requests(struct request_queue *q,
+void blk_mq_sched_insert_requests(struct blk_mq_hw_ctx *hctx,
struct blk_mq_ctx *ctx,
struct list_head *list, bool run_queue_async);
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 6b2859d3ad23..271726d48003 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1624,11 +1624,12 @@ static int plug_ctx_cmp(void *priv, struct list_head *a, struct list_head *b)
void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
{
+ struct blk_mq_hw_ctx *this_hctx;
struct blk_mq_ctx *this_ctx;
struct request_queue *this_q;
struct request *rq;
LIST_HEAD(list);
- LIST_HEAD(ctx_list);
+ LIST_HEAD(rq_list);
unsigned int depth;
list_splice_init(&plug->mq_list, &list);
@@ -1636,6 +1637,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
list_sort(NULL, &list, plug_ctx_cmp);
this_q = NULL;
+ this_hctx = NULL;
this_ctx = NULL;
depth = 0;
@@ -1643,30 +1645,31 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule)
rq = list_entry_rq(list.next);
list_del_init(&rq->queuelist);
BUG_ON(!rq->q);
- if (rq->mq_ctx != this_ctx) {
- if (this_ctx) {
+ if (rq->mq_hctx != this_hctx || rq->mq_ctx != this_ctx) {
+ if (this_hctx) {
trace_block_unplug(this_q, depth, !from_schedule);
- blk_mq_sched_insert_requests(this_q, this_ctx,
- &ctx_list,
+ blk_mq_sched_insert_requests(this_hctx, this_ctx,
+ &rq_list,
from_schedule);
}
- this_ctx = rq->mq_ctx;
this_q = rq->q;
+ this_ctx = rq->mq_ctx;
+ this_hctx = rq->mq_hctx;
depth = 0;
}
depth++;
- list_add_tail(&rq->queuelist, &ctx_list);
+ list_add_tail(&rq->queuelist, &rq_list);
}
/*
- * If 'this_ctx' is set, we know we have entries to complete
- * on 'ctx_list'. Do those.
+ * If 'this_hctx' is set, we know we have entries to complete
+ * on 'rq_list'. Do those.
*/
- if (this_ctx) {
+ if (this_hctx) {
trace_block_unplug(this_q, depth, !from_schedule);
- blk_mq_sched_insert_requests(this_q, this_ctx, &ctx_list,
+ blk_mq_sched_insert_requests(this_hctx, this_ctx, &rq_list,
from_schedule);
}
}