aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2017-02-17 13:39:26 -0500
committerJens Axboe <axboe@fb.com>2017-02-17 14:35:47 -0500
commit64765a75ef258c802f795558d00a5a1864c531fc (patch)
treef748a608e3489cc582a3788fe7dc776c5722ec97
parent0c2a6fe4dc3e8c24bc67cd5d0a36092834027cf0 (diff)
blk-mq-sched: ask scheduler for work, if we failed dispatching leftovers
Usually we don't ask the scheduler for work, if we already have leftovers on the dispatch list. This is done to leave work on the scheduler side for as long as possible, for proper merging. But if we do have work leftover but didn't dispatch anything, then we should ask the scheduler since we could potentially issue requests from that. Signed-off-by: Jens Axboe <axboe@fb.com> Reviewed-by: Omar Sandoval <osandov@fb.com>
-rw-r--r--block/blk-mq-sched.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 4ee7cb043812..9e8d6795a8c1 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -175,6 +175,8 @@ void blk_mq_sched_put_request(struct request *rq)
175void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx) 175void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
176{ 176{
177 struct elevator_queue *e = hctx->queue->elevator; 177 struct elevator_queue *e = hctx->queue->elevator;
178 const bool has_sched_dispatch = e && e->type->ops.mq.dispatch_request;
179 bool did_work = false;
178 LIST_HEAD(rq_list); 180 LIST_HEAD(rq_list);
179 181
180 if (unlikely(blk_mq_hctx_stopped(hctx))) 182 if (unlikely(blk_mq_hctx_stopped(hctx)))
@@ -204,11 +206,18 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx)
204 */ 206 */
205 if (!list_empty(&rq_list)) { 207 if (!list_empty(&rq_list)) {
206 blk_mq_sched_mark_restart(hctx); 208 blk_mq_sched_mark_restart(hctx);
207 blk_mq_dispatch_rq_list(hctx, &rq_list); 209 did_work = blk_mq_dispatch_rq_list(hctx, &rq_list);
208 } else if (!e || !e->type->ops.mq.dispatch_request) { 210 } else if (!has_sched_dispatch) {
209 blk_mq_flush_busy_ctxs(hctx, &rq_list); 211 blk_mq_flush_busy_ctxs(hctx, &rq_list);
210 blk_mq_dispatch_rq_list(hctx, &rq_list); 212 blk_mq_dispatch_rq_list(hctx, &rq_list);
211 } else { 213 }
214
215 /*
216 * We want to dispatch from the scheduler if we had no work left
217 * on the dispatch list, OR if we did have work but weren't able
218 * to make progress.
219 */
220 if (!did_work && has_sched_dispatch) {
212 do { 221 do {
213 struct request *rq; 222 struct request *rq;
214 223