Commit db196935 authored by Hiral Shah's avatar Hiral Shah Committed by James Bottomley

fnic: Use the local variable instead of I/O flag to acquire io_req_lock in...

fnic: Use the local variable instead of I/O flag to acquire io_req_lock in fnic_queuecommand() to avoid deadloack

We added changes in fnic driver patch 1.6.0.16 to acquire
io_req_lock in fnic_queuecommand() before issuing I/O so that io completion
is serialized. But when releasing the lock we check for the I/O flag and
this could be modified if IO abort occurs before I/O completion. In this case
we wont release the lock and causes deadlock in some scenerios. Using the
local variable to check the IO lock status will resolve the problem.

Fixes: 41df7b02Signed-off-by: default avatarHiral Shah <hishah@cisco.com>
Signed-off-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Signed-off-by: default avatarAnil Chintalapati <achintal@cisco.com>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent 4f258a46
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define DRV_NAME "fnic" #define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
#define DRV_VERSION "1.6.0.17" #define DRV_VERSION "1.6.0.17a"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: " #define DFX DRV_NAME "%d: "
......
...@@ -425,6 +425,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ ...@@ -425,6 +425,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
unsigned long ptr; unsigned long ptr;
struct fc_rport_priv *rdata; struct fc_rport_priv *rdata;
spinlock_t *io_lock = NULL; spinlock_t *io_lock = NULL;
int io_lock_acquired = 0;
if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED))) if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED)))
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
...@@ -518,6 +519,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ ...@@ -518,6 +519,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
/* initialize rest of io_req */ /* initialize rest of io_req */
io_lock_acquired = 1;
io_req->port_id = rport->port_id; io_req->port_id = rport->port_id;
io_req->start_time = jiffies; io_req->start_time = jiffies;
CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING;
...@@ -571,7 +573,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ ...@@ -571,7 +573,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
(((u64)CMD_FLAGS(sc) >> 32) | CMD_STATE(sc))); (((u64)CMD_FLAGS(sc) >> 32) | CMD_STATE(sc)));
/* if only we issued IO, will we have the io lock */ /* if only we issued IO, will we have the io lock */
if (CMD_FLAGS(sc) & FNIC_IO_INITIALIZED) if (io_lock_acquired)
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
atomic_dec(&fnic->in_flight); atomic_dec(&fnic->in_flight);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment