diff options
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.25/0047-workqueue-perform-cpu-down-operations-from-low-prior.patch')
-rw-r--r-- | recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.25/0047-workqueue-perform-cpu-down-operations-from-low-prior.patch | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.25/0047-workqueue-perform-cpu-down-operations-from-low-prior.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.25/0047-workqueue-perform-cpu-down-operations-from-low-prior.patch new file mode 100644 index 00000000..772eafb5 --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.25/0047-workqueue-perform-cpu-down-operations-from-low-prior.patch | |||
@@ -0,0 +1,120 @@ | |||
1 | From 47ba7731c120a3ed09336d18b85493bd85d926f2 Mon Sep 17 00:00:00 2001 | ||
2 | From: Tejun Heo <tj@kernel.org> | ||
3 | Date: Tue, 17 Jul 2012 12:39:26 -0700 | ||
4 | Subject: [PATCH 47/73] workqueue: perform cpu down operations from low | ||
5 | priority cpu_notifier() | ||
6 | |||
7 | commit 6575820221f7a4dd6eadecf7bf83cdd154335eda upstream. | ||
8 | |||
9 | Currently, all workqueue cpu hotplug operations run off | ||
10 | CPU_PRI_WORKQUEUE which is higher than normal notifiers. This is to | ||
11 | ensure that workqueue is up and running while bringing up a CPU before | ||
12 | other notifiers try to use workqueue on the CPU. | ||
13 | |||
14 | Per-cpu workqueues are supposed to remain working and bound to the CPU | ||
15 | for normal CPU_DOWN_PREPARE notifiers. This holds mostly true even | ||
16 | with workqueue offlining running with higher priority because | ||
17 | workqueue CPU_DOWN_PREPARE only creates a bound trustee thread which | ||
18 | runs the per-cpu workqueue without concurrency management without | ||
19 | explicitly detaching the existing workers. | ||
20 | |||
21 | However, if the trustee needs to create new workers, it creates | ||
22 | unbound workers which may wander off to other CPUs while | ||
23 | CPU_DOWN_PREPARE notifiers are in progress. Furthermore, if the CPU | ||
24 | down is cancelled, the per-CPU workqueue may end up with workers which | ||
25 | aren't bound to the CPU. | ||
26 | |||
27 | While reliably reproducible with a convoluted artificial test-case | ||
28 | involving scheduling and flushing CPU burning work items from CPU down | ||
29 | notifiers, this isn't very likely to happen in the wild, and, even | ||
30 | when it happens, the effects are likely to be hidden by the following | ||
31 | successful CPU down. | ||
32 | |||
33 | Fix it by using different priorities for up and down notifiers - high | ||
34 | priority for up operations and low priority for down operations. | ||
35 | |||
36 | Workqueue cpu hotplug operations will soon go through further cleanup. | ||
37 | |||
38 | Signed-off-by: Tejun Heo <tj@kernel.org> | ||
39 | Acked-by: "Rafael J. Wysocki" <rjw@sisk.pl> | ||
40 | Signed-off-by: Ben Hutchings <ben@decadent.org.uk> | ||
41 | --- | ||
42 | include/linux/cpu.h | 5 +++-- | ||
43 | kernel/workqueue.c | 38 +++++++++++++++++++++++++++++++++++++- | ||
44 | 2 files changed, 40 insertions(+), 3 deletions(-) | ||
45 | |||
46 | diff --git a/include/linux/cpu.h b/include/linux/cpu.h | ||
47 | index 6cb60fd..c692acc 100644 | ||
48 | --- a/include/linux/cpu.h | ||
49 | +++ b/include/linux/cpu.h | ||
50 | @@ -66,8 +66,9 @@ enum { | ||
51 | /* migration should happen before other stuff but after perf */ | ||
52 | CPU_PRI_PERF = 20, | ||
53 | CPU_PRI_MIGRATION = 10, | ||
54 | - /* prepare workqueues for other notifiers */ | ||
55 | - CPU_PRI_WORKQUEUE = 5, | ||
56 | + /* bring up workqueues before normal notifiers and down after */ | ||
57 | + CPU_PRI_WORKQUEUE_UP = 5, | ||
58 | + CPU_PRI_WORKQUEUE_DOWN = -5, | ||
59 | }; | ||
60 | |||
61 | #define CPU_ONLINE 0x0002 /* CPU (unsigned)v is up */ | ||
62 | diff --git a/kernel/workqueue.c b/kernel/workqueue.c | ||
63 | index 7947e16..a650bee 100644 | ||
64 | --- a/kernel/workqueue.c | ||
65 | +++ b/kernel/workqueue.c | ||
66 | @@ -3586,6 +3586,41 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | ||
67 | return notifier_from_errno(0); | ||
68 | } | ||
69 | |||
70 | +/* | ||
71 | + * Workqueues should be brought up before normal priority CPU notifiers. | ||
72 | + * This will be registered high priority CPU notifier. | ||
73 | + */ | ||
74 | +static int __devinit workqueue_cpu_up_callback(struct notifier_block *nfb, | ||
75 | + unsigned long action, | ||
76 | + void *hcpu) | ||
77 | +{ | ||
78 | + switch (action & ~CPU_TASKS_FROZEN) { | ||
79 | + case CPU_UP_PREPARE: | ||
80 | + case CPU_UP_CANCELED: | ||
81 | + case CPU_DOWN_FAILED: | ||
82 | + case CPU_ONLINE: | ||
83 | + return workqueue_cpu_callback(nfb, action, hcpu); | ||
84 | + } | ||
85 | + return NOTIFY_OK; | ||
86 | +} | ||
87 | + | ||
88 | +/* | ||
89 | + * Workqueues should be brought down after normal priority CPU notifiers. | ||
90 | + * This will be registered as low priority CPU notifier. | ||
91 | + */ | ||
92 | +static int __devinit workqueue_cpu_down_callback(struct notifier_block *nfb, | ||
93 | + unsigned long action, | ||
94 | + void *hcpu) | ||
95 | +{ | ||
96 | + switch (action & ~CPU_TASKS_FROZEN) { | ||
97 | + case CPU_DOWN_PREPARE: | ||
98 | + case CPU_DYING: | ||
99 | + case CPU_POST_DEAD: | ||
100 | + return workqueue_cpu_callback(nfb, action, hcpu); | ||
101 | + } | ||
102 | + return NOTIFY_OK; | ||
103 | +} | ||
104 | + | ||
105 | #ifdef CONFIG_SMP | ||
106 | |||
107 | struct work_for_cpu { | ||
108 | @@ -3779,7 +3814,8 @@ static int __init init_workqueues(void) | ||
109 | unsigned int cpu; | ||
110 | int i; | ||
111 | |||
112 | - cpu_notifier(workqueue_cpu_callback, CPU_PRI_WORKQUEUE); | ||
113 | + cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP); | ||
114 | + cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN); | ||
115 | |||
116 | /* initialize gcwqs */ | ||
117 | for_each_gcwq_cpu(cpu) { | ||
118 | -- | ||
119 | 1.7.7.6 | ||
120 | |||