Commit 5e3d02bb authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe

blk-mq-sched: dispatch from scheduler IFF progress is made in ->dispatch

When the hw queue is busy, we shouldn't take requests from the scheduler
queue any more, otherwise it is difficult to do IO merge.

This patch fixes the awful IO performance on some SCSI devices(lpfc,
qla2xxx, ...) when mq-deadline/kyber is used by not taking requests if
hw queue is busy.
Reviewed-by: default avatarOmar Sandoval <osandov@fb.com>
Reviewed-by: default avatarBart Van Assche <bart.vanassche@wdc.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 0e7d3a8d
...@@ -94,7 +94,7 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx) ...@@ -94,7 +94,7 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
struct request_queue *q = hctx->queue; struct request_queue *q = hctx->queue;
struct elevator_queue *e = q->elevator; struct elevator_queue *e = q->elevator;
const bool has_sched_dispatch = e && e->type->ops.mq.dispatch_request; const bool has_sched_dispatch = e && e->type->ops.mq.dispatch_request;
bool did_work = false; bool do_sched_dispatch = true;
LIST_HEAD(rq_list); LIST_HEAD(rq_list);
/* RCU or SRCU read lock is needed before checking quiesced flag */ /* RCU or SRCU read lock is needed before checking quiesced flag */
...@@ -125,18 +125,18 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx) ...@@ -125,18 +125,18 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
*/ */
if (!list_empty(&rq_list)) { if (!list_empty(&rq_list)) {
blk_mq_sched_mark_restart_hctx(hctx); blk_mq_sched_mark_restart_hctx(hctx);
did_work = blk_mq_dispatch_rq_list(q, &rq_list); do_sched_dispatch = blk_mq_dispatch_rq_list(q, &rq_list);
} else if (!has_sched_dispatch) { } else if (!has_sched_dispatch) {
blk_mq_flush_busy_ctxs(hctx, &rq_list); blk_mq_flush_busy_ctxs(hctx, &rq_list);
blk_mq_dispatch_rq_list(q, &rq_list); blk_mq_dispatch_rq_list(q, &rq_list);
} }
/* /*
* We want to dispatch from the scheduler if we had no work left * We want to dispatch from the scheduler if there was nothing
* on the dispatch list, OR if we did have work but weren't able * on the dispatch list or we were able to dispatch from the
* to make progress. * dispatch list.
*/ */
if (!did_work && has_sched_dispatch) { if (do_sched_dispatch && has_sched_dispatch) {
do { do {
struct request *rq; struct request *rq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment