Commit 66818663 authored by Hiral Shah's avatar Hiral Shah Committed by Christoph Hellwig

fnic: Failing to queue aborts due to Q full cause terminate driver timeout

In fnic abort handler, abort queuing can be failed when hardware queue is full.
The command state is left as abort queued. The command with abort queued state
will never be queued next time for abort or termiantion.
Fix restores the command state in above case.
Signed-off-by: default avatarHiral Shah <hishah@cisco.com>
Signed-off-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Signed-off-by: default avatarNarsimhulu Musini <nmusini@cisco.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent c8ff03c6
...@@ -1312,8 +1312,9 @@ static void fnic_cleanup_io(struct fnic *fnic, int exclude_id) ...@@ -1312,8 +1312,9 @@ static void fnic_cleanup_io(struct fnic *fnic, int exclude_id)
cleanup_scsi_cmd: cleanup_scsi_cmd:
sc->result = DID_TRANSPORT_DISRUPTED << 16; sc->result = DID_TRANSPORT_DISRUPTED << 16;
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "fnic_cleanup_io:" FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
" DID_TRANSPORT_DISRUPTED\n"); "%s: sc duration = %lu DID_TRANSPORT_DISRUPTED\n",
__func__, (jiffies - start_time));
if (atomic64_read(&fnic->io_cmpl_skip)) if (atomic64_read(&fnic->io_cmpl_skip))
atomic64_dec(&fnic->io_cmpl_skip); atomic64_dec(&fnic->io_cmpl_skip);
...@@ -1733,6 +1734,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) ...@@ -1733,6 +1734,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
struct fnic_stats *fnic_stats; struct fnic_stats *fnic_stats;
struct abort_stats *abts_stats; struct abort_stats *abts_stats;
struct terminate_stats *term_stats; struct terminate_stats *term_stats;
enum fnic_ioreq_state old_ioreq_state;
int tag; int tag;
DECLARE_COMPLETION_ONSTACK(tm_done); DECLARE_COMPLETION_ONSTACK(tm_done);
...@@ -1793,6 +1795,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) ...@@ -1793,6 +1795,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
* the completion wont be done till mid-layer, since abort * the completion wont be done till mid-layer, since abort
* has already started. * has already started.
*/ */
old_ioreq_state = CMD_STATE(sc);
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING;
CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE;
...@@ -1816,6 +1819,8 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) ...@@ -1816,6 +1819,8 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
if (fnic_queue_abort_io_req(fnic, sc->request->tag, task_req, if (fnic_queue_abort_io_req(fnic, sc->request->tag, task_req,
fc_lun.scsi_lun, io_req)) { fc_lun.scsi_lun, io_req)) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING)
CMD_STATE(sc) = old_ioreq_state;
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = (struct fnic_io_req *)CMD_SP(sc);
if (io_req) if (io_req)
io_req->abts_done = NULL; io_req->abts_done = NULL;
...@@ -1859,12 +1864,8 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) ...@@ -1859,12 +1864,8 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) { if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
if (task_req == FCPIO_ITMF_ABT_TASK) { if (task_req == FCPIO_ITMF_ABT_TASK) {
FNIC_SCSI_DBG(KERN_INFO,
fnic->lport->host, "Abort Driver Timeout\n");
atomic64_inc(&abts_stats->abort_drv_timeouts); atomic64_inc(&abts_stats->abort_drv_timeouts);
} else { } else {
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"Terminate Driver Timeout\n");
atomic64_inc(&term_stats->terminate_drv_timeouts); atomic64_inc(&term_stats->terminate_drv_timeouts);
} }
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT; CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT;
......
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