> From: Dexuan Cui <decui@xxxxxxxxxxxxx> > Sent: Tuesday, August 13, 2019 6:07 PM > To: lorenzo.pieralisi@xxxxxxx; bhelgaas@xxxxxxxxxx; > linux-pci@xxxxxxxxxxxxxxx > Cc: Michael Kelley <mikelley@xxxxxxxxxxxxx>; linux-hyperv@xxxxxxxxxxxxxxx; > linux-kernel@xxxxxxxxxxxxxxx; driverdev-devel@xxxxxxxxxxxxxxxxxxxxxx; Sasha > Levin <Alexander.Levin@xxxxxxxxxxxxx>; Haiyang Zhang > <haiyangz@xxxxxxxxxxxxx>; KY Srinivasan <kys@xxxxxxxxxxxxx>; > olaf@xxxxxxxxx; apw@xxxxxxxxxxxxx; jasowang@xxxxxxxxxx; vkuznets > <vkuznets@xxxxxxxxxx>; marcelo.cerri@xxxxxxxxxxxxx; Stephen Hemminger > <sthemmin@xxxxxxxxxxxxx>; jackm@xxxxxxxxxxxx; Dexuan Cui > <decui@xxxxxxxxxxxxx> > Subject: [PATCH v2] PCI: PM: Move to D0 before calling > pci_legacy_resume_early() > > > In pci_legacy_suspend_late(), the device state is moved to PCI_UNKNOWN. > > In pci_pm_thaw_noirq(), the state is supposed to be moved back to PCI_D0, > but the current code misses the pci_legacy_resume_early() path, so the > state remains in PCI_UNKNOWN in that path. As a result, in the resume > phase of hibernation, this causes an error for the Mellanox VF driver, > which fails to enable MSI-X because pci_msi_supported() is false due > to dev->current_state != PCI_D0: > > mlx4_core a6d1:00:02.0: Detected virtual function - running in slave mode > mlx4_core a6d1:00:02.0: Sending reset > mlx4_core a6d1:00:02.0: Sending vhcr0 > mlx4_core a6d1:00:02.0: HCA minimum page size:512 > mlx4_core a6d1:00:02.0: Timestamping is not supported in slave mode > mlx4_core a6d1:00:02.0: INTx is not supported in multi-function mode, > aborting > PM: dpm_run_callback(): pci_pm_thaw+0x0/0xd7 returns -95 > PM: Device a6d1:00:02.0 failed to thaw: error -95 > > To be more accurate, the "resume" phase means the "thaw" callbacks which > run before the system enters hibernation: when the user runs the command > "echo disk > /sys/power/state" for hibernation, first the kernel "freezes" > all the devices and creates a hibernation image, then the kernel "thaws" > the devices including the disk/NIC, writes the memory to the disk, and > powers down. This patch fixes the error message for the Mellanox VF driver > in this phase. > > When the system starts again, a fresh kernel starts to run, and when the > kernel detects that a hibernation image was saved, the kernel "quiesces" > the devices, and then "restores" the devices from the saved image. In this > path: > device_resume_noirq() -> ... -> > pci_pm_restore_noirq() -> > pci_pm_default_resume_early() -> > pci_power_up() moves the device states back to PCI_D0. This path is > not broken and doesn't need my patch. > > Signed-off-by: Dexuan Cui <decui@xxxxxxxxxxxxx> > --- > > changes in v2: > Updated the changelog with more details. > > drivers/pci/pci-driver.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c > index 36dbe960306b..27dfc68db9e7 100644 > --- a/drivers/pci/pci-driver.c > +++ b/drivers/pci/pci-driver.c > @@ -1074,15 +1074,16 @@ static int pci_pm_thaw_noirq(struct device *dev) > return error; > } > > - if (pci_has_legacy_pm_support(pci_dev)) > - return pci_legacy_resume_early(dev); > - > /* > * pci_restore_state() requires the device to be in D0 (because of MSI > * restoration among other things), so force it into D0 in case the > * driver's "freeze" callbacks put it into a low-power state directly. > */ > pci_set_power_state(pci_dev, PCI_D0); > + > + if (pci_has_legacy_pm_support(pci_dev)) > + return pci_legacy_resume_early(dev); > + > pci_restore_state(pci_dev); > > if (drv && drv->pm && drv->pm->thaw_noirq) > -- Hi, Lorenzo, Bjorn, Can you please take a look at the v2 ? Thanks, -- Dexuan