cpu/hotplug: Remove the 'cpu' member of cpuhp_cpu_state

Currently the setting of the 'cpu' member of struct cpuhp_cpu_state in
cpuhp_create() is too late as it is used earlier in _cpu_up().

If kzalloc_node() in __smpboot_create_thread() fails then the rollback will
be done with st->cpu==0 causing CPU0 to be erroneously set to be dying,
causing the scheduler to get mightily confused and throw its toys out of
the pram.

However the cpu number is actually available directly, so simply remove
the 'cpu' member and avoid the problem in the first place.

Fixes: 2ea46c6fc945 ("cpumask/hotplug: Fix cpu_dying() state tracking")
Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20220411152233.474129-2-steven.price@arm.com

authored by Steven Price and committed by Thomas Gleixner b7ba6d8d 9e949a38

Changed files
+18 -18
kernel
+18 -18
kernel/cpu.c
··· 71 71 bool rollback; 72 72 bool single; 73 73 bool bringup; 74 - int cpu; 75 74 struct hlist_node *node; 76 75 struct hlist_node *last; 77 76 enum cpuhp_state cb_state; ··· 474 475 #endif 475 476 476 477 static inline enum cpuhp_state 477 - cpuhp_set_state(struct cpuhp_cpu_state *st, enum cpuhp_state target) 478 + cpuhp_set_state(int cpu, struct cpuhp_cpu_state *st, enum cpuhp_state target) 478 479 { 479 480 enum cpuhp_state prev_state = st->state; 480 481 bool bringup = st->state < target; ··· 485 486 st->target = target; 486 487 st->single = false; 487 488 st->bringup = bringup; 488 - if (cpu_dying(st->cpu) != !bringup) 489 - set_cpu_dying(st->cpu, !bringup); 489 + if (cpu_dying(cpu) != !bringup) 490 + set_cpu_dying(cpu, !bringup); 490 491 491 492 return prev_state; 492 493 } 493 494 494 495 static inline void 495 - cpuhp_reset_state(struct cpuhp_cpu_state *st, enum cpuhp_state prev_state) 496 + cpuhp_reset_state(int cpu, struct cpuhp_cpu_state *st, 497 + enum cpuhp_state prev_state) 496 498 { 497 499 bool bringup = !st->bringup; 498 500 ··· 520 520 } 521 521 522 522 st->bringup = bringup; 523 - if (cpu_dying(st->cpu) != !bringup) 524 - set_cpu_dying(st->cpu, !bringup); 523 + if (cpu_dying(cpu) != !bringup) 524 + set_cpu_dying(cpu, !bringup); 525 525 } 526 526 527 527 /* Regular hotplug invocation of the AP hotplug thread */ ··· 541 541 wait_for_ap_thread(st, st->bringup); 542 542 } 543 543 544 - static int cpuhp_kick_ap(struct cpuhp_cpu_state *st, enum cpuhp_state target) 544 + static int cpuhp_kick_ap(int cpu, struct cpuhp_cpu_state *st, 545 + enum cpuhp_state target) 545 546 { 546 547 enum cpuhp_state prev_state; 547 548 int ret; 548 549 549 - prev_state = cpuhp_set_state(st, target); 550 + prev_state = cpuhp_set_state(cpu, st, target); 550 551 __cpuhp_kick_ap(st); 551 552 if ((ret = st->result)) { 552 - cpuhp_reset_state(st, prev_state); 553 + cpuhp_reset_state(cpu, st, prev_state); 553 554 __cpuhp_kick_ap(st); 554 555 } 555 556 ··· 582 581 if (st->target <= CPUHP_AP_ONLINE_IDLE) 583 582 return 0; 584 583 585 - return cpuhp_kick_ap(st, st->target); 584 + return cpuhp_kick_ap(cpu, st, st->target); 586 585 } 587 586 588 587 static int bringup_cpu(unsigned int cpu) ··· 705 704 ret, cpu, cpuhp_get_step(st->state)->name, 706 705 st->state); 707 706 708 - cpuhp_reset_state(st, prev_state); 707 + cpuhp_reset_state(cpu, st, prev_state); 709 708 if (can_rollback_cpu(st)) 710 709 WARN_ON(cpuhp_invoke_callback_range(false, cpu, st, 711 710 prev_state)); ··· 722 721 723 722 init_completion(&st->done_up); 724 723 init_completion(&st->done_down); 725 - st->cpu = cpu; 726 724 } 727 725 728 726 static int cpuhp_should_run(unsigned int cpu) ··· 875 875 cpuhp_lock_release(true); 876 876 877 877 trace_cpuhp_enter(cpu, st->target, prev_state, cpuhp_kick_ap_work); 878 - ret = cpuhp_kick_ap(st, st->target); 878 + ret = cpuhp_kick_ap(cpu, st, st->target); 879 879 trace_cpuhp_exit(cpu, st->state, prev_state, ret); 880 880 881 881 return ret; ··· 1107 1107 ret, cpu, cpuhp_get_step(st->state)->name, 1108 1108 st->state); 1109 1109 1110 - cpuhp_reset_state(st, prev_state); 1110 + cpuhp_reset_state(cpu, st, prev_state); 1111 1111 1112 1112 if (st->state < prev_state) 1113 1113 WARN_ON(cpuhp_invoke_callback_range(true, cpu, st, ··· 1134 1134 1135 1135 cpuhp_tasks_frozen = tasks_frozen; 1136 1136 1137 - prev_state = cpuhp_set_state(st, target); 1137 + prev_state = cpuhp_set_state(cpu, st, target); 1138 1138 /* 1139 1139 * If the current CPU state is in the range of the AP hotplug thread, 1140 1140 * then we need to kick the thread. ··· 1165 1165 ret = cpuhp_down_callbacks(cpu, st, target); 1166 1166 if (ret && st->state < prev_state) { 1167 1167 if (st->state == CPUHP_TEARDOWN_CPU) { 1168 - cpuhp_reset_state(st, prev_state); 1168 + cpuhp_reset_state(cpu, st, prev_state); 1169 1169 __cpuhp_kick_ap(st); 1170 1170 } else { 1171 1171 WARN(1, "DEAD callback error for CPU%d", cpu); ··· 1352 1352 1353 1353 cpuhp_tasks_frozen = tasks_frozen; 1354 1354 1355 - cpuhp_set_state(st, target); 1355 + cpuhp_set_state(cpu, st, target); 1356 1356 /* 1357 1357 * If the current CPU state is in the range of the AP hotplug thread, 1358 1358 * then we need to kick the thread once more.