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

Bean Huo
2021-11-23T12:20:12Z

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@acm.org>
> ---
> 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