Re: [PATCH V4 3/6] blk-mq: move getting driver tag and budget into one helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxx>
> Cc: Baolin Wang <baolin.wang7@xxxxxxxxx>
> Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx>
> Reviewed-by: Sagi Grimberg <sagi@xxxxxxxxxxx>
> Reviewed-by: Christoph Hellwig <hch@xxxxxxxxxxxxx>
> Reviewed-by: Johannes Thumshirn <johannes.thumshirn@xxxxxxx>
> Tested-by: Baolin Wang <baolin.wang7@xxxxxxxxx>
> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx>
> ---
>  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
> 


-- 
Damien Le Moal
Western Digital Research




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux