[SCSI] mpt2sas: fix for driver fails EEH, recovery from injected pci bus error
authorSreekanth Reddy <Sreekanth.Reddy@lsi.com>
Tue, 18 Dec 2012 13:45:30 +0000 (14:45 +0100)
committerJames Bottomley <JBottomley@Parallels.com>
Tue, 29 Jan 2013 03:15:35 +0000 (14:15 +1100)
This patch stops the driver to invoke kthread (which remove the dead ioc)
for some time while EEH recovery has started.

[thenzl: add a 'non_operational_loop' reset.]
Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
Signed-off-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/mpt2sas/mpt2sas_base.h

index ffd85c511c8e2925314d27a96f268f922d1db3aa..5e24e7e7371404e8b6f723b2e8d762a3b4511659 100644 (file)
@@ -155,7 +155,7 @@ _base_fault_reset_work(struct work_struct *work)
        struct task_struct *p;
 
        spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       if (ioc->shost_recovery)
+       if (ioc->shost_recovery || ioc->pci_error_recovery)
                goto rearm_timer;
        spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
@@ -164,6 +164,20 @@ _base_fault_reset_work(struct work_struct *work)
                printk(MPT2SAS_INFO_FMT "%s : SAS host is non-operational !!!!\n",
                        ioc->name, __func__);
 
+               /* It may be possible that EEH recovery can resolve some of
+                * pci bus failure issues rather removing the dead ioc function
+                * by considering controller is in a non-operational state. So
+                * here priority is given to the EEH recovery. If it doesn't
+                * not resolve this issue, mpt2sas driver will consider this
+                * controller to non-operational state and remove the dead ioc
+                * function.
+                */
+               if (ioc->non_operational_loop++ < 5) {
+                       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock,
+                                                        flags);
+                       goto rearm_timer;
+               }
+
                /*
                 * Call _scsih_flush_pending_cmds callback so that we flush all
                 * pending commands back to OS. This call is required to aovid
@@ -193,6 +207,8 @@ _base_fault_reset_work(struct work_struct *work)
                return; /* don't rearm timer */
        }
 
+       ioc->non_operational_loop = 0;
+
        if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
                rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
                    FORCE_BIG_HAMMER);
@@ -4386,6 +4402,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
        if (missing_delay[0] != -1 && missing_delay[1] != -1)
                _base_update_missing_delay(ioc, missing_delay[0],
                    missing_delay[1]);
+       ioc->non_operational_loop = 0;
 
        return 0;
 
index 543d8d637479d4a983a80174412fe0f2f05e990a..c6ee7aad7501cd274b02071cdba69d70fafe6281 100644 (file)
@@ -835,6 +835,7 @@ struct MPT2SAS_ADAPTER {
        u16             cpu_msix_table_sz;
        u32             ioc_reset_count;
        MPT2SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
+       u32             non_operational_loop;
 
        /* internal commands, callback index */
        u8              scsi_io_cb_idx;