Commit 67cae4c9 authored by Jens Axboe's avatar Jens Axboe
Browse files

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: default avatarKeith Busch <keith.busch@intel.com>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent ea4f995e
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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);

+14 −11
Original line number Diff line number Diff line
@@ -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);
	}
}