diff options
Diffstat (limited to 'drivers/xen/manage.c')
-rw-r--r-- | drivers/xen/manage.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 10d03d7931c4..2ac4440e7b08 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | #include <linux/err.h> | 5 | #include <linux/err.h> |
6 | #include <linux/slab.h> | ||
6 | #include <linux/reboot.h> | 7 | #include <linux/reboot.h> |
7 | #include <linux/sysrq.h> | 8 | #include <linux/sysrq.h> |
8 | #include <linux/stop_machine.h> | 9 | #include <linux/stop_machine.h> |
@@ -43,7 +44,6 @@ static int xen_suspend(void *data) | |||
43 | if (err) { | 44 | if (err) { |
44 | printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", | 45 | printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", |
45 | err); | 46 | err); |
46 | dpm_resume_noirq(PMSG_RESUME); | ||
47 | return err; | 47 | return err; |
48 | } | 48 | } |
49 | 49 | ||
@@ -69,7 +69,6 @@ static int xen_suspend(void *data) | |||
69 | } | 69 | } |
70 | 70 | ||
71 | sysdev_resume(); | 71 | sysdev_resume(); |
72 | dpm_resume_noirq(PMSG_RESUME); | ||
73 | 72 | ||
74 | return 0; | 73 | return 0; |
75 | } | 74 | } |
@@ -81,6 +80,12 @@ static void do_suspend(void) | |||
81 | 80 | ||
82 | shutting_down = SHUTDOWN_SUSPEND; | 81 | shutting_down = SHUTDOWN_SUSPEND; |
83 | 82 | ||
83 | err = stop_machine_create(); | ||
84 | if (err) { | ||
85 | printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err); | ||
86 | goto out; | ||
87 | } | ||
88 | |||
84 | #ifdef CONFIG_PREEMPT | 89 | #ifdef CONFIG_PREEMPT |
85 | /* If the kernel is preemptible, we need to freeze all the processes | 90 | /* If the kernel is preemptible, we need to freeze all the processes |
86 | to prevent them from being in the middle of a pagetable update | 91 | to prevent them from being in the middle of a pagetable update |
@@ -88,14 +93,14 @@ static void do_suspend(void) | |||
88 | err = freeze_processes(); | 93 | err = freeze_processes(); |
89 | if (err) { | 94 | if (err) { |
90 | printk(KERN_ERR "xen suspend: freeze failed %d\n", err); | 95 | printk(KERN_ERR "xen suspend: freeze failed %d\n", err); |
91 | return; | 96 | goto out_destroy_sm; |
92 | } | 97 | } |
93 | #endif | 98 | #endif |
94 | 99 | ||
95 | err = dpm_suspend_start(PMSG_SUSPEND); | 100 | err = dpm_suspend_start(PMSG_SUSPEND); |
96 | if (err) { | 101 | if (err) { |
97 | printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); | 102 | printk(KERN_ERR "xen suspend: dpm_suspend_start %d\n", err); |
98 | goto out; | 103 | goto out_thaw; |
99 | } | 104 | } |
100 | 105 | ||
101 | printk(KERN_DEBUG "suspending xenstore...\n"); | 106 | printk(KERN_DEBUG "suspending xenstore...\n"); |
@@ -104,32 +109,39 @@ static void do_suspend(void) | |||
104 | err = dpm_suspend_noirq(PMSG_SUSPEND); | 109 | err = dpm_suspend_noirq(PMSG_SUSPEND); |
105 | if (err) { | 110 | if (err) { |
106 | printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); | 111 | printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); |
107 | goto resume_devices; | 112 | goto out_resume; |
108 | } | 113 | } |
109 | 114 | ||
110 | err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); | 115 | err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); |
116 | |||
117 | dpm_resume_noirq(PMSG_RESUME); | ||
118 | |||
111 | if (err) { | 119 | if (err) { |
112 | printk(KERN_ERR "failed to start xen_suspend: %d\n", err); | 120 | printk(KERN_ERR "failed to start xen_suspend: %d\n", err); |
113 | goto out; | 121 | cancelled = 1; |
114 | } | 122 | } |
115 | 123 | ||
124 | out_resume: | ||
116 | if (!cancelled) { | 125 | if (!cancelled) { |
117 | xen_arch_resume(); | 126 | xen_arch_resume(); |
118 | xs_resume(); | 127 | xs_resume(); |
119 | } else | 128 | } else |
120 | xs_suspend_cancel(); | 129 | xs_suspend_cancel(); |
121 | 130 | ||
122 | dpm_resume_noirq(PMSG_RESUME); | ||
123 | |||
124 | resume_devices: | ||
125 | dpm_resume_end(PMSG_RESUME); | 131 | dpm_resume_end(PMSG_RESUME); |
126 | 132 | ||
127 | /* Make sure timer events get retriggered on all CPUs */ | 133 | /* Make sure timer events get retriggered on all CPUs */ |
128 | clock_was_set(); | 134 | clock_was_set(); |
129 | out: | 135 | |
136 | out_thaw: | ||
130 | #ifdef CONFIG_PREEMPT | 137 | #ifdef CONFIG_PREEMPT |
131 | thaw_processes(); | 138 | thaw_processes(); |
139 | |||
140 | out_destroy_sm: | ||
132 | #endif | 141 | #endif |
142 | stop_machine_destroy(); | ||
143 | |||
144 | out: | ||
133 | shutting_down = SHUTDOWN_INVALID; | 145 | shutting_down = SHUTDOWN_INVALID; |
134 | } | 146 | } |
135 | #endif /* CONFIG_PM_SLEEP */ | 147 | #endif /* CONFIG_PM_SLEEP */ |