Browse Source

scsi: qla2xxx: Timeouts occur on surprise removal of QLogic adapter

When doing a surprise removal of an adapter, some in flight I/Os can get
stuck and take a while to complete (they actually time out and are
retried). We are not handling an early error exit from qla2xxx_eh_abort
properly.

Fixes: 45235022da99 ("scsi: qla2xxx: Fix driver unload by shutting down chip")
Signed-off-by: Bill Kuzeja <william.kuzeja@stratus.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Acked-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Bill Kuzeja 6 years ago
parent
commit
f2ffd4e5bc
1 changed files with 8 additions and 2 deletions
  1. 8 2
      drivers/scsi/qla2xxx/qla_os.c

+ 8 - 2
drivers/scsi/qla2xxx/qla_os.c

@@ -1749,7 +1749,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 static void
 static void
 __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
 __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
 {
 {
-	int cnt;
+	int cnt, status;
 	unsigned long flags;
 	unsigned long flags;
 	srb_t *sp;
 	srb_t *sp;
 	scsi_qla_host_t *vha = qp->vha;
 	scsi_qla_host_t *vha = qp->vha;
@@ -1799,10 +1799,16 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res)
 					if (!sp_get(sp)) {
 					if (!sp_get(sp)) {
 						spin_unlock_irqrestore
 						spin_unlock_irqrestore
 							(qp->qp_lock_ptr, flags);
 							(qp->qp_lock_ptr, flags);
-						qla2xxx_eh_abort(
+						status = qla2xxx_eh_abort(
 							GET_CMD_SP(sp));
 							GET_CMD_SP(sp));
 						spin_lock_irqsave
 						spin_lock_irqsave
 							(qp->qp_lock_ptr, flags);
 							(qp->qp_lock_ptr, flags);
+						/*
+						 * Get rid of extra reference caused
+						 * by early exit from qla2xxx_eh_abort
+						 */
+						if (status == FAST_IO_FAIL)
+							atomic_dec(&sp->ref_count);
 					}
 					}
 				}
 				}
 				sp->done(sp, res);
 				sp->done(sp, res);