summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/blk-mq-sched.c12
-rw-r--r--block/blk-mq.c2
-rw-r--r--block/blk-mq.h2
3 files changed, 14 insertions, 2 deletions
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 045b6878b8c5..a9182d2f8ad3 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -168,9 +168,19 @@ static int __blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx)
* in blk_mq_dispatch_rq_list().
*/
list_add_tail(&rq->queuelist, &rq_list);
+ count++;
if (rq->mq_hctx != hctx)
multi_hctxs = true;
- } while (++count < max_dispatch);
+
+ /*
+ * If we cannot get tag for the request, stop dequeueing
+ * requests from the IO scheduler. We are unlikely to be able
+ * to submit them anyway and it creates false impression for
+ * scheduling heuristics that the device can take more IO.
+ */
+ if (!blk_mq_get_driver_tag(rq))
+ break;
+ } while (count < max_dispatch);
if (!count) {
if (run_queue)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index f11d4018ce2e..4261adee9964 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1104,7 +1104,7 @@ static bool __blk_mq_get_driver_tag(struct request *rq)
return true;
}
-static bool blk_mq_get_driver_tag(struct request *rq)
+bool blk_mq_get_driver_tag(struct request *rq)
{
struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 556368d2c5b6..4b1ca7b7bbeb 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -260,6 +260,8 @@ static inline void blk_mq_put_driver_tag(struct request *rq)
__blk_mq_put_driver_tag(rq->mq_hctx, rq);
}
+bool blk_mq_get_driver_tag(struct request *rq);
+
static inline void blk_mq_clear_mq_map(struct blk_mq_queue_map *qmap)
{
int cpu;