summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.25/0047-workqueue-perform-cpu-down-operations-from-low-prior.patch
diff options
context:
space:
mode:
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.patch120
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 @@
1From 47ba7731c120a3ed09336d18b85493bd85d926f2 Mon Sep 17 00:00:00 2001
2From: Tejun Heo <tj@kernel.org>
3Date: Tue, 17 Jul 2012 12:39:26 -0700
4Subject: [PATCH 47/73] workqueue: perform cpu down operations from low
5 priority cpu_notifier()
6
7commit 6575820221f7a4dd6eadecf7bf83cdd154335eda upstream.
8
9Currently, all workqueue cpu hotplug operations run off
10CPU_PRI_WORKQUEUE which is higher than normal notifiers. This is to
11ensure that workqueue is up and running while bringing up a CPU before
12other notifiers try to use workqueue on the CPU.
13
14Per-cpu workqueues are supposed to remain working and bound to the CPU
15for normal CPU_DOWN_PREPARE notifiers. This holds mostly true even
16with workqueue offlining running with higher priority because
17workqueue CPU_DOWN_PREPARE only creates a bound trustee thread which
18runs the per-cpu workqueue without concurrency management without
19explicitly detaching the existing workers.
20
21However, if the trustee needs to create new workers, it creates
22unbound workers which may wander off to other CPUs while
23CPU_DOWN_PREPARE notifiers are in progress. Furthermore, if the CPU
24down is cancelled, the per-CPU workqueue may end up with workers which
25aren't bound to the CPU.
26
27While reliably reproducible with a convoluted artificial test-case
28involving scheduling and flushing CPU burning work items from CPU down
29notifiers, this isn't very likely to happen in the wild, and, even
30when it happens, the effects are likely to be hidden by the following
31successful CPU down.
32
33Fix it by using different priorities for up and down notifiers - high
34priority for up operations and low priority for down operations.
35
36Workqueue cpu hotplug operations will soon go through further cleanup.
37
38Signed-off-by: Tejun Heo <tj@kernel.org>
39Acked-by: "Rafael J. Wysocki" <rjw@sisk.pl>
40Signed-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
46diff --git a/include/linux/cpu.h b/include/linux/cpu.h
47index 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 */
62diff --git a/kernel/workqueue.c b/kernel/workqueue.c
63index 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--
1191.7.7.6
120