[SCSI] ipr: possible irq lock inversion dependency detected
authorwenxiong@linux.vnet.ibm.com <wenxiong@linux.vnet.ibm.com>
Fri, 24 May 2013 14:59:13 +0000 (09:59 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 26 Jun 2013 17:48:38 +0000 (10:48 -0700)
When enable lockdep, seeing "possible irq lock inversion dependency detected"
error. This patch fixes the issue.

Signed-off-by: Wen Xiong <wenxiong@linux.vnet.ibm.com>
Acked-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/ipr.c

index 6c4cedb44c075fba2ba81999e187e4587901b5f0..a87767f73913ddb0b329db0b2d7c40db2fed319b 100644 (file)
@@ -9392,7 +9392,7 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
        void __iomem *ipr_regs;
        int rc = PCIBIOS_SUCCESSFUL;
        volatile u32 mask, uproc, interrupts;
-       unsigned long lock_flags;
+       unsigned long lock_flags, driver_lock_flags;
 
        ENTER;
 
@@ -9615,9 +9615,9 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
        } else
                ioa_cfg->reset = ipr_reset_start_bist;
 
-       spin_lock(&ipr_driver_lock);
+       spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags);
        list_add_tail(&ioa_cfg->queue, &ipr_ioa_head);
-       spin_unlock(&ipr_driver_lock);
+       spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags);
 
        LEAVE;
 out:
@@ -9700,6 +9700,7 @@ static void __ipr_remove(struct pci_dev *pdev)
        unsigned long host_lock_flags = 0;
        struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
        int i;
+       unsigned long driver_lock_flags;
        ENTER;
 
        spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
@@ -9723,9 +9724,9 @@ static void __ipr_remove(struct pci_dev *pdev)
        INIT_LIST_HEAD(&ioa_cfg->used_res_q);
        spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
 
-       spin_lock(&ipr_driver_lock);
+       spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags);
        list_del(&ioa_cfg->queue);
-       spin_unlock(&ipr_driver_lock);
+       spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags);
 
        if (ioa_cfg->sdt_state == ABORT_DUMP)
                ioa_cfg->sdt_state = WAIT_FOR_DUMP;
@@ -9991,12 +9992,12 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf)
 {
        struct ipr_cmnd *ipr_cmd;
        struct ipr_ioa_cfg *ioa_cfg;
-       unsigned long flags = 0;
+       unsigned long flags = 0, driver_lock_flags;
 
        if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
                return NOTIFY_DONE;
 
-       spin_lock(&ipr_driver_lock);
+       spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags);
 
        list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) {
                spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
@@ -10014,7 +10015,7 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf)
                ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
                spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
        }
-       spin_unlock(&ipr_driver_lock);
+       spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags);
 
        return NOTIFY_OK;
 }