diff mbox series

[12/12] scsi: iscsi: Fix race between recovery and task xmit.

Message ID 20220308002747.122682-13-michael.christie@oracle.com
State Superseded
Headers show
Series misc iscsi patches | expand

Commit Message

Mike Christie March 8, 2022, 12:27 a.m. UTC
set_bit doesn't provide a barrier, so we can hit race where we've called
iscsi_suspend_tx and didn't see a work queued, and then a work is queued
and run and doesn't see the suspend bit is set. We will then call into the
driver when they might have already cleaned up their xmit related code.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/libiscsi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Comments

Lee Duncan March 14, 2022, 5:46 p.m. UTC | #1
On 3/7/22 16:27, Mike Christie wrote:
> set_bit doesn't provide a barrier, so we can hit race where we've called
> iscsi_suspend_tx and didn't see a work queued, and then a work is queued
> and run and doesn't see the suspend bit is set. We will then call into the
> driver when they might have already cleaned up their xmit related code.
> 
> Signed-off-by: Mike Christie <michael.christie@oracle.com>
> ---
>   drivers/scsi/libiscsi.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
> index a165d4d10cea..b79739b41b10 100644
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -2020,10 +2020,14 @@ EXPORT_SYMBOL_GPL(iscsi_suspend_queue);
>    */
>   void iscsi_suspend_tx(struct iscsi_conn *conn)
>   {
> -	struct Scsi_Host *shost = conn->session->host;
> +	struct iscsi_session *session = conn->session;
> +	struct Scsi_Host *shost = session->host;
>   	struct iscsi_host *ihost = shost_priv(shost);
>   
> +	spin_lock_bh(&session->frwd_lock);
>   	set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags);
> +	spin_unlock_bh(&session->frwd_lock);
> +
>   	if (ihost->workq)
>   		flush_work(&conn->xmitwork);
>   }

Reviewed-by: Lee Duncan <lduncan@suse.com>
diff mbox series

Patch

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index a165d4d10cea..b79739b41b10 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2020,10 +2020,14 @@  EXPORT_SYMBOL_GPL(iscsi_suspend_queue);
  */
 void iscsi_suspend_tx(struct iscsi_conn *conn)
 {
-	struct Scsi_Host *shost = conn->session->host;
+	struct iscsi_session *session = conn->session;
+	struct Scsi_Host *shost = session->host;
 	struct iscsi_host *ihost = shost_priv(shost);
 
+	spin_lock_bh(&session->frwd_lock);
 	set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags);
+	spin_unlock_bh(&session->frwd_lock);
+
 	if (ihost->workq)
 		flush_work(&conn->xmitwork);
 }