summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-02-26 13:43:36 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-03-01 14:36:56 -0500
commit931ef163309ee955611f287dc65248b39a65fc9d (patch)
tree5bf19b5c5cc9bc73db3cd575335413a653c58cc6
parent949338e35131c551f7bf54f48a2e3a227af6721b (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.h7
-rw-r--r--include/linux/cpuhotplug.h1
-rw-r--r--init/main.c1
-rw-r--r--kernel/cpu.c39
-rw-r--r--kernel/smpboot.c6
-rw-r--r--kernel/smpboot.h4
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
175void smpboot_thread_init(void);
176int cpu_up(unsigned int cpu); 175int cpu_up(unsigned int cpu);
177void notify_cpu_starting(unsigned int cpu); 176void notify_cpu_starting(unsigned int cpu);
178extern void cpu_maps_update_begin(void); 177extern void cpu_maps_update_begin(void);
@@ -221,10 +220,6 @@ static inline void cpu_notifier_register_done(void)
221{ 220{
222} 221}
223 222
224static inline void smpboot_thread_init(void)
225{
226}
227
228#endif /* CONFIG_SMP */ 223#endif /* CONFIG_SMP */
229extern struct bus_type cpu_subsys; 224extern 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)
612EXPORT_SYMBOL(cpu_down); 610EXPORT_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 */
618static 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
637static struct notifier_block smpboot_thread_notifier = {
638 .notifier_call = smpboot_thread_call,
639 .priority = CPU_PRI_SMPBOOT,
640};
641
642void 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
229void smpboot_unpark_threads(unsigned int cpu) 229int 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
240static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu) 241static 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
248void smpboot_park_threads(unsigned int cpu) 249int 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
258static void smpboot_destroy_threads(struct smp_hotplug_thread *ht) 260static 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
16int smpboot_create_threads(unsigned int cpu); 16int smpboot_create_threads(unsigned int cpu);
17void smpboot_park_threads(unsigned int cpu); 17int smpboot_park_threads(unsigned int cpu);
18void smpboot_unpark_threads(unsigned int cpu); 18int smpboot_unpark_threads(unsigned int cpu);
19 19
20#endif 20#endif