Skip to content

Commit 15924b0

Browse files
Karan Tilak Kumarmartinkpetersen
authored andcommitted
scsi: fnic: Replace sgreset tag with max_tag_id
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> Link: https://lore.kernel.org/r/20230817182146.229059-1-kartilak@cisco.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 530e86c commit 15924b0

File tree

2 files changed

+11
-12
lines changed

2 files changed

+11
-12
lines changed

drivers/scsi/fnic/fnic.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
#define DRV_NAME "fnic"
2929
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
30-
#define DRV_VERSION "1.6.0.54"
30+
#define DRV_VERSION "1.6.0.56"
3131
#define PFX DRV_NAME ": "
3232
#define DFX DRV_NAME "%d: "
3333

@@ -236,6 +236,7 @@ struct fnic {
236236
unsigned int wq_count;
237237
unsigned int cq_count;
238238

239+
struct mutex sgreset_mutex;
239240
struct dentry *fnic_stats_debugfs_host;
240241
struct dentry *fnic_stats_debugfs_file;
241242
struct dentry *fnic_reset_debugfs_file;

drivers/scsi/fnic/fnic_scsi.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,7 +2220,6 @@ int fnic_device_reset(struct scsi_cmnd *sc)
22202220
struct reset_stats *reset_stats;
22212221
int tag = rq->tag;
22222222
DECLARE_COMPLETION_ONSTACK(tm_done);
2223-
int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/
22242223
bool new_sc = 0;
22252224

22262225
/* Wait for rport to unblock */
@@ -2250,17 +2249,17 @@ int fnic_device_reset(struct scsi_cmnd *sc)
22502249
}
22512250

22522251
fnic_priv(sc)->flags = FNIC_DEVICE_RESET;
2253-
/* Allocate tag if not present */
22542252

22552253
if (unlikely(tag < 0)) {
22562254
/*
2257-
* Really should fix the midlayer to pass in a proper
2258-
* request for ioctls...
2255+
* For device reset issued through sg3utils, we let
2256+
* only one LUN_RESET to go through and use a special
2257+
* tag equal to max_tag_id so that we don't have to allocate
2258+
* or free it. It won't interact with tags
2259+
* allocated by mid layer.
22592260
*/
2260-
tag = fnic_scsi_host_start_tag(fnic, sc);
2261-
if (unlikely(tag == SCSI_NO_TAG))
2262-
goto fnic_device_reset_end;
2263-
tag_gen_flag = 1;
2261+
mutex_lock(&fnic->sgreset_mutex);
2262+
tag = fnic->fnic_max_tag_id;
22642263
new_sc = 1;
22652264
}
22662265
io_lock = fnic_io_lock_hash(fnic, sc);
@@ -2432,9 +2431,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
24322431
(u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
24332432
fnic_flags_and_state(sc));
24342433

2435-
/* free tag if it is allocated */
2436-
if (unlikely(tag_gen_flag))
2437-
fnic_scsi_host_end_tag(fnic, sc);
2434+
if (new_sc)
2435+
mutex_unlock(&fnic->sgreset_mutex);
24382436

24392437
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
24402438
"Returning from device reset %s\n",

0 commit comments

Comments
 (0)