Skip to content

Commit 1a06d01

Browse files
dcuiliuw
authored andcommitted
Drivers: hv: vmbus: Fix Suspend-to-Idle for Generation-2 VM
Before the hibernation patchset (e.g. f53335e), in a Generation-2 Linux VM on Hyper-V, the user can run "echo freeze > /sys/power/state" to freeze the system, i.e. Suspend-to-Idle. The user can press the keyboard or move the mouse to wake up the VM. With the hibernation patchset, Linux VM on Hyper-V can hibernate to disk, but Suspend-to-Idle is broken: when the synthetic keyboard/mouse are suspended, there is no way to wake up the VM. Fix the issue by not suspending and resuming the vmbus devices upon Suspend-to-Idle. Fixes: f53335e ("Drivers: hv: vmbus: Suspend/resume the vmbus itself for hibernation") Cc: [email protected] Reviewed-by: Michael Kelley <[email protected]> Signed-off-by: Dexuan Cui <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Wei Liu <[email protected]>
1 parent f3a99e7 commit 1a06d01

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

drivers/hv/vmbus_drv.c

+34-9
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device)
978978

979979
return drv->resume(dev);
980980
}
981+
#else
982+
#define vmbus_suspend NULL
983+
#define vmbus_resume NULL
981984
#endif /* CONFIG_PM_SLEEP */
982985

983986
/*
@@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device)
9971000
}
9981001

9991002
/*
1000-
* Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
1001-
* SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm.
1003+
* Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm.
1004+
*
1005+
* suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we
1006+
* shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there
1007+
* is no way to wake up a Generation-2 VM.
1008+
*
1009+
* The other 4 ops are for hibernation.
10021010
*/
1011+
10031012
static const struct dev_pm_ops vmbus_pm = {
1004-
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume)
1013+
.suspend_noirq = NULL,
1014+
.resume_noirq = NULL,
1015+
.freeze_noirq = vmbus_suspend,
1016+
.thaw_noirq = vmbus_resume,
1017+
.poweroff_noirq = vmbus_suspend,
1018+
.restore_noirq = vmbus_resume,
10051019
};
10061020

10071021
/* The one and only one */
@@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev)
22812295

22822296
return 0;
22832297
}
2298+
#else
2299+
#define vmbus_bus_suspend NULL
2300+
#define vmbus_bus_resume NULL
22842301
#endif /* CONFIG_PM_SLEEP */
22852302

22862303
static const struct acpi_device_id vmbus_acpi_device_ids[] = {
@@ -2291,16 +2308,24 @@ static const struct acpi_device_id vmbus_acpi_device_ids[] = {
22912308
MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
22922309

22932310
/*
2294-
* Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
2295-
* SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the
2296-
* "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the
2297-
* pci "noirq" restore callback runs before "non-noirq" callbacks (see
2311+
* Note: we must use the "no_irq" ops, otherwise hibernation can not work with
2312+
* PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in
2313+
* the resume path, the pci "noirq" restore op runs before "non-noirq" op (see
22982314
* resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() ->
22992315
* dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's
2300-
* resume callback must also run via the "noirq" callbacks.
2316+
* resume callback must also run via the "noirq" ops.
2317+
*
2318+
* Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment
2319+
* earlier in this file before vmbus_pm.
23012320
*/
2321+
23022322
static const struct dev_pm_ops vmbus_bus_pm = {
2303-
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume)
2323+
.suspend_noirq = NULL,
2324+
.resume_noirq = NULL,
2325+
.freeze_noirq = vmbus_bus_suspend,
2326+
.thaw_noirq = vmbus_bus_resume,
2327+
.poweroff_noirq = vmbus_bus_suspend,
2328+
.restore_noirq = vmbus_bus_resume
23042329
};
23052330

23062331
static struct acpi_driver vmbus_acpi_driver = {

0 commit comments

Comments
 (0)