On Wed, Oct 15, 2014 at 4:34 PM, Wilmer van der Gaast <[email protected]> wrote:
>
> Is there anything I can do now to find out why your change is causing my
> machine to crash?

Can you please try attached patch? that should workaround the problem.

as some driver is using pci_enable_device in .resume instead of
pci_renable_device....

We should skip the pci_enable_bridge in those pci_enable_device to avoid
contention between async device_resume.

Thanks

Yinghai
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 625a4ac..6567831 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1266,7 +1266,6 @@ static void pci_enable_bridge(struct pci_dev *dev)
 
 static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
 {
-	struct pci_dev *bridge;
 	int err;
 	int i, bars = 0;
 
@@ -1285,9 +1284,19 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
 	if (atomic_inc_return(&dev->enable_cnt) > 1)
 		return 0;		/* already enabled */
 
-	bridge = pci_upstream_bridge(dev);
-	if (bridge)
-		pci_enable_bridge(bridge);
+	/*
+	 * Do not enable bridge again on resume path, as parent state
+	 * get restored before.
+	 * Also could avoid delay between different async resume.
+	 */
+	if (!(dev->dev.power.is_suspended ||
+	      dev->dev.power.is_noirq_suspended ||
+	      dev->dev.power.is_late_suspended)) {
+		struct pci_dev *bridge = pci_upstream_bridge(dev);
+
+		if (bridge)
+			pci_enable_bridge(bridge);
+	}
 
 	/* only skip sriov related */
 	for (i = 0; i <= PCI_ROM_RESOURCE; i++)

Reply via email to