diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
commit | 1236d6bb6e19fc72ffc6bbcdeb1bfefe450e54ee (patch) | |
tree | 47da3feee8e263e8c9352c85cf518e624be3c211 /kernel/cpu.c | |
parent | 750b1a6894ecc9b178c6e3d0a1170122971b2036 (diff) | |
parent | 8a5776a5f49812d29fe4b2d0a2d71675c3facf3f (diff) |
Merge 4.14-rc4 into staging-next
We want the staging/iio fixes in here as well to handle merge issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r-- | kernel/cpu.c | 512 |
1 files changed, 370 insertions, 142 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index acf5308fad51..d851df22f5c5 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/lockdep.h> | 24 | #include <linux/lockdep.h> |
25 | #include <linux/tick.h> | 25 | #include <linux/tick.h> |
26 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
27 | #include <linux/nmi.h> | ||
27 | #include <linux/smpboot.h> | 28 | #include <linux/smpboot.h> |
28 | #include <linux/relay.h> | 29 | #include <linux/relay.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
@@ -46,11 +47,13 @@ | |||
46 | * @bringup: Single callback bringup or teardown selector | 47 | * @bringup: Single callback bringup or teardown selector |
47 | * @cb_state: The state for a single callback (install/uninstall) | 48 | * @cb_state: The state for a single callback (install/uninstall) |
48 | * @result: Result of the operation | 49 | * @result: Result of the operation |
49 | * @done: Signal completion to the issuer of the task | 50 | * @done_up: Signal completion to the issuer of the task for cpu-up |
51 | * @done_down: Signal completion to the issuer of the task for cpu-down | ||
50 | */ | 52 | */ |
51 | struct cpuhp_cpu_state { | 53 | struct cpuhp_cpu_state { |
52 | enum cpuhp_state state; | 54 | enum cpuhp_state state; |
53 | enum cpuhp_state target; | 55 | enum cpuhp_state target; |
56 | enum cpuhp_state fail; | ||
54 | #ifdef CONFIG_SMP | 57 | #ifdef CONFIG_SMP |
55 | struct task_struct *thread; | 58 | struct task_struct *thread; |
56 | bool should_run; | 59 | bool should_run; |
@@ -58,18 +61,39 @@ struct cpuhp_cpu_state { | |||
58 | bool single; | 61 | bool single; |
59 | bool bringup; | 62 | bool bringup; |
60 | struct hlist_node *node; | 63 | struct hlist_node *node; |
64 | struct hlist_node *last; | ||
61 | enum cpuhp_state cb_state; | 65 | enum cpuhp_state cb_state; |
62 | int result; | 66 | int result; |
63 | struct completion done; | 67 | struct completion done_up; |
68 | struct completion done_down; | ||
64 | #endif | 69 | #endif |
65 | }; | 70 | }; |
66 | 71 | ||
67 | static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state); | 72 | static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state) = { |
73 | .fail = CPUHP_INVALID, | ||
74 | }; | ||
68 | 75 | ||
69 | #if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP) | 76 | #if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP) |
70 | static struct lock_class_key cpuhp_state_key; | 77 | static struct lockdep_map cpuhp_state_up_map = |
71 | static struct lockdep_map cpuhp_state_lock_map = | 78 | STATIC_LOCKDEP_MAP_INIT("cpuhp_state-up", &cpuhp_state_up_map); |
72 | STATIC_LOCKDEP_MAP_INIT("cpuhp_state", &cpuhp_state_key); | 79 | static struct lockdep_map cpuhp_state_down_map = |
80 | STATIC_LOCKDEP_MAP_INIT("cpuhp_state-down", &cpuhp_state_down_map); | ||
81 | |||
82 | |||
83 | static void inline cpuhp_lock_acquire(bool bringup) | ||
84 | { | ||
85 | lock_map_acquire(bringup ? &cpuhp_state_up_map : &cpuhp_state_down_map); | ||
86 | } | ||
87 | |||
88 | static void inline cpuhp_lock_release(bool bringup) | ||
89 | { | ||
90 | lock_map_release(bringup ? &cpuhp_state_up_map : &cpuhp_state_down_map); | ||
91 | } | ||
92 | #else | ||
93 | |||
94 | static void inline cpuhp_lock_acquire(bool bringup) { } | ||
95 | static void inline cpuhp_lock_release(bool bringup) { } | ||
96 | |||
73 | #endif | 97 | #endif |
74 | 98 | ||
75 | /** | 99 | /** |
@@ -123,13 +147,16 @@ static struct cpuhp_step *cpuhp_get_step(enum cpuhp_state state) | |||
123 | /** | 147 | /** |
124 | * cpuhp_invoke_callback _ Invoke the callbacks for a given state | 148 | * cpuhp_invoke_callback _ Invoke the callbacks for a given state |
125 | * @cpu: The cpu for which the callback should be invoked | 149 | * @cpu: The cpu for which the callback should be invoked |
126 | * @step: The step in the state machine | 150 | * @state: The state to do callbacks for |
127 | * @bringup: True if the bringup callback should be invoked | 151 | * @bringup: True if the bringup callback should be invoked |
152 | * @node: For multi-instance, do a single entry callback for install/remove | ||
153 | * @lastp: For multi-instance rollback, remember how far we got | ||
128 | * | 154 | * |
129 | * Called from cpu hotplug and from the state register machinery. | 155 | * Called from cpu hotplug and from the state register machinery. |
130 | */ | 156 | */ |
131 | static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, | 157 | static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, |
132 | bool bringup, struct hlist_node *node) | 158 | bool bringup, struct hlist_node *node, |
159 | struct hlist_node **lastp) | ||
133 | { | 160 | { |
134 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); | 161 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); |
135 | struct cpuhp_step *step = cpuhp_get_step(state); | 162 | struct cpuhp_step *step = cpuhp_get_step(state); |
@@ -137,7 +164,17 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, | |||
137 | int (*cb)(unsigned int cpu); | 164 | int (*cb)(unsigned int cpu); |
138 | int ret, cnt; | 165 | int ret, cnt; |
139 | 166 | ||
167 | if (st->fail == state) { | ||
168 | st->fail = CPUHP_INVALID; | ||
169 | |||
170 | if (!(bringup ? step->startup.single : step->teardown.single)) | ||
171 | return 0; | ||
172 | |||
173 | return -EAGAIN; | ||
174 | } | ||
175 | |||
140 | if (!step->multi_instance) { | 176 | if (!step->multi_instance) { |
177 | WARN_ON_ONCE(lastp && *lastp); | ||
141 | cb = bringup ? step->startup.single : step->teardown.single; | 178 | cb = bringup ? step->startup.single : step->teardown.single; |
142 | if (!cb) | 179 | if (!cb) |
143 | return 0; | 180 | return 0; |
@@ -152,6 +189,7 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, | |||
152 | 189 | ||
153 | /* Single invocation for instance add/remove */ | 190 | /* Single invocation for instance add/remove */ |
154 | if (node) { | 191 | if (node) { |
192 | WARN_ON_ONCE(lastp && *lastp); | ||
155 | trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); | 193 | trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); |
156 | ret = cbm(cpu, node); | 194 | ret = cbm(cpu, node); |
157 | trace_cpuhp_exit(cpu, st->state, state, ret); | 195 | trace_cpuhp_exit(cpu, st->state, state, ret); |
@@ -161,13 +199,23 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, | |||
161 | /* State transition. Invoke on all instances */ | 199 | /* State transition. Invoke on all instances */ |
162 | cnt = 0; | 200 | cnt = 0; |
163 | hlist_for_each(node, &step->list) { | 201 | hlist_for_each(node, &step->list) { |
202 | if (lastp && node == *lastp) | ||
203 | break; | ||
204 | |||
164 | trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); | 205 | trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); |
165 | ret = cbm(cpu, node); | 206 | ret = cbm(cpu, node); |
166 | trace_cpuhp_exit(cpu, st->state, state, ret); | 207 | trace_cpuhp_exit(cpu, st->state, state, ret); |
167 | if (ret) | 208 | if (ret) { |
168 | goto err; | 209 | if (!lastp) |
210 | goto err; | ||
211 | |||
212 | *lastp = node; | ||
213 | return ret; | ||
214 | } | ||
169 | cnt++; | 215 | cnt++; |
170 | } | 216 | } |
217 | if (lastp) | ||
218 | *lastp = NULL; | ||
171 | return 0; | 219 | return 0; |
172 | err: | 220 | err: |
173 | /* Rollback the instances if one failed */ | 221 | /* Rollback the instances if one failed */ |
@@ -178,12 +226,39 @@ err: | |||
178 | hlist_for_each(node, &step->list) { | 226 | hlist_for_each(node, &step->list) { |
179 | if (!cnt--) | 227 | if (!cnt--) |
180 | break; | 228 | break; |
181 | cbm(cpu, node); | 229 | |
230 | trace_cpuhp_multi_enter(cpu, st->target, state, cbm, node); | ||
231 | ret = cbm(cpu, node); | ||
232 | trace_cpuhp_exit(cpu, st->state, state, ret); | ||
233 | /* | ||
234 | * Rollback must not fail, | ||
235 | */ | ||
236 | WARN_ON_ONCE(ret); | ||
182 | } | 237 | } |
183 | return ret; | 238 | return ret; |
184 | } | 239 | } |
185 | 240 | ||
186 | #ifdef CONFIG_SMP | 241 | #ifdef CONFIG_SMP |
242 | static inline void wait_for_ap_thread(struct cpuhp_cpu_state *st, bool bringup) | ||
243 | { | ||
244 | struct completion *done = bringup ? &st->done_up : &st->done_down; | ||
245 | wait_for_completion(done); | ||
246 | } | ||
247 | |||
248 | static inline void complete_ap_thread(struct cpuhp_cpu_state *st, bool bringup) | ||
249 | { | ||
250 | struct completion *done = bringup ? &st->done_up : &st->done_down; | ||
251 | complete(done); | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * The former STARTING/DYING states, ran with IRQs disabled and must not fail. | ||
256 | */ | ||
257 | static bool cpuhp_is_atomic_state(enum cpuhp_state state) | ||
258 | { | ||
259 | return CPUHP_AP_IDLE_DEAD <= state && state < CPUHP_AP_ONLINE; | ||
260 | } | ||
261 | |||
187 | /* Serializes the updates to cpu_online_mask, cpu_present_mask */ | 262 | /* Serializes the updates to cpu_online_mask, cpu_present_mask */ |
188 | static DEFINE_MUTEX(cpu_add_remove_lock); | 263 | static DEFINE_MUTEX(cpu_add_remove_lock); |
189 | bool cpuhp_tasks_frozen; | 264 | bool cpuhp_tasks_frozen; |
@@ -271,14 +346,79 @@ void cpu_hotplug_enable(void) | |||
271 | EXPORT_SYMBOL_GPL(cpu_hotplug_enable); | 346 | EXPORT_SYMBOL_GPL(cpu_hotplug_enable); |
272 | #endif /* CONFIG_HOTPLUG_CPU */ | 347 | #endif /* CONFIG_HOTPLUG_CPU */ |
273 | 348 | ||
274 | static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st); | 349 | static inline enum cpuhp_state |
350 | cpuhp_set_state(struct cpuhp_cpu_state *st, enum cpuhp_state target) | ||
351 | { | ||
352 | enum cpuhp_state prev_state = st->state; | ||
353 | |||
354 | st->rollback = false; | ||
355 | st->last = NULL; | ||
356 | |||
357 | st->target = target; | ||
358 | st->single = false; | ||
359 | st->bringup = st->state < target; | ||
360 | |||
361 | return prev_state; | ||
362 | } | ||
363 | |||
364 | static inline void | ||
365 | cpuhp_reset_state(struct cpuhp_cpu_state *st, enum cpuhp_state prev_state) | ||
366 | { | ||
367 | st->rollback = true; | ||
368 | |||
369 | /* | ||
370 | * If we have st->last we need to undo partial multi_instance of this | ||
371 | * state first. Otherwise start undo at the previous state. | ||
372 | */ | ||
373 | if (!st->last) { | ||
374 | if (st->bringup) | ||
375 | st->state--; | ||
376 | else | ||
377 | st->state++; | ||
378 | } | ||
379 | |||
380 | st->target = prev_state; | ||
381 | st->bringup = !st->bringup; | ||
382 | } | ||
383 | |||
384 | /* Regular hotplug invocation of the AP hotplug thread */ | ||
385 | static void __cpuhp_kick_ap(struct cpuhp_cpu_state *st) | ||
386 | { | ||
387 | if (!st->single && st->state == st->target) | ||
388 | return; | ||
389 | |||
390 | st->result = 0; | ||
391 | /* | ||
392 | * Make sure the above stores are visible before should_run becomes | ||
393 | * true. Paired with the mb() above in cpuhp_thread_fun() | ||
394 | */ | ||
395 | smp_mb(); | ||
396 | st->should_run = true; | ||
397 | wake_up_process(st->thread); | ||
398 | wait_for_ap_thread(st, st->bringup); | ||
399 | } | ||
400 | |||
401 | static int cpuhp_kick_ap(struct cpuhp_cpu_state *st, enum cpuhp_state target) | ||
402 | { | ||
403 | enum cpuhp_state prev_state; | ||
404 | int ret; | ||
405 | |||
406 | prev_state = cpuhp_set_state(st, target); | ||
407 | __cpuhp_kick_ap(st); | ||
408 | if ((ret = st->result)) { | ||
409 | cpuhp_reset_state(st, prev_state); | ||
410 | __cpuhp_kick_ap(st); | ||
411 | } | ||
412 | |||
413 | return ret; | ||
414 | } | ||
275 | 415 | ||
276 | static int bringup_wait_for_ap(unsigned int cpu) | 416 | static int bringup_wait_for_ap(unsigned int cpu) |
277 | { | 417 | { |
278 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); | 418 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); |
279 | 419 | ||
280 | /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */ | 420 | /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */ |
281 | wait_for_completion(&st->done); | 421 | wait_for_ap_thread(st, true); |
282 | if (WARN_ON_ONCE((!cpu_online(cpu)))) | 422 | if (WARN_ON_ONCE((!cpu_online(cpu)))) |
283 | return -ECANCELED; | 423 | return -ECANCELED; |
284 | 424 | ||
@@ -286,12 +426,10 @@ static int bringup_wait_for_ap(unsigned int cpu) | |||
286 | stop_machine_unpark(cpu); | 426 | stop_machine_unpark(cpu); |
287 | kthread_unpark(st->thread); | 427 | kthread_unpark(st->thread); |
288 | 428 | ||
289 | /* Should we go further up ? */ | 429 | if (st->target <= CPUHP_AP_ONLINE_IDLE) |
290 | if (st->target > CPUHP_AP_ONLINE_IDLE) { | 430 | return 0; |
291 | __cpuhp_kick_ap_work(st); | 431 | |
292 | wait_for_completion(&st->done); | 432 | return cpuhp_kick_ap(st, st->target); |
293 | } | ||
294 | return st->result; | ||
295 | } | 433 | } |
296 | 434 | ||
297 | static int bringup_cpu(unsigned int cpu) | 435 | static int bringup_cpu(unsigned int cpu) |
@@ -317,32 +455,6 @@ static int bringup_cpu(unsigned int cpu) | |||
317 | /* | 455 | /* |
318 | * Hotplug state machine related functions | 456 | * Hotplug state machine related functions |
319 | */ | 457 | */ |
320 | static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st) | ||
321 | { | ||
322 | for (st->state++; st->state < st->target; st->state++) { | ||
323 | struct cpuhp_step *step = cpuhp_get_step(st->state); | ||
324 | |||
325 | if (!step->skip_onerr) | ||
326 | cpuhp_invoke_callback(cpu, st->state, true, NULL); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, | ||
331 | enum cpuhp_state target) | ||
332 | { | ||
333 | enum cpuhp_state prev_state = st->state; | ||
334 | int ret = 0; | ||
335 | |||
336 | for (; st->state > target; st->state--) { | ||
337 | ret = cpuhp_invoke_callback(cpu, st->state, false, NULL); | ||
338 | if (ret) { | ||
339 | st->target = prev_state; | ||
340 | undo_cpu_down(cpu, st); | ||
341 | break; | ||
342 | } | ||
343 | } | ||
344 | return ret; | ||
345 | } | ||
346 | 458 | ||
347 | static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st) | 459 | static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st) |
348 | { | 460 | { |
@@ -350,7 +462,7 @@ static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st) | |||
350 | struct cpuhp_step *step = cpuhp_get_step(st->state); | 462 | struct cpuhp_step *step = cpuhp_get_step(st->state); |
351 | 463 | ||
352 | if (!step->skip_onerr) | 464 | if (!step->skip_onerr) |
353 | cpuhp_invoke_callback(cpu, st->state, false, NULL); | 465 | cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); |
354 | } | 466 | } |
355 | } | 467 | } |
356 | 468 | ||
@@ -362,7 +474,7 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, | |||
362 | 474 | ||
363 | while (st->state < target) { | 475 | while (st->state < target) { |
364 | st->state++; | 476 | st->state++; |
365 | ret = cpuhp_invoke_callback(cpu, st->state, true, NULL); | 477 | ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); |
366 | if (ret) { | 478 | if (ret) { |
367 | st->target = prev_state; | 479 | st->target = prev_state; |
368 | undo_cpu_up(cpu, st); | 480 | undo_cpu_up(cpu, st); |
@@ -379,7 +491,8 @@ static void cpuhp_create(unsigned int cpu) | |||
379 | { | 491 | { |
380 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); | 492 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); |
381 | 493 | ||
382 | init_completion(&st->done); | 494 | init_completion(&st->done_up); |
495 | init_completion(&st->done_down); | ||
383 | } | 496 | } |
384 | 497 | ||
385 | static int cpuhp_should_run(unsigned int cpu) | 498 | static int cpuhp_should_run(unsigned int cpu) |
@@ -389,69 +502,90 @@ static int cpuhp_should_run(unsigned int cpu) | |||
389 | return st->should_run; | 502 | return st->should_run; |
390 | } | 503 | } |
391 | 504 | ||
392 | /* Execute the teardown callbacks. Used to be CPU_DOWN_PREPARE */ | ||
393 | static int cpuhp_ap_offline(unsigned int cpu, struct cpuhp_cpu_state *st) | ||
394 | { | ||
395 | enum cpuhp_state target = max((int)st->target, CPUHP_TEARDOWN_CPU); | ||
396 | |||
397 | return cpuhp_down_callbacks(cpu, st, target); | ||
398 | } | ||
399 | |||
400 | /* Execute the online startup callbacks. Used to be CPU_ONLINE */ | ||
401 | static int cpuhp_ap_online(unsigned int cpu, struct cpuhp_cpu_state *st) | ||
402 | { | ||
403 | return cpuhp_up_callbacks(cpu, st, st->target); | ||
404 | } | ||
405 | |||
406 | /* | 505 | /* |
407 | * Execute teardown/startup callbacks on the plugged cpu. Also used to invoke | 506 | * Execute teardown/startup callbacks on the plugged cpu. Also used to invoke |
408 | * callbacks when a state gets [un]installed at runtime. | 507 | * callbacks when a state gets [un]installed at runtime. |
508 | * | ||
509 | * Each invocation of this function by the smpboot thread does a single AP | ||
510 | * state callback. | ||
511 | * | ||
512 | * It has 3 modes of operation: | ||
513 | * - single: runs st->cb_state | ||
514 | * - up: runs ++st->state, while st->state < st->target | ||
515 | * - down: runs st->state--, while st->state > st->target | ||
516 | * | ||
517 | * When complete or on error, should_run is cleared and the completion is fired. | ||
409 | */ | 518 | */ |
410 | static void cpuhp_thread_fun(unsigned int cpu) | 519 | static void cpuhp_thread_fun(unsigned int cpu) |
411 | { | 520 | { |
412 | struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); | 521 | struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); |
413 | int ret = 0; | 522 | bool bringup = st->bringup; |
523 | enum cpuhp_state state; | ||
414 | 524 | ||
415 | /* | 525 | /* |
416 | * Paired with the mb() in cpuhp_kick_ap_work and | 526 | * ACQUIRE for the cpuhp_should_run() load of ->should_run. Ensures |
417 | * cpuhp_invoke_ap_callback, so the work set is consistent visible. | 527 | * that if we see ->should_run we also see the rest of the state. |
418 | */ | 528 | */ |
419 | smp_mb(); | 529 | smp_mb(); |
420 | if (!st->should_run) | 530 | |
531 | if (WARN_ON_ONCE(!st->should_run)) | ||
421 | return; | 532 | return; |
422 | 533 | ||
423 | st->should_run = false; | 534 | cpuhp_lock_acquire(bringup); |
424 | 535 | ||
425 | lock_map_acquire(&cpuhp_state_lock_map); | ||
426 | /* Single callback invocation for [un]install ? */ | ||
427 | if (st->single) { | 536 | if (st->single) { |
428 | if (st->cb_state < CPUHP_AP_ONLINE) { | 537 | state = st->cb_state; |
429 | local_irq_disable(); | 538 | st->should_run = false; |
430 | ret = cpuhp_invoke_callback(cpu, st->cb_state, | 539 | } else { |
431 | st->bringup, st->node); | 540 | if (bringup) { |
432 | local_irq_enable(); | 541 | st->state++; |
542 | state = st->state; | ||
543 | st->should_run = (st->state < st->target); | ||
544 | WARN_ON_ONCE(st->state > st->target); | ||
433 | } else { | 545 | } else { |
434 | ret = cpuhp_invoke_callback(cpu, st->cb_state, | 546 | state = st->state; |
435 | st->bringup, st->node); | 547 | st->state--; |
548 | st->should_run = (st->state > st->target); | ||
549 | WARN_ON_ONCE(st->state < st->target); | ||
436 | } | 550 | } |
437 | } else if (st->rollback) { | 551 | } |
438 | BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE); | 552 | |
553 | WARN_ON_ONCE(!cpuhp_is_ap_state(state)); | ||
554 | |||
555 | if (st->rollback) { | ||
556 | struct cpuhp_step *step = cpuhp_get_step(state); | ||
557 | if (step->skip_onerr) | ||
558 | goto next; | ||
559 | } | ||
560 | |||
561 | if (cpuhp_is_atomic_state(state)) { | ||
562 | local_irq_disable(); | ||
563 | st->result = cpuhp_invoke_callback(cpu, state, bringup, st->node, &st->last); | ||
564 | local_irq_enable(); | ||
439 | 565 | ||
440 | undo_cpu_down(cpu, st); | 566 | /* |
441 | st->rollback = false; | 567 | * STARTING/DYING must not fail! |
568 | */ | ||
569 | WARN_ON_ONCE(st->result); | ||
442 | } else { | 570 | } else { |
443 | /* Cannot happen .... */ | 571 | st->result = cpuhp_invoke_callback(cpu, state, bringup, st->node, &st->last); |
444 | BUG_ON(st->state < CPUHP_AP_ONLINE_IDLE); | 572 | } |
445 | 573 | ||
446 | /* Regular hotplug work */ | 574 | if (st->result) { |
447 | if (st->state < st->target) | 575 | /* |
448 | ret = cpuhp_ap_online(cpu, st); | 576 | * If we fail on a rollback, we're up a creek without no |
449 | else if (st->state > st->target) | 577 | * paddle, no way forward, no way back. We loose, thanks for |
450 | ret = cpuhp_ap_offline(cpu, st); | 578 | * playing. |
579 | */ | ||
580 | WARN_ON_ONCE(st->rollback); | ||
581 | st->should_run = false; | ||
451 | } | 582 | } |
452 | lock_map_release(&cpuhp_state_lock_map); | 583 | |
453 | st->result = ret; | 584 | next: |
454 | complete(&st->done); | 585 | cpuhp_lock_release(bringup); |
586 | |||
587 | if (!st->should_run) | ||
588 | complete_ap_thread(st, bringup); | ||
455 | } | 589 | } |
456 | 590 | ||
457 | /* Invoke a single callback on a remote cpu */ | 591 | /* Invoke a single callback on a remote cpu */ |
@@ -460,62 +594,64 @@ cpuhp_invoke_ap_callback(int cpu, enum cpuhp_state state, bool bringup, | |||
460 | struct hlist_node *node) | 594 | struct hlist_node *node) |
461 | { | 595 | { |
462 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); | 596 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); |
597 | int ret; | ||
463 | 598 | ||
464 | if (!cpu_online(cpu)) | 599 | if (!cpu_online(cpu)) |
465 | return 0; | 600 | return 0; |
466 | 601 | ||
467 | lock_map_acquire(&cpuhp_state_lock_map); | 602 | cpuhp_lock_acquire(false); |
468 | lock_map_release(&cpuhp_state_lock_map); | 603 | cpuhp_lock_release(false); |
604 | |||
605 | cpuhp_lock_acquire(true); | ||
606 | cpuhp_lock_release(true); | ||
469 | 607 | ||
470 | /* | 608 | /* |
471 | * If we are up and running, use the hotplug thread. For early calls | 609 | * If we are up and running, use the hotplug thread. For early calls |
472 | * we invoke the thread function directly. | 610 | * we invoke the thread function directly. |
473 | */ | 611 | */ |
474 | if (!st->thread) | 612 | if (!st->thread) |
475 | return cpuhp_invoke_callback(cpu, state, bringup, node); | 613 | return cpuhp_invoke_callback(cpu, state, bringup, node, NULL); |
614 | |||
615 | st->rollback = false; | ||
616 | st->last = NULL; | ||
476 | 617 | ||
618 | st->node = node; | ||
619 | st->bringup = bringup; | ||
477 | st->cb_state = state; | 620 | st->cb_state = state; |
478 | st->single = true; | 621 | st->single = true; |
479 | st->bringup = bringup; | ||
480 | st->node = node; | ||
481 | 622 | ||
482 | /* | 623 | __cpuhp_kick_ap(st); |
483 | * Make sure the above stores are visible before should_run becomes | ||
484 | * true. Paired with the mb() above in cpuhp_thread_fun() | ||
485 | */ | ||
486 | smp_mb(); | ||
487 | st->should_run = true; | ||
488 | wake_up_process(st->thread); | ||
489 | wait_for_completion(&st->done); | ||
490 | return st->result; | ||
491 | } | ||
492 | 624 | ||
493 | /* Regular hotplug invocation of the AP hotplug thread */ | ||
494 | static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st) | ||
495 | { | ||
496 | st->result = 0; | ||
497 | st->single = false; | ||
498 | /* | 625 | /* |
499 | * Make sure the above stores are visible before should_run becomes | 626 | * If we failed and did a partial, do a rollback. |
500 | * true. Paired with the mb() above in cpuhp_thread_fun() | ||
501 | */ | 627 | */ |
502 | smp_mb(); | 628 | if ((ret = st->result) && st->last) { |
503 | st->should_run = true; | 629 | st->rollback = true; |
504 | wake_up_process(st->thread); | 630 | st->bringup = !bringup; |
631 | |||
632 | __cpuhp_kick_ap(st); | ||
633 | } | ||
634 | |||
635 | return ret; | ||
505 | } | 636 | } |
506 | 637 | ||
507 | static int cpuhp_kick_ap_work(unsigned int cpu) | 638 | static int cpuhp_kick_ap_work(unsigned int cpu) |
508 | { | 639 | { |
509 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); | 640 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); |
510 | enum cpuhp_state state = st->state; | 641 | enum cpuhp_state prev_state = st->state; |
642 | int ret; | ||
643 | |||
644 | cpuhp_lock_acquire(false); | ||
645 | cpuhp_lock_release(false); | ||
511 | 646 | ||
512 | trace_cpuhp_enter(cpu, st->target, state, cpuhp_kick_ap_work); | 647 | cpuhp_lock_acquire(true); |
513 | lock_map_acquire(&cpuhp_state_lock_map); | 648 | cpuhp_lock_release(true); |
514 | lock_map_release(&cpuhp_state_lock_map); | 649 | |
515 | __cpuhp_kick_ap_work(st); | 650 | trace_cpuhp_enter(cpu, st->target, prev_state, cpuhp_kick_ap_work); |
516 | wait_for_completion(&st->done); | 651 | ret = cpuhp_kick_ap(st, st->target); |
517 | trace_cpuhp_exit(cpu, st->state, state, st->result); | 652 | trace_cpuhp_exit(cpu, st->state, prev_state, ret); |
518 | return st->result; | 653 | |
654 | return ret; | ||
519 | } | 655 | } |
520 | 656 | ||
521 | static struct smp_hotplug_thread cpuhp_threads = { | 657 | static struct smp_hotplug_thread cpuhp_threads = { |
@@ -581,6 +717,7 @@ static int take_cpu_down(void *_param) | |||
581 | struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); | 717 | struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); |
582 | enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE); | 718 | enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE); |
583 | int err, cpu = smp_processor_id(); | 719 | int err, cpu = smp_processor_id(); |
720 | int ret; | ||
584 | 721 | ||
585 | /* Ensure this CPU doesn't handle any more interrupts. */ | 722 | /* Ensure this CPU doesn't handle any more interrupts. */ |
586 | err = __cpu_disable(); | 723 | err = __cpu_disable(); |
@@ -594,8 +731,13 @@ static int take_cpu_down(void *_param) | |||
594 | WARN_ON(st->state != CPUHP_TEARDOWN_CPU); | 731 | WARN_ON(st->state != CPUHP_TEARDOWN_CPU); |
595 | st->state--; | 732 | st->state--; |
596 | /* Invoke the former CPU_DYING callbacks */ | 733 | /* Invoke the former CPU_DYING callbacks */ |
597 | for (; st->state > target; st->state--) | 734 | for (; st->state > target; st->state--) { |
598 | cpuhp_invoke_callback(cpu, st->state, false, NULL); | 735 | ret = cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); |
736 | /* | ||
737 | * DYING must not fail! | ||
738 | */ | ||
739 | WARN_ON_ONCE(ret); | ||
740 | } | ||
599 | 741 | ||
600 | /* Give up timekeeping duties */ | 742 | /* Give up timekeeping duties */ |
601 | tick_handover_do_timer(); | 743 | tick_handover_do_timer(); |
@@ -639,7 +781,7 @@ static int takedown_cpu(unsigned int cpu) | |||
639 | * | 781 | * |
640 | * Wait for the stop thread to go away. | 782 | * Wait for the stop thread to go away. |
641 | */ | 783 | */ |
642 | wait_for_completion(&st->done); | 784 | wait_for_ap_thread(st, false); |
643 | BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); | 785 | BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); |
644 | 786 | ||
645 | /* Interrupts are moved away from the dying cpu, reenable alloc/free */ | 787 | /* Interrupts are moved away from the dying cpu, reenable alloc/free */ |
@@ -658,7 +800,7 @@ static void cpuhp_complete_idle_dead(void *arg) | |||
658 | { | 800 | { |
659 | struct cpuhp_cpu_state *st = arg; | 801 | struct cpuhp_cpu_state *st = arg; |
660 | 802 | ||
661 | complete(&st->done); | 803 | complete_ap_thread(st, false); |
662 | } | 804 | } |
663 | 805 | ||
664 | void cpuhp_report_idle_dead(void) | 806 | void cpuhp_report_idle_dead(void) |
@@ -676,11 +818,32 @@ void cpuhp_report_idle_dead(void) | |||
676 | cpuhp_complete_idle_dead, st, 0); | 818 | cpuhp_complete_idle_dead, st, 0); |
677 | } | 819 | } |
678 | 820 | ||
679 | #else | 821 | static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st) |
680 | #define takedown_cpu NULL | 822 | { |
681 | #endif | 823 | for (st->state++; st->state < st->target; st->state++) { |
824 | struct cpuhp_step *step = cpuhp_get_step(st->state); | ||
682 | 825 | ||
683 | #ifdef CONFIG_HOTPLUG_CPU | 826 | if (!step->skip_onerr) |
827 | cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st, | ||
832 | enum cpuhp_state target) | ||
833 | { | ||
834 | enum cpuhp_state prev_state = st->state; | ||
835 | int ret = 0; | ||
836 | |||
837 | for (; st->state > target; st->state--) { | ||
838 | ret = cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL); | ||
839 | if (ret) { | ||
840 | st->target = prev_state; | ||
841 | undo_cpu_down(cpu, st); | ||
842 | break; | ||
843 | } | ||
844 | } | ||
845 | return ret; | ||
846 | } | ||
684 | 847 | ||
685 | /* Requires cpu_add_remove_lock to be held */ | 848 | /* Requires cpu_add_remove_lock to be held */ |
686 | static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, | 849 | static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, |
@@ -699,13 +862,13 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, | |||
699 | 862 | ||
700 | cpuhp_tasks_frozen = tasks_frozen; | 863 | cpuhp_tasks_frozen = tasks_frozen; |
701 | 864 | ||
702 | prev_state = st->state; | 865 | prev_state = cpuhp_set_state(st, target); |
703 | st->target = target; | ||
704 | /* | 866 | /* |
705 | * If the current CPU state is in the range of the AP hotplug thread, | 867 | * If the current CPU state is in the range of the AP hotplug thread, |
706 | * then we need to kick the thread. | 868 | * then we need to kick the thread. |
707 | */ | 869 | */ |
708 | if (st->state > CPUHP_TEARDOWN_CPU) { | 870 | if (st->state > CPUHP_TEARDOWN_CPU) { |
871 | st->target = max((int)target, CPUHP_TEARDOWN_CPU); | ||
709 | ret = cpuhp_kick_ap_work(cpu); | 872 | ret = cpuhp_kick_ap_work(cpu); |
710 | /* | 873 | /* |
711 | * The AP side has done the error rollback already. Just | 874 | * The AP side has done the error rollback already. Just |
@@ -720,6 +883,8 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, | |||
720 | */ | 883 | */ |
721 | if (st->state > CPUHP_TEARDOWN_CPU) | 884 | if (st->state > CPUHP_TEARDOWN_CPU) |
722 | goto out; | 885 | goto out; |
886 | |||
887 | st->target = target; | ||
723 | } | 888 | } |
724 | /* | 889 | /* |
725 | * The AP brought itself down to CPUHP_TEARDOWN_CPU. So we need | 890 | * The AP brought itself down to CPUHP_TEARDOWN_CPU. So we need |
@@ -727,13 +892,17 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, | |||
727 | */ | 892 | */ |
728 | ret = cpuhp_down_callbacks(cpu, st, target); | 893 | ret = cpuhp_down_callbacks(cpu, st, target); |
729 | if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) { | 894 | if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) { |
730 | st->target = prev_state; | 895 | cpuhp_reset_state(st, prev_state); |
731 | st->rollback = true; | 896 | __cpuhp_kick_ap(st); |
732 | cpuhp_kick_ap_work(cpu); | ||
733 | } | 897 | } |
734 | 898 | ||
735 | out: | 899 | out: |
736 | cpus_write_unlock(); | 900 | cpus_write_unlock(); |
901 | /* | ||
902 | * Do post unplug cleanup. This is still protected against | ||
903 | * concurrent CPU hotplug via cpu_add_remove_lock. | ||
904 | */ | ||
905 | lockup_detector_cleanup(); | ||
737 | return ret; | 906 | return ret; |
738 | } | 907 | } |
739 | 908 | ||
@@ -754,11 +923,15 @@ out: | |||
754 | cpu_maps_update_done(); | 923 | cpu_maps_update_done(); |
755 | return err; | 924 | return err; |
756 | } | 925 | } |
926 | |||
757 | int cpu_down(unsigned int cpu) | 927 | int cpu_down(unsigned int cpu) |
758 | { | 928 | { |
759 | return do_cpu_down(cpu, CPUHP_OFFLINE); | 929 | return do_cpu_down(cpu, CPUHP_OFFLINE); |
760 | } | 930 | } |
761 | EXPORT_SYMBOL(cpu_down); | 931 | EXPORT_SYMBOL(cpu_down); |
932 | |||
933 | #else | ||
934 | #define takedown_cpu NULL | ||
762 | #endif /*CONFIG_HOTPLUG_CPU*/ | 935 | #endif /*CONFIG_HOTPLUG_CPU*/ |
763 | 936 | ||
764 | /** | 937 | /** |
@@ -772,11 +945,16 @@ void notify_cpu_starting(unsigned int cpu) | |||
772 | { | 945 | { |
773 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); | 946 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); |
774 | enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE); | 947 | enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE); |
948 | int ret; | ||
775 | 949 | ||
776 | rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */ | 950 | rcu_cpu_starting(cpu); /* Enables RCU usage on this CPU. */ |
777 | while (st->state < target) { | 951 | while (st->state < target) { |
778 | st->state++; | 952 | st->state++; |
779 | cpuhp_invoke_callback(cpu, st->state, true, NULL); | 953 | ret = cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL); |
954 | /* | ||
955 | * STARTING must not fail! | ||
956 | */ | ||
957 | WARN_ON_ONCE(ret); | ||
780 | } | 958 | } |
781 | } | 959 | } |
782 | 960 | ||
@@ -794,7 +972,7 @@ void cpuhp_online_idle(enum cpuhp_state state) | |||
794 | return; | 972 | return; |
795 | 973 | ||
796 | st->state = CPUHP_AP_ONLINE_IDLE; | 974 | st->state = CPUHP_AP_ONLINE_IDLE; |
797 | complete(&st->done); | 975 | complete_ap_thread(st, true); |
798 | } | 976 | } |
799 | 977 | ||
800 | /* Requires cpu_add_remove_lock to be held */ | 978 | /* Requires cpu_add_remove_lock to be held */ |
@@ -829,7 +1007,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target) | |||
829 | 1007 | ||
830 | cpuhp_tasks_frozen = tasks_frozen; | 1008 | cpuhp_tasks_frozen = tasks_frozen; |
831 | 1009 | ||
832 | st->target = target; | 1010 | cpuhp_set_state(st, target); |
833 | /* | 1011 | /* |
834 | * If the current CPU state is in the range of the AP hotplug thread, | 1012 | * If the current CPU state is in the range of the AP hotplug thread, |
835 | * then we need to kick the thread once more. | 1013 | * then we need to kick the thread once more. |
@@ -1296,6 +1474,10 @@ static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup, | |||
1296 | struct cpuhp_step *sp = cpuhp_get_step(state); | 1474 | struct cpuhp_step *sp = cpuhp_get_step(state); |
1297 | int ret; | 1475 | int ret; |
1298 | 1476 | ||
1477 | /* | ||
1478 | * If there's nothing to do, we done. | ||
1479 | * Relies on the union for multi_instance. | ||
1480 | */ | ||
1299 | if ((bringup && !sp->startup.single) || | 1481 | if ((bringup && !sp->startup.single) || |
1300 | (!bringup && !sp->teardown.single)) | 1482 | (!bringup && !sp->teardown.single)) |
1301 | return 0; | 1483 | return 0; |
@@ -1307,9 +1489,9 @@ static int cpuhp_issue_call(int cpu, enum cpuhp_state state, bool bringup, | |||
1307 | if (cpuhp_is_ap_state(state)) | 1489 | if (cpuhp_is_ap_state(state)) |
1308 | ret = cpuhp_invoke_ap_callback(cpu, state, bringup, node); | 1490 | ret = cpuhp_invoke_ap_callback(cpu, state, bringup, node); |
1309 | else | 1491 | else |
1310 | ret = cpuhp_invoke_callback(cpu, state, bringup, node); | 1492 | ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL); |
1311 | #else | 1493 | #else |
1312 | ret = cpuhp_invoke_callback(cpu, state, bringup, node); | 1494 | ret = cpuhp_invoke_callback(cpu, state, bringup, node, NULL); |
1313 | #endif | 1495 | #endif |
1314 | BUG_ON(ret && !bringup); | 1496 | BUG_ON(ret && !bringup); |
1315 | return ret; | 1497 | return ret; |
@@ -1641,9 +1823,55 @@ static ssize_t show_cpuhp_target(struct device *dev, | |||
1641 | } | 1823 | } |
1642 | static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target); | 1824 | static DEVICE_ATTR(target, 0644, show_cpuhp_target, write_cpuhp_target); |
1643 | 1825 | ||
1826 | |||
1827 | static ssize_t write_cpuhp_fail(struct device *dev, | ||
1828 | struct device_attribute *attr, | ||
1829 | const char *buf, size_t count) | ||
1830 | { | ||
1831 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id); | ||
1832 | struct cpuhp_step *sp; | ||
1833 | int fail, ret; | ||
1834 | |||
1835 | ret = kstrtoint(buf, 10, &fail); | ||
1836 | if (ret) | ||
1837 | return ret; | ||
1838 | |||
1839 | /* | ||
1840 | * Cannot fail STARTING/DYING callbacks. | ||
1841 | */ | ||
1842 | if (cpuhp_is_atomic_state(fail)) | ||
1843 | return -EINVAL; | ||
1844 | |||
1845 | /* | ||
1846 | * Cannot fail anything that doesn't have callbacks. | ||
1847 | */ | ||
1848 | mutex_lock(&cpuhp_state_mutex); | ||
1849 | sp = cpuhp_get_step(fail); | ||
1850 | if (!sp->startup.single && !sp->teardown.single) | ||
1851 | ret = -EINVAL; | ||
1852 | mutex_unlock(&cpuhp_state_mutex); | ||
1853 | if (ret) | ||
1854 | return ret; | ||
1855 | |||
1856 | st->fail = fail; | ||
1857 | |||
1858 | return count; | ||
1859 | } | ||
1860 | |||
1861 | static ssize_t show_cpuhp_fail(struct device *dev, | ||
1862 | struct device_attribute *attr, char *buf) | ||
1863 | { | ||
1864 | struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, dev->id); | ||
1865 | |||
1866 | return sprintf(buf, "%d\n", st->fail); | ||
1867 | } | ||
1868 | |||
1869 | static DEVICE_ATTR(fail, 0644, show_cpuhp_fail, write_cpuhp_fail); | ||
1870 | |||
1644 | static struct attribute *cpuhp_cpu_attrs[] = { | 1871 | static struct attribute *cpuhp_cpu_attrs[] = { |
1645 | &dev_attr_state.attr, | 1872 | &dev_attr_state.attr, |
1646 | &dev_attr_target.attr, | 1873 | &dev_attr_target.attr, |
1874 | &dev_attr_fail.attr, | ||
1647 | NULL | 1875 | NULL |
1648 | }; | 1876 | }; |
1649 | 1877 | ||