diff options
author | Oleg Nesterov <oleg@redhat.com> | 2015-10-09 12:00:49 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-10-20 04:23:55 -0400 |
commit | c00166d87e730088d919814020e96ffed129d0d1 (patch) | |
tree | 89194ca8d10e2c6ceddf203958e65787927d9f9b | |
parent | d8bc853582bfd81a9c08ca6922aeb01570080ccc (diff) |
stop_machine: Kill smp_hotplug_thread->pre_unpark, introduce stop_machine_unpark()
1. Change smpboot_unpark_thread() to check ->selfparking, just
like smpboot_park_thread() does.
2. Introduce stop_machine_unpark() which sets ->enabled and calls
kthread_unpark().
3. Change smpboot_thread_call() and cpu_stop_init() to call
stop_machine_unpark() by hand.
This way:
- IMO the ->selfparking logic becomes more consistent.
- We can kill the smp_hotplug_thread->pre_unpark() method.
- We can easily unpark the stopper thread earlier. Say, we
can move stop_machine_unpark() from smpboot_thread_call()
to sched_cpu_active() as Peter suggests.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: heiko.carstens@de.ibm.com
Link: http://lkml.kernel.org/r/20151009160049.GA10166@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | include/linux/smpboot.h | 4 | ||||
-rw-r--r-- | include/linux/stop_machine.h | 1 | ||||
-rw-r--r-- | kernel/cpu.c | 1 | ||||
-rw-r--r-- | kernel/smpboot.c | 5 | ||||
-rw-r--r-- | kernel/stop_machine.c | 10 |
5 files changed, 13 insertions, 8 deletions
diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h index e6109a6cd8f6..12910cf19869 100644 --- a/include/linux/smpboot.h +++ b/include/linux/smpboot.h | |||
@@ -24,9 +24,6 @@ struct smpboot_thread_data; | |||
24 | * parked (cpu offline) | 24 | * parked (cpu offline) |
25 | * @unpark: Optional unpark function, called when the thread is | 25 | * @unpark: Optional unpark function, called when the thread is |
26 | * unparked (cpu online) | 26 | * unparked (cpu online) |
27 | * @pre_unpark: Optional unpark function, called before the thread is | ||
28 | * unparked (cpu online). This is not guaranteed to be | ||
29 | * called on the target cpu of the thread. Careful! | ||
30 | * @cpumask: Internal state. To update which threads are unparked, | 27 | * @cpumask: Internal state. To update which threads are unparked, |
31 | * call smpboot_update_cpumask_percpu_thread(). | 28 | * call smpboot_update_cpumask_percpu_thread(). |
32 | * @selfparking: Thread is not parked by the park function. | 29 | * @selfparking: Thread is not parked by the park function. |
@@ -42,7 +39,6 @@ struct smp_hotplug_thread { | |||
42 | void (*cleanup)(unsigned int cpu, bool online); | 39 | void (*cleanup)(unsigned int cpu, bool online); |
43 | void (*park)(unsigned int cpu); | 40 | void (*park)(unsigned int cpu); |
44 | void (*unpark)(unsigned int cpu); | 41 | void (*unpark)(unsigned int cpu); |
45 | void (*pre_unpark)(unsigned int cpu); | ||
46 | cpumask_var_t cpumask; | 42 | cpumask_var_t cpumask; |
47 | bool selfparking; | 43 | bool selfparking; |
48 | const char *thread_comm; | 44 | const char *thread_comm; |
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h index 7b76362b381c..0adedca24c5b 100644 --- a/include/linux/stop_machine.h +++ b/include/linux/stop_machine.h | |||
@@ -34,6 +34,7 @@ void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg, | |||
34 | int stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg); | 34 | int stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg); |
35 | int try_stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg); | 35 | int try_stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg); |
36 | void stop_machine_park(int cpu); | 36 | void stop_machine_park(int cpu); |
37 | void stop_machine_unpark(int cpu); | ||
37 | 38 | ||
38 | #else /* CONFIG_SMP */ | 39 | #else /* CONFIG_SMP */ |
39 | 40 | ||
diff --git a/kernel/cpu.c b/kernel/cpu.c index c85df2775b73..6467521e1e15 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -475,6 +475,7 @@ static int smpboot_thread_call(struct notifier_block *nfb, | |||
475 | 475 | ||
476 | case CPU_DOWN_FAILED: | 476 | case CPU_DOWN_FAILED: |
477 | case CPU_ONLINE: | 477 | case CPU_ONLINE: |
478 | stop_machine_unpark(cpu); | ||
478 | smpboot_unpark_threads(cpu); | 479 | smpboot_unpark_threads(cpu); |
479 | break; | 480 | break; |
480 | 481 | ||
diff --git a/kernel/smpboot.c b/kernel/smpboot.c index a818cbc73e14..d264f59bff56 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c | |||
@@ -222,9 +222,8 @@ static void smpboot_unpark_thread(struct smp_hotplug_thread *ht, unsigned int cp | |||
222 | { | 222 | { |
223 | struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu); | 223 | struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu); |
224 | 224 | ||
225 | if (ht->pre_unpark) | 225 | if (!ht->selfparking) |
226 | ht->pre_unpark(cpu); | 226 | kthread_unpark(tsk); |
227 | kthread_unpark(tsk); | ||
228 | } | 227 | } |
229 | 228 | ||
230 | void smpboot_unpark_threads(unsigned int cpu) | 229 | void smpboot_unpark_threads(unsigned int cpu) |
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 91fbb109de6c..59096a55089f 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c | |||
@@ -513,6 +513,14 @@ static void cpu_stop_unpark(unsigned int cpu) | |||
513 | spin_unlock_irq(&stopper->lock); | 513 | spin_unlock_irq(&stopper->lock); |
514 | } | 514 | } |
515 | 515 | ||
516 | void stop_machine_unpark(int cpu) | ||
517 | { | ||
518 | struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu); | ||
519 | |||
520 | cpu_stop_unpark(cpu); | ||
521 | kthread_unpark(stopper->thread); | ||
522 | } | ||
523 | |||
516 | static struct smp_hotplug_thread cpu_stop_threads = { | 524 | static struct smp_hotplug_thread cpu_stop_threads = { |
517 | .store = &cpu_stopper.thread, | 525 | .store = &cpu_stopper.thread, |
518 | .thread_should_run = cpu_stop_should_run, | 526 | .thread_should_run = cpu_stop_should_run, |
@@ -521,7 +529,6 @@ static struct smp_hotplug_thread cpu_stop_threads = { | |||
521 | .create = cpu_stop_create, | 529 | .create = cpu_stop_create, |
522 | .setup = cpu_stop_unpark, | 530 | .setup = cpu_stop_unpark, |
523 | .park = cpu_stop_park, | 531 | .park = cpu_stop_park, |
524 | .pre_unpark = cpu_stop_unpark, | ||
525 | .selfparking = true, | 532 | .selfparking = true, |
526 | }; | 533 | }; |
527 | 534 | ||
@@ -537,6 +544,7 @@ static int __init cpu_stop_init(void) | |||
537 | } | 544 | } |
538 | 545 | ||
539 | BUG_ON(smpboot_register_percpu_thread(&cpu_stop_threads)); | 546 | BUG_ON(smpboot_register_percpu_thread(&cpu_stop_threads)); |
547 | stop_machine_unpark(raw_smp_processor_id()); | ||
540 | stop_machine_initialized = true; | 548 | stop_machine_initialized = true; |
541 | return 0; | 549 | return 0; |
542 | } | 550 | } |