blk-mq: move getting driver tag and budget into one helper
authorMing Lei <ming.lei@redhat.com>
Tue, 30 Jun 2020 10:24:58 +0000 (18:24 +0800)
committerJens Axboe <axboe@kernel.dk>
Tue, 30 Jun 2020 13:51:48 +0000 (07:51 -0600)
Move code for getting driver tag and budget into one helper, so
blk_mq_dispatch_rq_list gets a bit simplified, and easier to read.

Meantime move updating of 'no_tag' and 'no_budget_available' into
the branch for handling partial dispatch because that is exactly
consumer of the two local variables.

Also rename the parameter of 'got_budget' as 'ask_budget'.

No functional change.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
Tested-by: Baolin Wang <baolin.wang7@gmail.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@infradead.org>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Baolin Wang <baolin.wang7@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-mq.c

index 492aeda..3e370f5 100644 (file)
@@ -1255,18 +1255,50 @@ static void blk_mq_handle_zone_resource(struct request *rq,
        __blk_mq_requeue_request(rq);
 }
 
+enum prep_dispatch {
+       PREP_DISPATCH_OK,
+       PREP_DISPATCH_NO_TAG,
+       PREP_DISPATCH_NO_BUDGET,
+};
+
+static enum prep_dispatch blk_mq_prep_dispatch_rq(struct request *rq,
+                                                 bool need_budget)
+{
+       struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
+
+       if (need_budget && !blk_mq_get_dispatch_budget(rq->q)) {
+               blk_mq_put_driver_tag(rq);
+               return PREP_DISPATCH_NO_BUDGET;
+       }
+
+       if (!blk_mq_get_driver_tag(rq)) {
+               /*
+                * The initial allocation attempt failed, so we need to
+                * rerun the hardware queue when a tag is freed. The
+                * waitqueue takes care of that. If the queue is run
+                * before we add this entry back on the dispatch list,
+                * we'll re-run it below.
+                */
+               if (!blk_mq_mark_tag_wait(hctx, rq)) {
+                       blk_mq_put_dispatch_budget(rq->q);
+                       return PREP_DISPATCH_NO_TAG;
+               }
+       }
+
+       return PREP_DISPATCH_OK;
+}
+
 /*
  * Returns true if we did some work AND can potentially do more.
  */
 bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
                             bool got_budget)
 {
+       enum prep_dispatch prep;
        struct request_queue *q = hctx->queue;
        struct request *rq, *nxt;
-       bool no_tag = false;
        int errors, queued;
        blk_status_t ret = BLK_STS_OK;
-       bool no_budget_avail = false;
        LIST_HEAD(zone_list);
 
        if (list_empty(list))
@@ -1284,31 +1316,9 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
                rq = list_first_entry(list, struct request, queuelist);
 
                WARN_ON_ONCE(hctx != rq->mq_hctx);
-               if (!got_budget && !blk_mq_get_dispatch_budget(q)) {
-                       blk_mq_put_driver_tag(rq);
-                       no_budget_avail = true;
+               prep = blk_mq_prep_dispatch_rq(rq, !got_budget);
+               if (prep != PREP_DISPATCH_OK)
                        break;
-               }
-
-               if (!blk_mq_get_driver_tag(rq)) {
-                       /*
-                        * The initial allocation attempt failed, so we need to
-                        * rerun the hardware queue when a tag is freed. The
-                        * waitqueue takes care of that. If the queue is run
-                        * before we add this entry back on the dispatch list,
-                        * we'll re-run it below.
-                        */
-                       if (!blk_mq_mark_tag_wait(hctx, rq)) {
-                               blk_mq_put_dispatch_budget(q);
-                               /*
-                                * For non-shared tags, the RESTART check
-                                * will suffice.
-                                */
-                               if (hctx->flags & BLK_MQ_F_TAG_SHARED)
-                                       no_tag = true;
-                               break;
-                       }
-               }
 
                list_del_init(&rq->queuelist);
 
@@ -1361,6 +1371,10 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
         */
        if (!list_empty(list)) {
                bool needs_restart;
+               /* For non-shared tags, the RESTART check will suffice */
+               bool no_tag = prep == PREP_DISPATCH_NO_TAG &&
+                        (hctx->flags & BLK_MQ_F_TAG_SHARED);
+               bool no_budget_avail = prep == PREP_DISPATCH_NO_BUDGET;
 
                /*
                 * If we didn't flush the entire list, we could have told