All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] scsi: ibmvscsi: protect abort handler from done-scmd in flight
@ 2014-06-05  6:16 Liu Ping Fan
  2014-06-05  8:00 ` Paolo Bonzini
  0 siblings, 1 reply; 2+ messages in thread
From: Liu Ping Fan @ 2014-06-05  6:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Robert Jennings, Paolo Bonzini

Take the following scene in guest:
seqA: scsi_done() -> gapX (before taking REQ_ATOM_COMPLETE)
seqB: scmd_eh_abort_handler()-> ...-> ibmvscsi_eh_abort_handler()->
      ...->scsi_put_command(scmd)

If seqA is scheduled at gapX, and seqB reclaims scmd. Then when seqA
comes back, it tries to access the scmd when is turned back to mempool.

This patch fixes the race by ensuring when ibmvscsi_eh_abort_handler()
returns, no scsi_done is in flight

Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
When trying to figure the scsi_cmnd in flight issue, I learned from Paolo (thanks).
He showed me the way how virtscsi resolves the race between abort-handler
and scsi_done in flight. And I think that this method is also needed by ibmvscsi.
---
 drivers/scsi/ibmvscsi/ibmvscsi.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index fa76440..325cef6 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1828,16 +1828,19 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
 
 	if ((crq->status != VIOSRP_OK && crq->status != VIOSRP_OK2) && evt_struct->cmnd)
 		evt_struct->cmnd->result = DID_ERROR << 16;
-	if (evt_struct->done)
-		evt_struct->done(evt_struct);
-	else
-		dev_err(hostdata->dev, "returned done() is NULL; not running it!\n");
 
 	/*
 	 * Lock the host_lock before messing with these structures, since we
 	 * are running in a task context
+	 * Also, this lock helps ibmvscsi_eh_abort_handler() to shield the
+	 * scsi_done() in flight.
 	 */
 	spin_lock_irqsave(evt_struct->hostdata->host->host_lock, flags);
+	if (evt_struct->done)
+		evt_struct->done(evt_struct);
+	else
+		dev_err(hostdata->dev, "returned done() is NULL; not running it!\n");
+
 	list_del(&evt_struct->list);
 	free_event_struct(&evt_struct->hostdata->pool, evt_struct);
 	spin_unlock_irqrestore(evt_struct->hostdata->host->host_lock, flags);
-- 
1.8.1.4


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

* Re: [PATCH] scsi: ibmvscsi: protect abort handler from done-scmd in flight
  2014-06-05  6:16 [PATCH] scsi: ibmvscsi: protect abort handler from done-scmd in flight Liu Ping Fan
@ 2014-06-05  8:00 ` Paolo Bonzini
  0 siblings, 0 replies; 2+ messages in thread
From: Paolo Bonzini @ 2014-06-05  8:00 UTC (permalink / raw)
  To: Liu Ping Fan, linux-scsi; +Cc: Robert Jennings

Il 05/06/2014 08:16, Liu Ping Fan ha scritto:
> Take the following scene in guest:
> seqA: scsi_done() -> gapX (before taking REQ_ATOM_COMPLETE)
> seqB: scmd_eh_abort_handler()-> ...-> ibmvscsi_eh_abort_handler()->
>       ...->scsi_put_command(scmd)
>
> If seqA is scheduled at gapX, and seqB reclaims scmd. Then when seqA
> comes back, it tries to access the scmd when is turned back to mempool.
>
> This patch fixes the race by ensuring when ibmvscsi_eh_abort_handler()
> returns, no scsi_done is in flight
>
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
> When trying to figure the scsi_cmnd in flight issue, I learned from Paolo (thanks).
> He showed me the way how virtscsi resolves the race between abort-handler
> and scsi_done in flight. And I think that this method is also needed by ibmvscsi.
> ---
>  drivers/scsi/ibmvscsi/ibmvscsi.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
> index fa76440..325cef6 100644
> --- a/drivers/scsi/ibmvscsi/ibmvscsi.c
> +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
> @@ -1828,16 +1828,19 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq,
>
>  	if ((crq->status != VIOSRP_OK && crq->status != VIOSRP_OK2) && evt_struct->cmnd)
>  		evt_struct->cmnd->result = DID_ERROR << 16;
> -	if (evt_struct->done)
> -		evt_struct->done(evt_struct);
> -	else
> -		dev_err(hostdata->dev, "returned done() is NULL; not running it!\n");
>
>  	/*
>  	 * Lock the host_lock before messing with these structures, since we
>  	 * are running in a task context
> +	 * Also, this lock helps ibmvscsi_eh_abort_handler() to shield the
> +	 * scsi_done() in flight.
>  	 */
>  	spin_lock_irqsave(evt_struct->hostdata->host->host_lock, flags);
> +	if (evt_struct->done)
> +		evt_struct->done(evt_struct);
> +	else
> +		dev_err(hostdata->dev, "returned done() is NULL; not running it!\n");
> +
>  	list_del(&evt_struct->list);
>  	free_event_struct(&evt_struct->hostdata->pool, evt_struct);
>  	spin_unlock_irqrestore(evt_struct->hostdata->host->host_lock, flags);
>

I think this is not necessary because ibmvscsi places TMFs and commands 
in the same queue; virtio-scsi instead uses two different queues.

So ibmvscsi_handle_crq processes all completed requests, which naturally 
serializes the processing of the TMF and the command.

Paolo

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

end of thread, other threads:[~2014-06-05  8:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-05  6:16 [PATCH] scsi: ibmvscsi: protect abort handler from done-scmd in flight Liu Ping Fan
2014-06-05  8:00 ` Paolo Bonzini

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.