[PATCH] lpfc 8.1.3: Fix polling mode panic
authorJamie Wellnitz <Jamie.Wellnitz@emulex.com>
Wed, 1 Mar 2006 03:33:12 +0000 (22:33 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Mon, 6 Mar 2006 15:47:46 +0000 (09:47 -0600)
Fix polling mode panic

Cause: Race between interrupt driven and polling path in harvesting iocbs
from
the response ring.

Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c

index 094f18f1fa05c0ba6ba3aa580a151497d2804c08..f93799873721290c38b774b9668ad5bb0dd91365 100644 (file)
@@ -467,6 +467,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
        sdev = cmd->device;
        cmd->scsi_done(cmd);
 
+       if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+               lpfc_release_scsi_buf(phba, lpfc_cmd);
+               return;
+       }
+
        if (!result && pnode != NULL &&
           ((jiffies - pnode->last_ramp_up_time) >
                LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
index d08fd89dd44ff64966c11c1e589a7169ed76f8a2..764aadbec71b5096ea5320e0a35eef35b8c2b70e 100644 (file)
@@ -1154,12 +1154,17 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                        cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
                                                         &rspiocbq);
                        if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
-                               spin_unlock_irqrestore(
-                                      phba->host->host_lock, iflag);
-                               (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
-                                                     &rspiocbq);
-                               spin_lock_irqsave(phba->host->host_lock,
-                                                 iflag);
+                               if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+                                       (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+                                                             &rspiocbq);
+                               } else {
+                                       spin_unlock_irqrestore(
+                                               phba->host->host_lock, iflag);
+                                       (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+                                                             &rspiocbq);
+                                       spin_lock_irqsave(phba->host->host_lock,
+                                                         iflag);
+                               }
                        }
                        break;
                default: