[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <tip-4baa0afc6719cbf36a1e08551484a641926b3fd1@git.kernel.org>
Date: Tue, 1 Mar 2016 11:53:48 -0800
From: tip-bot for Thomas Gleixner <tipbot@...or.com>
To: linux-tip-commits@...r.kernel.org
Cc: tj@...nel.org, rostedt@...dmis.org, arjan@...ux.intel.com,
peterz@...radead.org, mingo@...nel.org, pjt@...gle.com,
paulmck@...ux.vnet.ibm.com, tglx@...utronix.de,
bigeasy@...utronix.de, oleg@...hat.com, riel@...hat.com,
linux-kernel@...r.kernel.org, rusty@...tcorp.com.au,
torvalds@...ux-foundation.org, srivatsa@....edu, hpa@...or.com,
akpm@...ux-foundation.org, rafael.j.wysocki@...el.com
Subject: [tip:smp/hotplug] cpu/hotplug: Convert the hotplugged cpu work to a
state machine
Commit-ID: 4baa0afc6719cbf36a1e08551484a641926b3fd1
Gitweb: http://git.kernel.org/tip/4baa0afc6719cbf36a1e08551484a641926b3fd1
Author: Thomas Gleixner <tglx@...utronix.de>
AuthorDate: Fri, 26 Feb 2016 18:43:29 +0000
Committer: Thomas Gleixner <tglx@...utronix.de>
CommitDate: Tue, 1 Mar 2016 20:36:54 +0100
cpu/hotplug: Convert the hotplugged cpu work to a state machine
Move the functions which need to run on the hotplugged processor into
a state machine array and let the code iterate through these functions.
In a later state, this will grow synchronization points between the
control processor and the hotplugged processor, so we can move the
various architecture implementations of the synchronizations to the
core.
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
Cc: linux-arch@...r.kernel.org
Cc: Rik van Riel <riel@...hat.com>
Cc: Rafael Wysocki <rafael.j.wysocki@...el.com>
Cc: "Srivatsa S. Bhat" <srivatsa@....edu>
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: Arjan van de Ven <arjan@...ux.intel.com>
Cc: Sebastian Siewior <bigeasy@...utronix.de>
Cc: Rusty Russell <rusty@...tcorp.com.au>
Cc: Steven Rostedt <rostedt@...dmis.org>
Cc: Oleg Nesterov <oleg@...hat.com>
Cc: Tejun Heo <tj@...nel.org>
Cc: Andrew Morton <akpm@...ux-foundation.org>
Cc: Paul McKenney <paulmck@...ux.vnet.ibm.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Paul Turner <pjt@...gle.com>
Link: http://lkml.kernel.org/r/20160226182340.770651526@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
---
include/linux/cpuhotplug.h | 4 +++
kernel/cpu.c | 81 +++++++++++++++++++++++++++++++++++++---------
2 files changed, 70 insertions(+), 15 deletions(-)
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index d55c9e6..d9303cc 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -6,6 +6,10 @@ enum cpuhp_state {
CPUHP_CREATE_THREADS,
CPUHP_NOTIFY_PREPARE,
CPUHP_BRINGUP_CPU,
+ CPUHP_AP_OFFLINE,
+ CPUHP_AP_NOTIFY_STARTING,
+ CPUHP_AP_ONLINE,
+ CPUHP_TEARDOWN_CPU,
CPUHP_NOTIFY_ONLINE,
CPUHP_ONLINE,
};
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 3018519..797723e 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -57,6 +57,7 @@ struct cpuhp_step {
};
static struct cpuhp_step cpuhp_bp_states[];
+static struct cpuhp_step cpuhp_ap_states[];
/**
* cpuhp_invoke_callback _ Invoke the callbacks for a given state
@@ -304,6 +305,12 @@ static int notify_online(unsigned int cpu)
return 0;
}
+static int notify_starting(unsigned int cpu)
+{
+ cpu_notify(CPU_STARTING, cpu);
+ return 0;
+}
+
static int bringup_cpu(unsigned int cpu)
{
struct task_struct *idle = idle_thread_get(cpu);
@@ -421,9 +428,17 @@ static int notify_down_prepare(unsigned int cpu)
return err;
}
+static int notify_dying(unsigned int cpu)
+{
+ cpu_notify(CPU_DYING, cpu);
+ return 0;
+}
+
/* Take this CPU down. */
static int take_cpu_down(void *_param)
{
+ struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
+ enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE);
int err, cpu = smp_processor_id();
/* Ensure this CPU doesn't handle any more interrupts. */
@@ -431,7 +446,12 @@ static int take_cpu_down(void *_param)
if (err < 0)
return err;
- cpu_notify(CPU_DYING, cpu);
+ /* Invoke the former CPU_DYING callbacks */
+ for (; st->state > target; st->state--) {
+ struct cpuhp_step *step = cpuhp_ap_states + st->state;
+
+ cpuhp_invoke_callback(cpu, st->state, step->teardown);
+ }
/* Give up timekeeping duties */
tick_handover_do_timer();
/* Park the stopper thread */
@@ -512,6 +532,7 @@ static int notify_dead(unsigned int cpu)
#define notify_down_prepare NULL
#define takedown_cpu NULL
#define notify_dead NULL
+#define notify_dying NULL
#endif
#ifdef CONFIG_HOTPLUG_CPU
@@ -615,6 +636,28 @@ void smpboot_thread_init(void)
register_cpu_notifier(&smpboot_thread_notifier);
}
+/**
+ * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers
+ * @cpu: cpu that just started
+ *
+ * This function calls the cpu_chain notifiers with CPU_STARTING.
+ * It must be called by the arch code on the new cpu, before the new cpu
+ * enables interrupts and before the "boot" cpu returns from __cpu_up().
+ */
+void notify_cpu_starting(unsigned int cpu)
+{
+ struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
+ enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE);
+
+ while (st->state < target) {
+ struct cpuhp_step *step;
+
+ st->state++;
+ step = cpuhp_ap_states + st->state;
+ cpuhp_invoke_callback(cpu, st->state, step->startup);
+ }
+}
+
static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st)
{
for (st->state--; st->state > st->target; st->state--) {
@@ -842,19 +885,6 @@ core_initcall(cpu_hotplug_pm_sync_init);
#endif /* CONFIG_PM_SLEEP_SMP */
-/**
- * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers
- * @cpu: cpu that just started
- *
- * This function calls the cpu_chain notifiers with CPU_STARTING.
- * It must be called by the arch code on the new cpu, before the new cpu
- * enables interrupts and before the "boot" cpu returns from __cpu_up().
- */
-void notify_cpu_starting(unsigned int cpu)
-{
- cpu_notify(CPU_STARTING, cpu);
-}
-
#endif /* CONFIG_SMP */
/* Boot processor state steps */
@@ -879,8 +909,12 @@ static struct cpuhp_step cpuhp_bp_states[] = {
[CPUHP_BRINGUP_CPU] = {
.name = "cpu:bringup",
.startup = bringup_cpu,
+ .teardown = NULL,
+ },
+ [CPUHP_TEARDOWN_CPU] = {
+ .name = "cpu:teardown",
+ .startup = NULL,
.teardown = takedown_cpu,
- .skip_onerr = true,
},
[CPUHP_NOTIFY_ONLINE] = {
.name = "notify:online",
@@ -895,6 +929,23 @@ static struct cpuhp_step cpuhp_bp_states[] = {
},
};
+/* Application processor state steps */
+static struct cpuhp_step cpuhp_ap_states[] = {
+#ifdef CONFIG_SMP
+ [CPUHP_AP_NOTIFY_STARTING] = {
+ .name = "notify:starting",
+ .startup = notify_starting,
+ .teardown = notify_dying,
+ .skip_onerr = true,
+ },
+#endif
+ [CPUHP_ONLINE] = {
+ .name = "online",
+ .startup = NULL,
+ .teardown = NULL,
+ },
+};
+
/*
* cpu_bit_bitmap[] is a special, "compressed" data structure that
* represents all NR_CPUS bits binary values of 1<<nr.
Powered by blists - more mailing lists