Skip to content

Commit 6b2c284

Browse files
Sebastian Andrzej SiewiorIngo Molnar
authored andcommitted
x86/x2apic: Convert to CPU hotplug state machine
Install the callbacks via the state machine and let the core invoke the callbacks on the already online CPUs. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> Cc: Len Brown <len.brown@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mathias Krause <minipli@googlemail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160713153337.736898691@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent e722d8d commit 6b2c284

File tree

2 files changed

+31
-50
lines changed

2 files changed

+31
-50
lines changed

arch/x86/kernel/apic/x2apic_cluster.c

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -152,68 +152,48 @@ static void init_x2apic_ldr(void)
152152
}
153153
}
154154

155-
/*
156-
* At CPU state changes, update the x2apic cluster sibling info.
157-
*/
158-
static int
159-
update_clusterinfo(struct notifier_block *nfb, unsigned long action, void *hcpu)
155+
/*
156+
* At CPU state changes, update the x2apic cluster sibling info.
157+
*/
158+
int x2apic_prepare_cpu(unsigned int cpu)
160159
{
161-
unsigned int this_cpu = (unsigned long)hcpu;
162-
unsigned int cpu;
163-
int err = 0;
164-
165-
switch (action) {
166-
case CPU_UP_PREPARE:
167-
if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, this_cpu),
168-
GFP_KERNEL)) {
169-
err = -ENOMEM;
170-
} else if (!zalloc_cpumask_var(&per_cpu(ipi_mask, this_cpu),
171-
GFP_KERNEL)) {
172-
free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
173-
err = -ENOMEM;
174-
}
175-
break;
176-
case CPU_UP_CANCELED:
177-
case CPU_UP_CANCELED_FROZEN:
178-
case CPU_DEAD:
179-
for_each_online_cpu(cpu) {
180-
if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu))
181-
continue;
182-
cpumask_clear_cpu(this_cpu, per_cpu(cpus_in_cluster, cpu));
183-
cpumask_clear_cpu(cpu, per_cpu(cpus_in_cluster, this_cpu));
184-
}
185-
free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
186-
free_cpumask_var(per_cpu(ipi_mask, this_cpu));
187-
break;
160+
if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL))
161+
return -ENOMEM;
162+
163+
if (!zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL)) {
164+
free_cpumask_var(per_cpu(cpus_in_cluster, cpu));
165+
return -ENOMEM;
188166
}
189167

190-
return notifier_from_errno(err);
168+
return 0;
191169
}
192170

193-
static struct notifier_block x2apic_cpu_notifier = {
194-
.notifier_call = update_clusterinfo,
195-
};
196-
197-
static int x2apic_init_cpu_notifier(void)
171+
int x2apic_dead_cpu(unsigned int this_cpu)
198172
{
199-
int cpu = smp_processor_id();
200-
201-
zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL);
202-
zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL);
173+
int cpu;
203174

204-
BUG_ON(!per_cpu(cpus_in_cluster, cpu) || !per_cpu(ipi_mask, cpu));
205-
206-
cpumask_set_cpu(cpu, per_cpu(cpus_in_cluster, cpu));
207-
register_hotcpu_notifier(&x2apic_cpu_notifier);
208-
return 1;
175+
for_each_online_cpu(cpu) {
176+
if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu))
177+
continue;
178+
cpumask_clear_cpu(this_cpu, per_cpu(cpus_in_cluster, cpu));
179+
cpumask_clear_cpu(cpu, per_cpu(cpus_in_cluster, this_cpu));
180+
}
181+
free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
182+
free_cpumask_var(per_cpu(ipi_mask, this_cpu));
183+
return 0;
209184
}
210185

211186
static int x2apic_cluster_probe(void)
212187
{
213-
if (x2apic_mode)
214-
return x2apic_init_cpu_notifier();
215-
else
188+
int cpu = smp_processor_id();
189+
190+
if (!x2apic_mode)
216191
return 0;
192+
193+
cpumask_set_cpu(cpu, per_cpu(cpus_in_cluster, cpu));
194+
cpuhp_setup_state(CPUHP_X2APIC_PREPARE, "X2APIC_PREPARE",
195+
x2apic_prepare_cpu, x2apic_dead_cpu);
196+
return 1;
217197
}
218198

219199
static const struct cpumask *x2apic_cluster_target_cpus(void)

include/linux/cpuhotplug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ enum cpuhp_state {
1717
CPUHP_WORKQUEUE_PREP,
1818
CPUHP_HRTIMERS_PREPARE,
1919
CPUHP_PROFILE_PREPARE,
20+
CPUHP_X2APIC_PREPARE,
2021
CPUHP_TIMERS_DEAD,
2122
CPUHP_NOTIFY_PREPARE,
2223
CPUHP_BRINGUP_CPU,

0 commit comments

Comments
 (0)