diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2017-01-10 08:01:05 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-01-16 07:20:05 -0500 |
commit | 4205e4786d0b9fc3b4fec7b1910cf645a0468307 (patch) | |
tree | 685ccb486409197b936c785eb9d173c3edff45a1 | |
parent | 7e164ce4e8ecd7e9a58a83750bd3ee03125df154 (diff) |
cpu/hotplug: Provide dynamic range for prepare stage
Mathieu reported that the LTTNG modules are broken as of 4.10-rc1 due to
the removal of the cpu hotplug notifiers.
Usually I don't care much about out of tree modules, but LTTNG is widely
used in distros. There are two ways to solve that:
1) Reserve a hotplug state for LTTNG
2) Add a dynamic range for the prepare states.
While #1 is the simplest solution, #2 is the proper one as we can convert
in tree users, which do not care about ordering, to the dynamic range as
well.
Add a dynamic range which allows LTTNG to request states in the prepare
stage.
Reported-and-tested-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sebastian Sewior <bigeasy@linutronix.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1701101353010.3401@nanos
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | include/linux/cpuhotplug.h | 2 | ||||
-rw-r--r-- | kernel/cpu.c | 22 |
2 files changed, 20 insertions, 4 deletions
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 20bfefbe7594..d936a0021839 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h | |||
@@ -74,6 +74,8 @@ enum cpuhp_state { | |||
74 | CPUHP_ZCOMP_PREPARE, | 74 | CPUHP_ZCOMP_PREPARE, |
75 | CPUHP_TIMERS_DEAD, | 75 | CPUHP_TIMERS_DEAD, |
76 | CPUHP_MIPS_SOC_PREPARE, | 76 | CPUHP_MIPS_SOC_PREPARE, |
77 | CPUHP_BP_PREPARE_DYN, | ||
78 | CPUHP_BP_PREPARE_DYN_END = CPUHP_BP_PREPARE_DYN + 20, | ||
77 | CPUHP_BRINGUP_CPU, | 79 | CPUHP_BRINGUP_CPU, |
78 | CPUHP_AP_IDLE_DEAD, | 80 | CPUHP_AP_IDLE_DEAD, |
79 | CPUHP_AP_OFFLINE, | 81 | CPUHP_AP_OFFLINE, |
diff --git a/kernel/cpu.c b/kernel/cpu.c index f75c4d031eeb..c47506357519 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -1302,10 +1302,24 @@ static int cpuhp_cb_check(enum cpuhp_state state) | |||
1302 | */ | 1302 | */ |
1303 | static int cpuhp_reserve_state(enum cpuhp_state state) | 1303 | static int cpuhp_reserve_state(enum cpuhp_state state) |
1304 | { | 1304 | { |
1305 | enum cpuhp_state i; | 1305 | enum cpuhp_state i, end; |
1306 | struct cpuhp_step *step; | ||
1306 | 1307 | ||
1307 | for (i = CPUHP_AP_ONLINE_DYN; i <= CPUHP_AP_ONLINE_DYN_END; i++) { | 1308 | switch (state) { |
1308 | if (!cpuhp_ap_states[i].name) | 1309 | case CPUHP_AP_ONLINE_DYN: |
1310 | step = cpuhp_ap_states + CPUHP_AP_ONLINE_DYN; | ||
1311 | end = CPUHP_AP_ONLINE_DYN_END; | ||
1312 | break; | ||
1313 | case CPUHP_BP_PREPARE_DYN: | ||
1314 | step = cpuhp_bp_states + CPUHP_BP_PREPARE_DYN; | ||
1315 | end = CPUHP_BP_PREPARE_DYN_END; | ||
1316 | break; | ||
1317 | default: | ||
1318 | return -EINVAL; | ||
1319 | } | ||
1320 | |||
1321 | for (i = state; i <= end; i++, step++) { | ||
1322 | if (!step->name) | ||
1309 | return i; | 1323 | return i; |
1310 | } | 1324 | } |
1311 | WARN(1, "No more dynamic states available for CPU hotplug\n"); | 1325 | WARN(1, "No more dynamic states available for CPU hotplug\n"); |
@@ -1323,7 +1337,7 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name, | |||
1323 | 1337 | ||
1324 | mutex_lock(&cpuhp_state_mutex); | 1338 | mutex_lock(&cpuhp_state_mutex); |
1325 | 1339 | ||
1326 | if (state == CPUHP_AP_ONLINE_DYN) { | 1340 | if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) { |
1327 | ret = cpuhp_reserve_state(state); | 1341 | ret = cpuhp_reserve_state(state); |
1328 | if (ret < 0) | 1342 | if (ret < 0) |
1329 | goto out; | 1343 | goto out; |