Skip to content

Commit 0e59732

Browse files
committed
Merge tag 'smp-urgent-2022-04-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull SMP fixes from Thomas Gleixner: "Two fixes for the SMP core: - Make the warning condition in flush_smp_call_function_queue() correct, which checked a just emptied list head for being empty instead of validating that there was no pending entry on the offlined CPU at all. - The @cpu member of struct cpuhp_cpu_state is initialized when the CPU hotplug thread for the upcoming CPU is created. That's too late because the creation of the thread can fail and then the following rollback operates on CPU0. Get rid of the CPU member and hand the CPU number to the involved functions directly" * tag 'smp-urgent-2022-04-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: cpu/hotplug: Remove the 'cpu' member of cpuhp_cpu_state smp: Fix offline cpu check in flush_smp_call_function_queue()
2 parents 7e1777f + b7ba6d8 commit 0e59732

File tree

2 files changed

+19
-19
lines changed

2 files changed

+19
-19
lines changed

kernel/cpu.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ struct cpuhp_cpu_state {
7171
bool rollback;
7272
bool single;
7373
bool bringup;
74-
int cpu;
7574
struct hlist_node *node;
7675
struct hlist_node *last;
7776
enum cpuhp_state cb_state;
@@ -475,7 +474,7 @@ static inline bool cpu_smt_allowed(unsigned int cpu) { return true; }
475474
#endif
476475

477476
static inline enum cpuhp_state
478-
cpuhp_set_state(struct cpuhp_cpu_state *st, enum cpuhp_state target)
477+
cpuhp_set_state(int cpu, struct cpuhp_cpu_state *st, enum cpuhp_state target)
479478
{
480479
enum cpuhp_state prev_state = st->state;
481480
bool bringup = st->state < target;
@@ -486,14 +485,15 @@ cpuhp_set_state(struct cpuhp_cpu_state *st, enum cpuhp_state target)
486485
st->target = target;
487486
st->single = false;
488487
st->bringup = bringup;
489-
if (cpu_dying(st->cpu) != !bringup)
490-
set_cpu_dying(st->cpu, !bringup);
488+
if (cpu_dying(cpu) != !bringup)
489+
set_cpu_dying(cpu, !bringup);
491490

492491
return prev_state;
493492
}
494493

495494
static inline void
496-
cpuhp_reset_state(struct cpuhp_cpu_state *st, enum cpuhp_state prev_state)
495+
cpuhp_reset_state(int cpu, struct cpuhp_cpu_state *st,
496+
enum cpuhp_state prev_state)
497497
{
498498
bool bringup = !st->bringup;
499499

@@ -520,8 +520,8 @@ cpuhp_reset_state(struct cpuhp_cpu_state *st, enum cpuhp_state prev_state)
520520
}
521521

522522
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);
525525
}
526526

527527
/* Regular hotplug invocation of the AP hotplug thread */
@@ -541,15 +541,16 @@ static void __cpuhp_kick_ap(struct cpuhp_cpu_state *st)
541541
wait_for_ap_thread(st, st->bringup);
542542
}
543543

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)
545546
{
546547
enum cpuhp_state prev_state;
547548
int ret;
548549

549-
prev_state = cpuhp_set_state(st, target);
550+
prev_state = cpuhp_set_state(cpu, st, target);
550551
__cpuhp_kick_ap(st);
551552
if ((ret = st->result)) {
552-
cpuhp_reset_state(st, prev_state);
553+
cpuhp_reset_state(cpu, st, prev_state);
553554
__cpuhp_kick_ap(st);
554555
}
555556

@@ -581,7 +582,7 @@ static int bringup_wait_for_ap(unsigned int cpu)
581582
if (st->target <= CPUHP_AP_ONLINE_IDLE)
582583
return 0;
583584

584-
return cpuhp_kick_ap(st, st->target);
585+
return cpuhp_kick_ap(cpu, st, st->target);
585586
}
586587

587588
static int bringup_cpu(unsigned int cpu)
@@ -704,7 +705,7 @@ static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
704705
ret, cpu, cpuhp_get_step(st->state)->name,
705706
st->state);
706707

707-
cpuhp_reset_state(st, prev_state);
708+
cpuhp_reset_state(cpu, st, prev_state);
708709
if (can_rollback_cpu(st))
709710
WARN_ON(cpuhp_invoke_callback_range(false, cpu, st,
710711
prev_state));
@@ -721,7 +722,6 @@ static void cpuhp_create(unsigned int cpu)
721722

722723
init_completion(&st->done_up);
723724
init_completion(&st->done_down);
724-
st->cpu = cpu;
725725
}
726726

727727
static int cpuhp_should_run(unsigned int cpu)
@@ -875,7 +875,7 @@ static int cpuhp_kick_ap_work(unsigned int cpu)
875875
cpuhp_lock_release(true);
876876

877877
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);
879879
trace_cpuhp_exit(cpu, st->state, prev_state, ret);
880880

881881
return ret;
@@ -1107,7 +1107,7 @@ static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
11071107
ret, cpu, cpuhp_get_step(st->state)->name,
11081108
st->state);
11091109

1110-
cpuhp_reset_state(st, prev_state);
1110+
cpuhp_reset_state(cpu, st, prev_state);
11111111

11121112
if (st->state < prev_state)
11131113
WARN_ON(cpuhp_invoke_callback_range(true, cpu, st,
@@ -1134,7 +1134,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
11341134

11351135
cpuhp_tasks_frozen = tasks_frozen;
11361136

1137-
prev_state = cpuhp_set_state(st, target);
1137+
prev_state = cpuhp_set_state(cpu, st, target);
11381138
/*
11391139
* If the current CPU state is in the range of the AP hotplug thread,
11401140
* then we need to kick the thread.
@@ -1165,7 +1165,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
11651165
ret = cpuhp_down_callbacks(cpu, st, target);
11661166
if (ret && st->state < prev_state) {
11671167
if (st->state == CPUHP_TEARDOWN_CPU) {
1168-
cpuhp_reset_state(st, prev_state);
1168+
cpuhp_reset_state(cpu, st, prev_state);
11691169
__cpuhp_kick_ap(st);
11701170
} else {
11711171
WARN(1, "DEAD callback error for CPU%d", cpu);
@@ -1352,7 +1352,7 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
13521352

13531353
cpuhp_tasks_frozen = tasks_frozen;
13541354

1355-
cpuhp_set_state(st, target);
1355+
cpuhp_set_state(cpu, st, target);
13561356
/*
13571357
* If the current CPU state is in the range of the AP hotplug thread,
13581358
* then we need to kick the thread once more.

kernel/smp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline)
579579

580580
/* There shouldn't be any pending callbacks on an offline CPU. */
581581
if (unlikely(warn_cpu_offline && !cpu_online(smp_processor_id()) &&
582-
!warned && !llist_empty(head))) {
582+
!warned && entry != NULL)) {
583583
warned = true;
584584
WARN(1, "IPI on offline CPU %d\n", smp_processor_id());
585585

0 commit comments

Comments
 (0)