[SCSI] lpfc 8.1.12 : Fix unlock inside list traversal
Fix unlock inside list traversal.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 4a9e613..e3bebf9 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -3272,9 +3272,7 @@
if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
struct lpfc_nodelist *ndlp;
- spin_unlock_irq(phba->host->host_lock);
- ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
- spin_lock_irq(phba->host->host_lock);
+ ndlp = __lpfc_findnode_rpi(phba, cmd->ulpContext);
remote_ID = ndlp->nlp_DID;
} else {
remote_ID = cmd->un.elsreq64.remoteID;
@@ -3298,6 +3296,7 @@
void
lpfc_els_flush_cmd(struct lpfc_hba * phba)
{
+ LIST_HEAD(completions);
struct lpfc_sli_ring *pring;
struct lpfc_iocbq *tmp_iocb, *piocb;
IOCB_t *cmd = NULL;
@@ -3319,18 +3318,9 @@
continue;
}
- list_del(&piocb->list);
+ list_move_tail(&piocb->list, &completions);
pring->txq_cnt--;
- cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
- cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
-
- if (piocb->iocb_cmpl) {
- spin_unlock_irq(phba->host->host_lock);
- (piocb->iocb_cmpl) (phba, piocb, piocb);
- spin_lock_irq(phba->host->host_lock);
- } else
- lpfc_sli_release_iocbq(phba, piocb);
}
list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3343,6 +3333,20 @@
lpfc_sli_issue_abort_iotag(phba, pring, piocb);
}
spin_unlock_irq(phba->host->host_lock);
+
+ while(!list_empty(&completions)) {
+ piocb = list_get_first(&completions, struct lpfc_iocbq, list);
+ cmd = &piocb->iocb;
+ list_del(&piocb->list);
+
+ if (piocb->iocb_cmpl) {
+ cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
+ cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
+ (piocb->iocb_cmpl) (phba, piocb, piocb);
+ } else
+ lpfc_sli_release_iocbq(phba, piocb);
+ }
+
return;
}