diff mbox series

scsi: fnic: Replace sgreset tag with max_tag_id

Message ID 20230817182146.229059-1-kartilak@cisco.com
State New
Headers show
Series scsi: fnic: Replace sgreset tag with max_tag_id | expand

Commit Message

Karan Tilak Kumar Aug. 17, 2023, 6:21 p.m. UTC
sgreset is issued with a scsi command pointer.
The device reset code assumes that it was issued
on a hardware queue, and calls block multiqueue
layer. However, the assumption is broken, and
there is no hardware queue associated with the
sgreset, and this leads to a crash due to a
null pointer exception.

Fix the code to use the max_tag_id as a tag
which does not overlap with the other tags
issued by mid layer.

Tested by running FC traffic for a few minutes,
and by issuing sgreset on the device in parallel.
Without the fix, the crash is observed right away.
With this fix, no crash is observed.

Reviewed-by: Sesidhar Baddela <sebaddel@cisco.com>
Tested-by: Karan Tilak Kumar <kartilak@cisco.com>
Signed-off-by: Karan Tilak Kumar <kartilak@cisco.com>
---
 drivers/scsi/fnic/fnic.h      |  3 ++-
 drivers/scsi/fnic/fnic_scsi.c | 20 +++++++++-----------
 2 files changed, 11 insertions(+), 12 deletions(-)

Comments

Martin K. Petersen Aug. 25, 2023, 9:15 p.m. UTC | #1
Karan,

> sgreset is issued with a scsi command pointer. The device reset code
> assumes that it was issued on a hardware queue, and calls block
> multiqueue layer. However, the assumption is broken, and there is no
> hardware queue associated with the sgreset, and this leads to a crash
> due to a null pointer exception.

Applied to 6.6/scsi-staging, thanks!
Karan Tilak Kumar Aug. 29, 2023, 2:44 a.m. UTC | #2
Thanks Martin.

Do I need to send out a patch request to apply this patch to 6.5/scsi-fixes?

Regards,
Karan

-----Original Message-----
From: Martin K. Petersen <martin.petersen@oracle.com> 
Sent: Friday, August 25, 2023 2:16 PM
To: Karan Tilak Kumar (kartilak) <kartilak@cisco.com>
Cc: Sesidhar Baddela (sebaddel) <sebaddel@cisco.com>; Arulprabhu Ponnusamy (arulponn) <arulponn@cisco.com>; Dhanraj Jhawar (djhawar) <djhawar@cisco.com>; Gian Carlo Boffa (gcboffa) <gcboffa@cisco.com>; Masa Kai (mkai2) <mkai2@cisco.com>; Satish Kharat (satishkh) <satishkh@cisco.com>; jejb@linux.ibm.com; martin.petersen@oracle.com; linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH] scsi: fnic: Replace sgreset tag with max_tag_id


Karan,

> sgreset is issued with a scsi command pointer. The device reset code 
> assumes that it was issued on a hardware queue, and calls block 
> multiqueue layer. However, the assumption is broken, and there is no 
> hardware queue associated with the sgreset, and this leads to a crash 
> due to a null pointer exception.

Applied to 6.6/scsi-staging, thanks!
Martin K. Petersen Aug. 31, 2023, 1:12 a.m. UTC | #3
Karan,

> Do I need to send out a patch request to apply this patch to
> 6.5/scsi-fixes?

You can request a stable backport once the commit is in Linus' tree.
Karan Tilak Kumar Sept. 7, 2023, 9:09 p.m. UTC | #4
Hi Martin,

Would I receive an email when the patch has been applied to Linus' tree?

I just checked out master branch from this repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
The fix has not been applied there yet. Am I looking in the right place?

>> You can request a stable backport once the commit is in Linus' tree.

Can you please let me know the procedure to request for this?

Thanks,
Karan

-----Original Message-----
From: Martin K. Petersen <martin.petersen@oracle.com> 
Sent: Wednesday, August 30, 2023 6:13 PM
To: Karan Tilak Kumar (kartilak) <kartilak@cisco.com>
Cc: Martin K. Petersen <martin.petersen@oracle.com>; Sesidhar Baddela (sebaddel) <sebaddel@cisco.com>; Arulprabhu Ponnusamy (arulponn) <arulponn@cisco.com>; Dhanraj Jhawar (djhawar) <djhawar@cisco.com>; Gian Carlo Boffa (gcboffa) <gcboffa@cisco.com>; Masa Kai (mkai2) <mkai2@cisco.com>; Satish Kharat (satishkh) <satishkh@cisco.com>; jejb@linux.ibm.com; linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH] scsi: fnic: Replace sgreset tag with max_tag_id


Karan,

> Do I need to send out a patch request to apply this patch to 
> 6.5/scsi-fixes?

You can request a stable backport once the commit is in Linus' tree.
diff mbox series

Patch

diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index e51e92f932fa..93c68931a593 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -27,7 +27,7 @@ 
 
 #define DRV_NAME		"fnic"
 #define DRV_DESCRIPTION		"Cisco FCoE HBA Driver"
-#define DRV_VERSION		"1.6.0.55"
+#define DRV_VERSION		"1.6.0.56"
 #define PFX			DRV_NAME ": "
 #define DFX                     DRV_NAME "%d: "
 
@@ -236,6 +236,7 @@  struct fnic {
 	unsigned int wq_count;
 	unsigned int cq_count;
 
+	struct mutex sgreset_mutex;
 	struct dentry *fnic_stats_debugfs_host;
 	struct dentry *fnic_stats_debugfs_file;
 	struct dentry *fnic_reset_debugfs_file;
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index be89ce96df46..185142efee3d 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -2222,7 +2222,6 @@  int fnic_device_reset(struct scsi_cmnd *sc)
 	struct reset_stats *reset_stats;
 	int tag = rq->tag;
 	DECLARE_COMPLETION_ONSTACK(tm_done);
-	int tag_gen_flag = 0;   /*to track tags allocated by fnic driver*/
 	bool new_sc = 0;
 
 	/* Wait for rport to unblock */
@@ -2252,17 +2251,17 @@  int fnic_device_reset(struct scsi_cmnd *sc)
 	}
 
 	fnic_priv(sc)->flags = FNIC_DEVICE_RESET;
-	/* Allocate tag if not present */
 
 	if (unlikely(tag < 0)) {
 		/*
-		 * Really should fix the midlayer to pass in a proper
-		 * request for ioctls...
+		 * For device reset issued through sg3utils, we let
+		 * only one LUN_RESET to go through and use a special
+		 * tag equal to max_tag_id so that we don't have to allocate
+		 * or free it. It won't interact with tags
+		 * allocated by mid layer.
 		 */
-		tag = fnic_scsi_host_start_tag(fnic, sc);
-		if (unlikely(tag == SCSI_NO_TAG))
-			goto fnic_device_reset_end;
-		tag_gen_flag = 1;
+		mutex_lock(&fnic->sgreset_mutex);
+		tag = fnic->fnic_max_tag_id;
 		new_sc = 1;
 	}
 	io_lock = fnic_io_lock_hash(fnic, sc);
@@ -2434,9 +2433,8 @@  int fnic_device_reset(struct scsi_cmnd *sc)
 		  (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
 		  fnic_flags_and_state(sc));
 
-	/* free tag if it is allocated */
-	if (unlikely(tag_gen_flag))
-		fnic_scsi_host_end_tag(fnic, sc);
+	if (new_sc)
+		mutex_unlock(&fnic->sgreset_mutex);
 
 	FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
 		      "Returning from device reset %s\n",