xen: use freeze/restore/thaw PM events for suspend/resume/chkpt

Use PM_FREEZE, PM_THAW and PM_RESTORE power events for
suspend/resume/checkpoint functionality, instead of PM_SUSPEND
and PM_RESUME. Use of these pm events fixes the Xen Guest hangup
when taking checkpoints. When a suspend event is cancelled
(while taking checkpoints once/continuously), we use PM_THAW
instead of PM_RESUME. PM_RESTORE is used when suspend is not
cancelled. See Documentation/power/devices.txt and linux/pm.h
for more info about freeze, thaw and restore. The sequence of
pm events in a suspend-resume scenario is shown below.

dpm_suspend_start(PMSG_FREEZE);

dpm_suspend_noirq(PMSG_FREEZE);

sysdev_suspend(PMSG_FREEZE);
cancelled = suspend_hypercall()
sysdev_resume();

dpm_resume_noirq(cancelled ? PMSG_THAW : PMSG_RESTORE);

dpm_resume_end(cancelled ? PMSG_THAW : PMSG_RESTORE);

Acked-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Shriram Rajagopalan <rshriram@cs.ubc.ca>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

authored by Shriram Rajagopalan and committed by Konrad Rzeszutek Wilk b3e96c0c c7853aea

+13 -11
+8 -8
drivers/xen/manage.c
··· 61 61 xen_mm_unpin_all(); 62 62 } 63 63 64 - #ifdef CONFIG_PM_SLEEP 64 + #ifdef CONFIG_HIBERNATION 65 65 static int xen_suspend(void *data) 66 66 { 67 67 struct suspend_info *si = data; ··· 69 69 70 70 BUG_ON(!irqs_disabled()); 71 71 72 - err = sysdev_suspend(PMSG_SUSPEND); 72 + err = sysdev_suspend(PMSG_FREEZE); 73 73 if (err) { 74 74 printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", 75 75 err); ··· 118 118 } 119 119 #endif 120 120 121 - err = dpm_suspend_start(PMSG_SUSPEND); 121 + err = dpm_suspend_start(PMSG_FREEZE); 122 122 if (err) { 123 123 printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); 124 124 goto out_thaw; ··· 127 127 printk(KERN_DEBUG "suspending xenstore...\n"); 128 128 xs_suspend(); 129 129 130 - err = dpm_suspend_noirq(PMSG_SUSPEND); 130 + err = dpm_suspend_noirq(PMSG_FREEZE); 131 131 if (err) { 132 132 printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); 133 133 goto out_resume; ··· 147 147 148 148 err = stop_machine(xen_suspend, &si, cpumask_of(0)); 149 149 150 - dpm_resume_noirq(PMSG_RESUME); 150 + dpm_resume_noirq(si.cancelled ? PMSG_THAW : PMSG_RESTORE); 151 151 152 152 if (err) { 153 153 printk(KERN_ERR "failed to start xen_suspend: %d\n", err); ··· 161 161 } else 162 162 xs_suspend_cancel(); 163 163 164 - dpm_resume_end(PMSG_RESUME); 164 + dpm_resume_end(si.cancelled ? PMSG_THAW : PMSG_RESTORE); 165 165 166 166 /* Make sure timer events get retriggered on all CPUs */ 167 167 clock_was_set(); ··· 173 173 #endif 174 174 shutting_down = SHUTDOWN_INVALID; 175 175 } 176 - #endif /* CONFIG_PM_SLEEP */ 176 + #endif /* CONFIG_HIBERNATION */ 177 177 178 178 struct shutdown_handler { 179 179 const char *command; ··· 202 202 { "poweroff", do_poweroff }, 203 203 { "halt", do_poweroff }, 204 204 { "reboot", do_reboot }, 205 - #ifdef CONFIG_PM_SLEEP 205 + #ifdef CONFIG_HIBERNATION 206 206 { "suspend", do_suspend }, 207 207 #endif 208 208 {NULL, NULL},
+5 -3
drivers/xen/xenbus/xenbus_probe_frontend.c
··· 86 86 }; 87 87 88 88 static const struct dev_pm_ops xenbus_pm_ops = { 89 - .suspend = xenbus_dev_suspend, 90 - .resume = xenbus_dev_resume, 91 - .thaw = xenbus_dev_cancel, 89 + .suspend = xenbus_dev_suspend, 90 + .resume = xenbus_dev_resume, 91 + .freeze = xenbus_dev_suspend, 92 + .thaw = xenbus_dev_cancel, 93 + .restore = xenbus_dev_resume, 92 94 }; 93 95 94 96 static struct xen_bus_type xenbus_frontend = {