Commit 59c68eaa authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Fix Abort request WQ selection

When running loads that generated aborts, io errors where seen.  Turns
out the abort requests where not placed on the proper WQ resulting in
the errors. Closer inspection inspection of this error also showed
improper spinlock api use.

Correct the WQ selection policy for the abort requests.  Correct
spin_lock/spin_lock_irq/spin_lock_irqsave usage.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 2448e484
...@@ -1021,7 +1021,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) ...@@ -1021,7 +1021,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
if (lpfc_test_rrq_active(phba, ndlp, if (lpfc_test_rrq_active(phba, ndlp,
lpfc_cmd->cur_iocbq.sli4_lxritag)) lpfc_cmd->cur_iocbq.sli4_lxritag))
continue; continue;
list_del(&lpfc_cmd->list); list_del_init(&lpfc_cmd->list);
found = 1; found = 1;
break; break;
} }
...@@ -1036,7 +1036,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) ...@@ -1036,7 +1036,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
if (lpfc_test_rrq_active( if (lpfc_test_rrq_active(
phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag)) phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag))
continue; continue;
list_del(&lpfc_cmd->list); list_del_init(&lpfc_cmd->list);
found = 1; found = 1;
break; break;
} }
...@@ -4716,7 +4716,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) ...@@ -4716,7 +4716,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
int ret = SUCCESS, status = 0; int ret = SUCCESS, status = 0;
struct lpfc_sli_ring *pring_s4; struct lpfc_sli_ring *pring_s4;
int ret_val; int ret_val;
unsigned long flags, iflags; unsigned long flags;
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
status = fc_block_scsi_eh(cmnd); status = fc_block_scsi_eh(cmnd);
...@@ -4816,16 +4816,16 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) ...@@ -4816,16 +4816,16 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl; abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
abtsiocb->vport = vport; abtsiocb->vport = vport;
if (phba->sli_rev == LPFC_SLI_REV4) { if (phba->sli_rev == LPFC_SLI_REV4) {
pring_s4 = lpfc_sli4_calc_ring(phba, iocb); pring_s4 = lpfc_sli4_calc_ring(phba, abtsiocb);
if (pring_s4 == NULL) { if (pring_s4 == NULL) {
ret = FAILED; ret = FAILED;
goto out_unlock; goto out_unlock;
} }
/* Note: both hbalock and ring_lock must be set here */ /* Note: both hbalock and ring_lock must be set here */
spin_lock_irqsave(&pring_s4->ring_lock, iflags); spin_lock(&pring_s4->ring_lock);
ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno, ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno,
abtsiocb, 0); abtsiocb, 0);
spin_unlock_irqrestore(&pring_s4->ring_lock, iflags); spin_unlock(&pring_s4->ring_lock);
} else { } else {
ret_val = __lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, ret_val = __lpfc_sli_issue_iocb(phba, LPFC_FCP_RING,
abtsiocb, 0); abtsiocb, 0);
......
...@@ -11300,11 +11300,11 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, ...@@ -11300,11 +11300,11 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
unsigned long iflags; unsigned long iflags;
struct lpfc_sli_ring *pring_s4; struct lpfc_sli_ring *pring_s4;
spin_lock_irq(&phba->hbalock); spin_lock_irqsave(&phba->hbalock, iflags);
/* all I/Os are in process of being flushed */ /* all I/Os are in process of being flushed */
if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) { if (phba->hba_flag & HBA_FCP_IOQ_FLUSH) {
spin_unlock_irq(&phba->hbalock); spin_unlock_irqrestore(&phba->hbalock, iflags);
return 0; return 0;
} }
sum = 0; sum = 0;
...@@ -11366,14 +11366,14 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, ...@@ -11366,14 +11366,14 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
iocbq->iocb_flag |= LPFC_DRIVER_ABORTED; iocbq->iocb_flag |= LPFC_DRIVER_ABORTED;
if (phba->sli_rev == LPFC_SLI_REV4) { if (phba->sli_rev == LPFC_SLI_REV4) {
pring_s4 = lpfc_sli4_calc_ring(phba, iocbq); pring_s4 = lpfc_sli4_calc_ring(phba, abtsiocbq);
if (pring_s4 == NULL) if (!pring_s4)
continue; continue;
/* Note: both hbalock and ring_lock must be set here */ /* Note: both hbalock and ring_lock must be set here */
spin_lock_irqsave(&pring_s4->ring_lock, iflags); spin_lock(&pring_s4->ring_lock);
ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno, ret_val = __lpfc_sli_issue_iocb(phba, pring_s4->ringno,
abtsiocbq, 0); abtsiocbq, 0);
spin_unlock_irqrestore(&pring_s4->ring_lock, iflags); spin_unlock(&pring_s4->ring_lock);
} else { } else {
ret_val = __lpfc_sli_issue_iocb(phba, pring->ringno, ret_val = __lpfc_sli_issue_iocb(phba, pring->ringno,
abtsiocbq, 0); abtsiocbq, 0);
...@@ -11385,7 +11385,7 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, ...@@ -11385,7 +11385,7 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
else else
sum++; sum++;
} }
spin_unlock_irq(&phba->hbalock); spin_unlock_irqrestore(&phba->hbalock, iflags);
return sum; return sum;
} }
......
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