Re: Machine crashes right *after* ~successful resume

From: Yinghai Lu
Date: Thu Oct 16 2014 - 00:32:59 EST


On Wed, Oct 15, 2014 at 4:34 PM, Wilmer van der Gaast <wilmer@xxxxxxxxx> 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++)