Re: [PATCH v2 11/20] scsi: ufs: Switch to scsi_(get|put)_internal_cmd()

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

 



On Fri, 2021-11-19 at 11:57 -0800, Bart Van Assche wrote:
> The only functional change in this patch is the addition of a
> blk_mq_start_request() call in ufshcd_issue_devman_upiu_cmd().
> 
> Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx>
> ---
>  drivers/scsi/ufs/ufshcd.c | 46 +++++++++++++++++++++++++----------
> ----
>  1 file changed, 30 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index fced4528ee90..dfa5f127342b 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -2933,6 +2933,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba
> *hba,
>  {
>  	struct request_queue *q = hba->cmd_queue;
>  	DECLARE_COMPLETION_ONSTACK(wait);
> +	struct scsi_cmnd *scmd;
>  	struct request *req;
>  	struct ufshcd_lrb *lrbp;
>  	int err;
> @@ -2945,15 +2946,18 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba
> *hba,
>  	 * Even though we use wait_event() which sleeps indefinitely,
>  	 * the maximum wait time is bounded by SCSI request timeout.
>  	 */
> -	req = blk_mq_alloc_request(q, REQ_OP_DRV_OUT, 0);
> -	if (IS_ERR(req)) {
> -		err = PTR_ERR(req);
> +	scmd = scsi_get_internal_cmd(q, DMA_TO_DEVICE, 0);
> +	if (IS_ERR(scmd)) {
> +		err = PTR_ERR(scmd);
>  		goto out_unlock;
>  	}
> +	req = scsi_cmd_to_rq(scmd);
>  	tag = req->tag;
>  	WARN_ONCE(tag < 0, "Invalid tag %d\n", tag);
> -	/* Set the timeout such that the SCSI error handler is not
> activated. */
> -	req->timeout = msecs_to_jiffies(2 * timeout);
> +	/*
> +	 * Start the request such that blk_mq_tag_idle() is called when
> the
> +	 * device management request finishes.
> +	 */
>  	blk_mq_start_request(req);
>  
>  	lrbp = &hba->lrb[tag];
> @@ -2972,7 +2976,8 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba
> *hba,
>  				    (struct utp_upiu_req *)lrbp-
> >ucd_rsp_ptr);
>  
>  out:
> -	blk_mq_free_request(req);
> +	scsi_put_internal_cmd(scmd);
> +
>  out_unlock:
>  	up_read(&hba->clk_scaling_lock);
>  	return err;
> @@ -6573,17 +6578,16 @@ static int __ufshcd_issue_tm_cmd(struct
> ufs_hba *hba,
>  	struct request_queue *q = hba->tmf_queue;
>  	struct Scsi_Host *host = hba->host;
>  	DECLARE_COMPLETION_ONSTACK(wait);
> +	struct scsi_cmnd *scmd;
>  	struct request *req;
>  	unsigned long flags;
>  	int task_tag, err;
>  
> -	/*
> -	 * blk_mq_alloc_request() is used here only to get a free tag.
> -	 */
> -	req = blk_mq_alloc_request(q, REQ_OP_DRV_OUT, 0);
> -	if (IS_ERR(req))
> -		return PTR_ERR(req);
> +	scmd = scsi_get_internal_cmd(q, DMA_TO_DEVICE, 0);
> +	if (IS_ERR(scmd))
> +		return PTR_ERR(scmd);
>  
> +	req = scsi_cmd_to_rq(scmd);
>  	req->end_io_data = &wait;
>  	ufshcd_hold(hba, false);
>  
> @@ -6636,7 +6640,8 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba
> *hba,
>  	spin_unlock_irqrestore(hba->host->host_lock, flags);
>  
>  	ufshcd_release(hba);
> -	blk_mq_free_request(req);
> +
> +	scsi_put_internal_cmd(scmd);
>  
>  	return err;
>  }
> @@ -6714,6 +6719,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct
> ufs_hba *hba,
>  {
>  	struct request_queue *q = hba->cmd_queue;
>  	DECLARE_COMPLETION_ONSTACK(wait);
> +	struct scsi_cmnd *scmd;
>  	struct request *req;
>  	struct ufshcd_lrb *lrbp;
>  	int err = 0;
> @@ -6722,13 +6728,19 @@ static int
> ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
>  
>  	down_read(&hba->clk_scaling_lock);
>  
> -	req = blk_mq_alloc_request(q, REQ_OP_DRV_OUT, 0);
> -	if (IS_ERR(req)) {
> -		err = PTR_ERR(req);
> +	scmd = scsi_get_internal_cmd(q, DMA_TO_DEVICE, 0);
> +	if (IS_ERR(scmd)) {
> +		err = PTR_ERR(scmd);
>  		goto out_unlock;
>  	}
> +	req = scsi_cmd_to_rq(scmd);
>  	tag = req->tag;
>  	WARN_ONCE(tag < 0, "Invalid tag %d\n", tag);
> +	/*
> +	 * Start the request such that blk_mq_tag_idle() is called when
> the
> +	 * device management request finishes.
> +	 */
> +	blk_mq_start_request(req);

Bart,

Calling blk_mq_start_request() will inject the trace print of the block
issued, but we do not have its paired completion trace print.
In addition, blk_mq_tag_idle() will not be called after the device
management request is completed, it will be called after the timer
expires.

I remember that we used to not allow this kind of LLD internal commands
to be attached to the block layer. I now find that to be correct way. 

Bean




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux