[V4,3/6] blk-mq: move getting driver tag and budget into one helper
diff mbox series

Message ID 20200602091502.1822499-4-ming.lei@redhat.com
State New
Headers show
Series
  • blk-mq: support batching dispatch from scheduler
Related show

Commit Message

Ming Lei June 2, 2020, 9:14 a.m. UTC
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.

Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Baolin Wang <baolin.wang7@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@infradead.org>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Tested-by: Baolin Wang <baolin.wang7@gmail.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 block/blk-mq.c | 75 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 49 insertions(+), 26 deletions(-)

Comments

Damien Le Moal June 2, 2020, 9:32 a.m. UTC | #1
On 2020/06/02 18:15, Ming Lei wrote:
> 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.
> 
> Cc: Sagi Grimberg <sagi@grimberg.me>
> Cc: Baolin Wang <baolin.wang7@gmail.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
> Reviewed-by: Christoph Hellwig <hch@infradead.org>
> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> Tested-by: Baolin Wang <baolin.wang7@gmail.com>
> Signed-off-by: Ming Lei <ming.lei@redhat.com>
> ---
>  block/blk-mq.c | 75 +++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 49 insertions(+), 26 deletions(-)
> 
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 723bc39507fe..ee9342aac7be 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -1233,18 +1233,51 @@ 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 ask_budget)

"need_budget" may  be a better argument name instead of ask_budget. More
reflective of the fact that this is a boolean.

> +{
> +	struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
> +
> +	if (ask_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)) {
> +			/* budget is always obtained before getting tag */

This is clear since it was down a few lines above. Maybe drop this comment ?

> +			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))
> @@ -1262,31 +1295,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);
>  
> @@ -1339,6 +1350,18 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
>  	 */
>  	if (!list_empty(list)) {
>  		bool needs_restart;
> +		bool no_tag = false;
> +		bool no_budget_avail = false;
> +
> +		/*
> +		 * For non-shared tags, the RESTART check
> +		 * will suffice.
> +		 */
> +		if (prep == PREP_DISPATCH_NO_TAG &&
> +				(hctx->flags & BLK_MQ_F_TAG_SHARED))
> +			no_tag = true;

You could drop the variable declaration initialization and simply have:

		no_tag = prep == PREP_DISPATCH_NO_TAG &&
			(hctx->flags & BLK_MQ_F_TAG_SHARED)

> +		if (prep == PREP_DISPATCH_NO_BUDGET)
> +			no_budget_avail = true;

Same here:

		no_budget = prep == PREP_DISPATCH_NO_BUDGET;

Also to be symmetric with "no_tag", "no_budget" may be a better variable name ?

>  
>  		/*
>  		 * If we didn't flush the entire list, we could have told
>

Patch
diff mbox series

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 723bc39507fe..ee9342aac7be 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1233,18 +1233,51 @@  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 ask_budget)
+{
+	struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
+
+	if (ask_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)) {
+			/* budget is always obtained before getting tag */
+			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))
@@ -1262,31 +1295,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);
 
@@ -1339,6 +1350,18 @@  bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,
 	 */
 	if (!list_empty(list)) {
 		bool needs_restart;
+		bool no_tag = false;
+		bool no_budget_avail = false;
+
+		/*
+		 * For non-shared tags, the RESTART check
+		 * will suffice.
+		 */
+		if (prep == PREP_DISPATCH_NO_TAG &&
+				(hctx->flags & BLK_MQ_F_TAG_SHARED))
+			no_tag = true;
+		if (prep == PREP_DISPATCH_NO_BUDGET)
+			no_budget_avail = true;
 
 		/*
 		 * If we didn't flush the entire list, we could have told