]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
c26c42e48bb9d6ec965a9d15bfec973949941291
[thirdparty/kernel/stable-queue.git] /
1 From b4606f2165153833247823e8c04c5e88cb3d298b Mon Sep 17 00:00:00 2001
2 From: Ian Campbell <ian.campbell@citrix.com>
3 Date: Tue, 1 Dec 2009 11:47:15 +0000
4 Subject: xen: explicitly create/destroy stop_machine workqueues outside suspend/resume region.
5
6 From: Ian Campbell <ian.campbell@citrix.com>
7
8 commit b4606f2165153833247823e8c04c5e88cb3d298b upstream.
9
10 I have observed cases where the implicit stop_machine_destroy() done by
11 stop_machine() hangs while destroying the workqueues, specifically in
12 kthread_stop(). This seems to be because timer ticks are not restarted
13 until after stop_machine() returns.
14
15 Fortunately stop_machine provides a facility to pre-create/post-destroy
16 the workqueues so use this to ensure that workqueues are only destroyed
17 after everything is really up and running again.
18
19 I only actually observed this failure with 2.6.30. It seems that newer
20 kernels are somehow more robust against doing kthread_stop() without timer
21 interrupts (I tried some backports of some likely looking candidates but
22 did not track down the commit which added this robustness). However this
23 change seems like a reasonable belt&braces thing to do.
24
25 Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
26 Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
28
29 ---
30 drivers/xen/manage.c | 12 +++++++++++-
31 1 file changed, 11 insertions(+), 1 deletion(-)
32
33 --- a/drivers/xen/manage.c
34 +++ b/drivers/xen/manage.c
35 @@ -79,6 +79,12 @@ static void do_suspend(void)
36
37 shutting_down = SHUTDOWN_SUSPEND;
38
39 + err = stop_machine_create();
40 + if (err) {
41 + printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err);
42 + goto out;
43 + }
44 +
45 #ifdef CONFIG_PREEMPT
46 /* If the kernel is preemptible, we need to freeze all the processes
47 to prevent them from being in the middle of a pagetable update
48 @@ -86,7 +92,7 @@ static void do_suspend(void)
49 err = freeze_processes();
50 if (err) {
51 printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
52 - goto out;
53 + goto out_destroy_sm;
54 }
55 #endif
56
57 @@ -129,7 +135,11 @@ out_resume:
58 out_thaw:
59 #ifdef CONFIG_PREEMPT
60 thaw_processes();
61 +
62 +out_destroy_sm:
63 #endif
64 + stop_machine_destroy();
65 +
66 out:
67 shutting_down = SHUTDOWN_INVALID;
68 }