diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-02-26 13:43:36 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-03-01 14:36:56 -0500 |
commit | 931ef163309ee955611f287dc65248b39a65fc9d (patch) | |
tree | 5bf19b5c5cc9bc73db3cd575335413a653c58cc6 | |
parent | 949338e35131c551f7bf54f48a2e3a227af6721b (diff) |
cpu/hotplug: Unpark smpboot threads from the state machine
Handle the smpboot threads in the state machine.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-arch@vger.kernel.org
Cc: Rik van Riel <riel@redhat.com>
Cc: Rafael Wysocki <rafael.j.wysocki@intel.com>
Cc: "Srivatsa S. Bhat" <srivatsa@mit.edu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: http://lkml.kernel.org/r/20160226182341.295777684@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | include/linux/cpu.h | 7 | ||||
-rw-r--r-- | include/linux/cpuhotplug.h | 1 | ||||
-rw-r--r-- | init/main.c | 1 | ||||
-rw-r--r-- | kernel/cpu.c | 39 | ||||
-rw-r--r-- | kernel/smpboot.c | 6 | ||||
-rw-r--r-- | kernel/smpboot.h | 4 |
6 files changed, 13 insertions, 45 deletions
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 78989f20420f..83f35767016d 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -78,7 +78,7 @@ enum { | |||
78 | /* migration should happen before other stuff but after perf */ | 78 | /* migration should happen before other stuff but after perf */ |
79 | CPU_PRI_PERF = 20, | 79 | CPU_PRI_PERF = 20, |
80 | CPU_PRI_MIGRATION = 10, | 80 | CPU_PRI_MIGRATION = 10, |
81 | CPU_PRI_SMPBOOT = 9, | 81 | |
82 | /* bring up workqueues before normal notifiers and down after */ | 82 | /* bring up workqueues before normal notifiers and down after */ |
83 | CPU_PRI_WORKQUEUE_UP = 5, | 83 | CPU_PRI_WORKQUEUE_UP = 5, |
84 | CPU_PRI_WORKQUEUE_DOWN = -5, | 84 | CPU_PRI_WORKQUEUE_DOWN = -5, |
@@ -172,7 +172,6 @@ static inline void __unregister_cpu_notifier(struct notifier_block *nb) | |||
172 | } | 172 | } |
173 | #endif | 173 | #endif |
174 | 174 | ||
175 | void smpboot_thread_init(void); | ||
176 | int cpu_up(unsigned int cpu); | 175 | int cpu_up(unsigned int cpu); |
177 | void notify_cpu_starting(unsigned int cpu); | 176 | void notify_cpu_starting(unsigned int cpu); |
178 | extern void cpu_maps_update_begin(void); | 177 | extern void cpu_maps_update_begin(void); |
@@ -221,10 +220,6 @@ static inline void cpu_notifier_register_done(void) | |||
221 | { | 220 | { |
222 | } | 221 | } |
223 | 222 | ||
224 | static inline void smpboot_thread_init(void) | ||
225 | { | ||
226 | } | ||
227 | |||
228 | #endif /* CONFIG_SMP */ | 223 | #endif /* CONFIG_SMP */ |
229 | extern struct bus_type cpu_subsys; | 224 | extern struct bus_type cpu_subsys; |
230 | 225 | ||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 2f2e5d9711c4..38679106fddd 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h | |||
@@ -11,6 +11,7 @@ enum cpuhp_state { | |||
11 | CPUHP_AP_ONLINE, | 11 | CPUHP_AP_ONLINE, |
12 | CPUHP_TEARDOWN_CPU, | 12 | CPUHP_TEARDOWN_CPU, |
13 | CPUHP_CPU_SET_ACTIVE, | 13 | CPUHP_CPU_SET_ACTIVE, |
14 | CPUHP_SMPBOOT_THREADS, | ||
14 | CPUHP_NOTIFY_ONLINE, | 15 | CPUHP_NOTIFY_ONLINE, |
15 | CPUHP_ONLINE_DYN, | 16 | CPUHP_ONLINE_DYN, |
16 | CPUHP_ONLINE_DYN_END = CPUHP_ONLINE_DYN + 30, | 17 | CPUHP_ONLINE_DYN_END = CPUHP_ONLINE_DYN + 30, |
diff --git a/init/main.c b/init/main.c index c2ea72362ee3..55563fd36be3 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -388,7 +388,6 @@ static noinline void __init_refok rest_init(void) | |||
388 | int pid; | 388 | int pid; |
389 | 389 | ||
390 | rcu_scheduler_starting(); | 390 | rcu_scheduler_starting(); |
391 | smpboot_thread_init(); | ||
392 | /* | 391 | /* |
393 | * We need to spawn init first so that it obtains pid 1, however | 392 | * We need to spawn init first so that it obtains pid 1, however |
394 | * the init task will end up wanting to create kthreads, which, if | 393 | * the init task will end up wanting to create kthreads, which, if |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 65e34d34ca93..3ec86bc414b7 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -481,8 +481,6 @@ static int takedown_cpu(unsigned int cpu) | |||
481 | else | 481 | else |
482 | synchronize_rcu(); | 482 | synchronize_rcu(); |
483 | 483 | ||
484 | smpboot_park_threads(cpu); | ||
485 | |||
486 | /* | 484 | /* |
487 | * Prevent irq alloc/free while the dying cpu reorganizes the | 485 | * Prevent irq alloc/free while the dying cpu reorganizes the |
488 | * interrupt affinities. | 486 | * interrupt affinities. |
@@ -612,38 +610,6 @@ int cpu_down(unsigned int cpu) | |||
612 | EXPORT_SYMBOL(cpu_down); | 610 | EXPORT_SYMBOL(cpu_down); |
613 | #endif /*CONFIG_HOTPLUG_CPU*/ | 611 | #endif /*CONFIG_HOTPLUG_CPU*/ |
614 | 612 | ||
615 | /* | ||
616 | * Unpark per-CPU smpboot kthreads at CPU-online time. | ||
617 | */ | ||
618 | static int smpboot_thread_call(struct notifier_block *nfb, | ||
619 | unsigned long action, void *hcpu) | ||
620 | { | ||
621 | int cpu = (long)hcpu; | ||
622 | |||
623 | switch (action & ~CPU_TASKS_FROZEN) { | ||
624 | |||
625 | case CPU_DOWN_FAILED: | ||
626 | case CPU_ONLINE: | ||
627 | smpboot_unpark_threads(cpu); | ||
628 | break; | ||
629 | |||
630 | default: | ||
631 | break; | ||
632 | } | ||
633 | |||
634 | return NOTIFY_OK; | ||
635 | } | ||
636 | |||
637 | static struct notifier_block smpboot_thread_notifier = { | ||
638 | .notifier_call = smpboot_thread_call, | ||
639 | .priority = CPU_PRI_SMPBOOT, | ||
640 | }; | ||
641 | |||
642 | void smpboot_thread_init(void) | ||
643 | { | ||
644 | register_cpu_notifier(&smpboot_thread_notifier); | ||
645 | } | ||
646 | |||
647 | /** | 613 | /** |
648 | * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers | 614 | * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers |
649 | * @cpu: cpu that just started | 615 | * @cpu: cpu that just started |
@@ -959,6 +925,11 @@ static struct cpuhp_step cpuhp_bp_states[] = { | |||
959 | .startup = cpuhp_set_cpu_active, | 925 | .startup = cpuhp_set_cpu_active, |
960 | .teardown = NULL, | 926 | .teardown = NULL, |
961 | }, | 927 | }, |
928 | [CPUHP_SMPBOOT_THREADS] = { | ||
929 | .name = "smpboot:threads", | ||
930 | .startup = smpboot_unpark_threads, | ||
931 | .teardown = smpboot_park_threads, | ||
932 | }, | ||
962 | [CPUHP_NOTIFY_ONLINE] = { | 933 | [CPUHP_NOTIFY_ONLINE] = { |
963 | .name = "notify:online", | 934 | .name = "notify:online", |
964 | .startup = notify_online, | 935 | .startup = notify_online, |
diff --git a/kernel/smpboot.c b/kernel/smpboot.c index d264f59bff56..13bc43d1fb22 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c | |||
@@ -226,7 +226,7 @@ static void smpboot_unpark_thread(struct smp_hotplug_thread *ht, unsigned int cp | |||
226 | kthread_unpark(tsk); | 226 | kthread_unpark(tsk); |
227 | } | 227 | } |
228 | 228 | ||
229 | void smpboot_unpark_threads(unsigned int cpu) | 229 | int smpboot_unpark_threads(unsigned int cpu) |
230 | { | 230 | { |
231 | struct smp_hotplug_thread *cur; | 231 | struct smp_hotplug_thread *cur; |
232 | 232 | ||
@@ -235,6 +235,7 @@ void smpboot_unpark_threads(unsigned int cpu) | |||
235 | if (cpumask_test_cpu(cpu, cur->cpumask)) | 235 | if (cpumask_test_cpu(cpu, cur->cpumask)) |
236 | smpboot_unpark_thread(cur, cpu); | 236 | smpboot_unpark_thread(cur, cpu); |
237 | mutex_unlock(&smpboot_threads_lock); | 237 | mutex_unlock(&smpboot_threads_lock); |
238 | return 0; | ||
238 | } | 239 | } |
239 | 240 | ||
240 | static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu) | 241 | static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu) |
@@ -245,7 +246,7 @@ static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu) | |||
245 | kthread_park(tsk); | 246 | kthread_park(tsk); |
246 | } | 247 | } |
247 | 248 | ||
248 | void smpboot_park_threads(unsigned int cpu) | 249 | int smpboot_park_threads(unsigned int cpu) |
249 | { | 250 | { |
250 | struct smp_hotplug_thread *cur; | 251 | struct smp_hotplug_thread *cur; |
251 | 252 | ||
@@ -253,6 +254,7 @@ void smpboot_park_threads(unsigned int cpu) | |||
253 | list_for_each_entry_reverse(cur, &hotplug_threads, list) | 254 | list_for_each_entry_reverse(cur, &hotplug_threads, list) |
254 | smpboot_park_thread(cur, cpu); | 255 | smpboot_park_thread(cur, cpu); |
255 | mutex_unlock(&smpboot_threads_lock); | 256 | mutex_unlock(&smpboot_threads_lock); |
257 | return 0; | ||
256 | } | 258 | } |
257 | 259 | ||
258 | static void smpboot_destroy_threads(struct smp_hotplug_thread *ht) | 260 | static void smpboot_destroy_threads(struct smp_hotplug_thread *ht) |
diff --git a/kernel/smpboot.h b/kernel/smpboot.h index 72415a0eb955..6b5f02017be3 100644 --- a/kernel/smpboot.h +++ b/kernel/smpboot.h | |||
@@ -14,7 +14,7 @@ static inline void idle_threads_init(void) { } | |||
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | int smpboot_create_threads(unsigned int cpu); | 16 | int smpboot_create_threads(unsigned int cpu); |
17 | void smpboot_park_threads(unsigned int cpu); | 17 | int smpboot_park_threads(unsigned int cpu); |
18 | void smpboot_unpark_threads(unsigned int cpu); | 18 | int smpboot_unpark_threads(unsigned int cpu); |
19 | 19 | ||
20 | #endif | 20 | #endif |