All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
@ 2018-02-28  8:55 Jianchao Wang
  2018-02-28 17:52 ` Bart Van Assche
  2018-03-02  1:44 ` Martin K. Petersen
  0 siblings, 2 replies; 10+ messages in thread
From: Jianchao Wang @ 2018-02-28  8:55 UTC (permalink / raw)
  To: jejb, martin.petersen
  Cc: Bart.VanAssche, linux-scsi, linux-kernel, Christoph Hellwig

In scsi core, __scsi_queue_insert should just put request back on
the queue and retry using the same command as before. However, for
blk-mq, scsi_mq_requeue_cmd is employed here which will unprepare
the request. To align with the semantics of __scsi_queue_insert,
use blk_mq_requeue_request with kick_requeue_list == true and put
the reference of scsi_device.

V1 -> V2:
 - add put_device on scsi_device->sdev_gendev

Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jianchao Wang <jianchao.w.wang@oracle.com>
---
 drivers/scsi/scsi_lib.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index a86df9c..6fa7b0c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -191,7 +191,8 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
 	 */
 	cmd->result = 0;
 	if (q->mq_ops) {
-		scsi_mq_requeue_cmd(cmd);
+		blk_mq_requeue_request(cmd->request, true);
+		put_device(&device->sdev_gendev);
 		return;
 	}
 	spin_lock_irqsave(q->queue_lock, flags);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-02-28  8:55 [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert Jianchao Wang
@ 2018-02-28 17:52 ` Bart Van Assche
  2018-03-01  1:57   ` jianchao.wang
  2018-03-02  1:44 ` Martin K. Petersen
  1 sibling, 1 reply; 10+ messages in thread
From: Bart Van Assche @ 2018-02-28 17:52 UTC (permalink / raw)
  To: jejb, martin.petersen, jianchao.w.wang; +Cc: linux-scsi, linux-kernel, hch

On Wed, 2018-02-28 at 16:55 +0800, Jianchao Wang wrote:
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index a86df9c..6fa7b0c 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -191,7 +191,8 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
>  	 */
>  	cmd->result = 0;
>  	if (q->mq_ops) {
> -		scsi_mq_requeue_cmd(cmd);
> +		blk_mq_requeue_request(cmd->request, true);
> +		put_device(&device->sdev_gendev);
>  		return;
>  	}
>  	spin_lock_irqsave(q->queue_lock, flags);

Anyone who sees the put_device() call that follows the blk_mq_requeue_request()
call will wonder why that call occurs there. So I think we need a comment above
that call that explains where the matching get_device() call is.

For the legacy code path, there is a get_device() call in scsi_prep_fn() but no
put_device() call in scsi_unprep_fn() - the matching put_device() calls occur in
scsi_end_request() and after blk_requeue_request().

For scsi-mq however there is a get_device() call in scsi_mq_get_budget() and a
put_device() call in scsi_mq_put_budget(). So why do we need the put_device()
calls after blk_mq_requeue_request() and in the mq path for scsi_end_request()?

Thanks,

Bart.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-02-28 17:52 ` Bart Van Assche
@ 2018-03-01  1:57   ` jianchao.wang
  2018-03-01 17:43     ` Bart Van Assche
  0 siblings, 1 reply; 10+ messages in thread
From: jianchao.wang @ 2018-03-01  1:57 UTC (permalink / raw)
  To: Bart Van Assche, jejb, martin.petersen; +Cc: linux-scsi, linux-kernel, hch

Hi Bart

Thanks for your precious time to review this and kindly detailed response.

On 03/01/2018 01:52 AM, Bart Van Assche wrote:
> On Wed, 2018-02-28 at 16:55 +0800, Jianchao Wang wrote:
>> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
>> index a86df9c..6fa7b0c 100644
>> --- a/drivers/scsi/scsi_lib.c
>> +++ b/drivers/scsi/scsi_lib.c
>> @@ -191,7 +191,8 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
>>  	 */
>>  	cmd->result = 0;
>>  	if (q->mq_ops) {
>> -		scsi_mq_requeue_cmd(cmd);
>> +		blk_mq_requeue_request(cmd->request, true);
>> +		put_device(&device->sdev_gendev);
>>  		return;
>>  	}
>>  	spin_lock_irqsave(q->queue_lock, flags);
> 
> Anyone who sees the put_device() call that follows the blk_mq_requeue_request()
> call will wonder why that call occurs there. So I think we need a comment above
> that call that explains where the matching get_device() call is.

Yes, I will add this.

> For the legacy code path, there is a get_device() call in scsi_prep_fn() but no
> put_device() call in scsi_unprep_fn() - the matching put_device() calls occur in
> scsi_end_request() and after blk_requeue_request().
> 
> For scsi-mq however there is a get_device() call in scsi_mq_get_budget() and a
> put_device() call in scsi_mq_put_budget(). So why do we need the put_device()
> calls after blk_mq_requeue_request() and in the mq path for scsi_end_request()?
> 

>From the source code, we know the scsi_mq_get_budget will be invoked every time when we issue a request.
But scsi_mq_put_budget is just in the fail path.

scsi_queue_rq // if any error
  -> scsi_mq_put_budget

blk_mq_dispatch_rq_list // if no driver tags
  -> blk_mq_put_dispatch_budget
    -> scsi_mq_put_budget
blk_mq_do_dispatch_sched/blk_mq_do_dispatch_ctx // if no requests
  -> blk_mq_put_dispatch_budget
    -> scsi_mq_put_budget

So we have to add put_device after  blk_mq_requeue_request() and in scsi_end_request() to match the
scsi_mq_get_budget.

Thanks
Jianchao

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-03-01  1:57   ` jianchao.wang
@ 2018-03-01 17:43     ` Bart Van Assche
  2018-03-02  1:43         ` Martin K. Petersen
  2018-03-02  2:16       ` jianchao.wang
  0 siblings, 2 replies; 10+ messages in thread
From: Bart Van Assche @ 2018-03-01 17:43 UTC (permalink / raw)
  To: jejb, martin.petersen, jianchao.w.wang; +Cc: linux-scsi, linux-kernel, hch

On Thu, 2018-03-01 at 09:57 +0800, jianchao.wang wrote:
> On 03/01/2018 01:52 AM, Bart Van Assche wrote:
> > On Wed, 2018-02-28 at 16:55 +0800, Jianchao Wang wrote:
> > > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> > > index a86df9c..6fa7b0c 100644
> > > --- a/drivers/scsi/scsi_lib.c
> > > +++ b/drivers/scsi/scsi_lib.c
> > > @@ -191,7 +191,8 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
> > >  	 */
> > >  	cmd->result = 0;
> > >  	if (q->mq_ops) {
> > > -		scsi_mq_requeue_cmd(cmd);
> > > +		blk_mq_requeue_request(cmd->request, true);
> > > +		put_device(&device->sdev_gendev);
> > >  		return;
> > >  	}
> > >  	spin_lock_irqsave(q->queue_lock, flags);
> > 
> > Anyone who sees the put_device() call that follows the blk_mq_requeue_request()
> > call will wonder why that call occurs there. So I think we need a comment above
> > that call that explains where the matching get_device() call is.
> 
> Yes, I will add this.
> 
> > For the legacy code path, there is a get_device() call in scsi_prep_fn() but no
> > put_device() call in scsi_unprep_fn() - the matching put_device() calls occur in
> > scsi_end_request() and after blk_requeue_request().
> > 
> > For scsi-mq however there is a get_device() call in scsi_mq_get_budget() and a
> > put_device() call in scsi_mq_put_budget(). So why do we need the put_device()
> > calls after blk_mq_requeue_request() and in the mq path for scsi_end_request()?
> > 
> 
> From the source code, we know the scsi_mq_get_budget will be invoked every time
> when we issue a request. But scsi_mq_put_budget is just in the fail path.
> 
> scsi_queue_rq // if any error
>   -> scsi_mq_put_budget
> 
> blk_mq_dispatch_rq_list // if no driver tags
>   -> blk_mq_put_dispatch_budget
>     -> scsi_mq_put_budget
> blk_mq_do_dispatch_sched/blk_mq_do_dispatch_ctx // if no requests
>   -> blk_mq_put_dispatch_budget
>     -> scsi_mq_put_budget
> 
> So we have to add put_device after blk_mq_requeue_request() and in
> scsi_end_request() to match the scsi_mq_get_budget.

Hello Jianchao,

Yes, the block layer core guarantees that scsi_mq_get_budget() will be called
before scsi_queue_rq(). I think the full picture is as follows:
* Before scsi_queue_rq() calls .queuecommand(), get_device() is called for the
  SCSI device and the device, target and host busy counters are incremented.
* If the SCSI core decides to requeue a command, scsi_queue_insert() causes
  __scsi_queue_insert() to call scsi_device_unbusy(). That last function
  decreases the device, target and host busy counters but not put_device(sdev).
  Hence the need for a separate put_device() call after requeuing.

It's unfortunate that the SCSI core became so asymmetric. Anyway, since I am
now convinced that this patch is correct, feel free to add:

Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-03-01 17:43     ` Bart Van Assche
@ 2018-03-02  1:43         ` Martin K. Petersen
  2018-03-02  2:16       ` jianchao.wang
  1 sibling, 0 replies; 10+ messages in thread
From: Martin K. Petersen @ 2018-03-02  1:43 UTC (permalink / raw)
  To: jianchao.w.wang
  Cc: Bart Van Assche, jejb, martin.petersen, linux-scsi, linux-kernel, hch


Jianchao,

> Yes, the block layer core guarantees that scsi_mq_get_budget() will be
> called before scsi_queue_rq(). I think the full picture is as follows:

> * Before scsi_queue_rq() calls .queuecommand(), get_device() is called for the
>   SCSI device and the device, target and host busy counters are incremented.
> * If the SCSI core decides to requeue a command, scsi_queue_insert() causes
>   __scsi_queue_insert() to call scsi_device_unbusy(). That last function
>   decreases the device, target and host busy counters but not put_device(sdev).
>   Hence the need for a separate put_device() call after requeuing.
>
> It's unfortunate that the SCSI core became so asymmetric. Anyway,
> since I am now convinced that this patch is correct, feel free to add:

Please add something akin to Bart's explanation as a comment and repost.

Thanks!

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
@ 2018-03-02  1:43         ` Martin K. Petersen
  0 siblings, 0 replies; 10+ messages in thread
From: Martin K. Petersen @ 2018-03-02  1:43 UTC (permalink / raw)
  To: jianchao.w.wang
  Cc: Bart Van Assche, jejb, martin.petersen, linux-scsi, linux-kernel, hch


Jianchao,

> Yes, the block layer core guarantees that scsi_mq_get_budget() will be
> called before scsi_queue_rq(). I think the full picture is as follows:

> * Before scsi_queue_rq() calls .queuecommand(), get_device() is called for the
>   SCSI device and the device, target and host busy counters are incremented.
> * If the SCSI core decides to requeue a command, scsi_queue_insert() causes
>   __scsi_queue_insert() to call scsi_device_unbusy(). That last function
>   decreases the device, target and host busy counters but not put_device(sdev).
>   Hence the need for a separate put_device() call after requeuing.
>
> It's unfortunate that the SCSI core became so asymmetric. Anyway,
> since I am now convinced that this patch is correct, feel free to add:

Please add something akin to Bart's explanation as a comment and repost.

Thanks!

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-02-28  8:55 [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert Jianchao Wang
  2018-02-28 17:52 ` Bart Van Assche
@ 2018-03-02  1:44 ` Martin K. Petersen
  2018-03-02  2:18   ` jianchao.wang
  1 sibling, 1 reply; 10+ messages in thread
From: Martin K. Petersen @ 2018-03-02  1:44 UTC (permalink / raw)
  To: Jianchao Wang
  Cc: jejb, martin.petersen, Bart.VanAssche, linux-scsi, linux-kernel,
	Christoph Hellwig


Jianchao,

> In scsi core, __scsi_queue_insert should just put request back on the
> queue and retry using the same command as before. However, for blk-mq,
> scsi_mq_requeue_cmd is employed here which will unprepare the
> request. To align with the semantics of __scsi_queue_insert, use
> blk_mq_requeue_request with kick_requeue_list == true and put the
> reference of scsi_device.
>
> V1 -> V2:
>  - add put_device on scsi_device->sdev_gendev

Also, please put changelog after the --- delimiter.

> Cc: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Jianchao Wang <jianchao.w.wang@oracle.com>
> ---
>  drivers/scsi/scsi_lib.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index a86df9c..6fa7b0c 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -191,7 +191,8 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy)
>  	 */
>  	cmd->result = 0;
>  	if (q->mq_ops) {
> -		scsi_mq_requeue_cmd(cmd);
> +		blk_mq_requeue_request(cmd->request, true);
> +		put_device(&device->sdev_gendev);
>  		return;
>  	}
>  	spin_lock_irqsave(q->queue_lock, flags);

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-03-01 17:43     ` Bart Van Assche
  2018-03-02  1:43         ` Martin K. Petersen
@ 2018-03-02  2:16       ` jianchao.wang
  1 sibling, 0 replies; 10+ messages in thread
From: jianchao.wang @ 2018-03-02  2:16 UTC (permalink / raw)
  To: Bart Van Assche, jejb, martin.petersen; +Cc: linux-scsi, linux-kernel, hch

Hi Bart

Thanks for your precious time and detailed summary.

On 03/02/2018 01:43 AM, Bart Van Assche wrote:
> Yes, the block layer core guarantees that scsi_mq_get_budget() will be called
> before scsi_queue_rq(). I think the full picture is as follows:
> * Before scsi_queue_rq() calls .queuecommand(), get_device() is called for the
>   SCSI device and the device, target and host busy counters are incremented.

Supply some details here:
scsi_mq_get_budget before calling .queuecommand get_device and increase device_busy.
scsi_queue_rq increases target_busy and host_busy.

> * If the SCSI core decides to requeue a command, scsi_queue_insert() causes
>   __scsi_queue_insert() to call scsi_device_unbusy(). That last function
>   decreases the device, target and host busy counters but not put_device(sdev).
>   Hence the need for a separate put_device() call after requeuing.
> 
> It's unfortunate that the SCSI core became so asymmetric. Anyway, since I am
> now convinced that this patch is correct, feel free to add:
> 
> Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>


Sincerely
Jianchao

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-03-02  1:43         ` Martin K. Petersen
  (?)
@ 2018-03-02  2:17         ` jianchao.wang
  -1 siblings, 0 replies; 10+ messages in thread
From: jianchao.wang @ 2018-03-02  2:17 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: Bart Van Assche, jejb, linux-scsi, linux-kernel, hch

Hi martin

Thanks for your kindly response.

On 03/02/2018 09:43 AM, Martin K. Petersen wrote:
> 
> Jianchao,
> 
>> Yes, the block layer core guarantees that scsi_mq_get_budget() will be
>> called before scsi_queue_rq(). I think the full picture is as follows:
> 
>> * Before scsi_queue_rq() calls .queuecommand(), get_device() is called for the
>>   SCSI device and the device, target and host busy counters are incremented.
>> * If the SCSI core decides to requeue a command, scsi_queue_insert() causes
>>   __scsi_queue_insert() to call scsi_device_unbusy(). That last function
>>   decreases the device, target and host busy counters but not put_device(sdev).
>>   Hence the need for a separate put_device() call after requeuing.
>>
>> It's unfortunate that the SCSI core became so asymmetric. Anyway,
>> since I am now convinced that this patch is correct, feel free to add:
> 
> Please add something akin to Bart's explanation as a comment and repost.

yes, sure.


Thanks
Jianchao

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
  2018-03-02  1:44 ` Martin K. Petersen
@ 2018-03-02  2:18   ` jianchao.wang
  0 siblings, 0 replies; 10+ messages in thread
From: jianchao.wang @ 2018-03-02  2:18 UTC (permalink / raw)
  To: Martin K. Petersen
  Cc: jejb, Bart.VanAssche, linux-scsi, linux-kernel, Christoph Hellwig

Hi martin

On 03/02/2018 09:44 AM, Martin K. Petersen wrote:
>> In scsi core, __scsi_queue_insert should just put request back on the
>> queue and retry using the same command as before. However, for blk-mq,
>> scsi_mq_requeue_cmd is employed here which will unprepare the
>> request. To align with the semantics of __scsi_queue_insert, use
>> blk_mq_requeue_request with kick_requeue_list == true and put the
>> reference of scsi_device.
>>
>> V1 -> V2:
>>  - add put_device on scsi_device->sdev_gendev
> Also, please put changelog after the --- delimiter.
> 

Yes, I will modify this next version.

Thanks 
Jianchao

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-03-02  2:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-28  8:55 [PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert Jianchao Wang
2018-02-28 17:52 ` Bart Van Assche
2018-03-01  1:57   ` jianchao.wang
2018-03-01 17:43     ` Bart Van Assche
2018-03-02  1:43       ` Martin K. Petersen
2018-03-02  1:43         ` Martin K. Petersen
2018-03-02  2:17         ` jianchao.wang
2018-03-02  2:16       ` jianchao.wang
2018-03-02  1:44 ` Martin K. Petersen
2018-03-02  2:18   ` jianchao.wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.