Skip to content

Commit a6408f6

Browse files
committed
Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull smp hotplug updates from Thomas Gleixner: "This is the next part of the hotplug rework. - Convert all notifiers with a priority assigned - Convert all CPU_STARTING/DYING notifiers The final removal of the STARTING/DYING infrastructure will happen when the merge window closes. Another 700 hundred line of unpenetrable maze gone :)" * 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits) timers/core: Correct callback order during CPU hot plug leds/trigger/cpu: Move from CPU_STARTING to ONLINE level powerpc/numa: Convert to hotplug state machine arm/perf: Fix hotplug state machine conversion irqchip/armada: Avoid unused function warnings ARC/time: Convert to hotplug state machine clocksource/atlas7: Convert to hotplug state machine clocksource/armada-370-xp: Convert to hotplug state machine clocksource/exynos_mct: Convert to hotplug state machine clocksource/arm_global_timer: Convert to hotplug state machine rcu: Convert rcutree to hotplug state machine KVM/arm/arm64/vgic-new: Convert to hotplug state machine smp/cfd: Convert core to hotplug state machine x86/x2apic: Convert to CPU hotplug state machine profile: Convert to hotplug state machine timers/core: Convert to hotplug state machine hrtimer: Convert to hotplug state machine x86/tboot: Convert to hotplug state machine arm64/armv8 deprecated: Convert to hotplug state machine hwtracing/coresight-etm4x: Convert to hotplug state machine ...
2 parents 1a81a8f + 4fae16d commit a6408f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1316
-2013
lines changed

arch/arc/kernel/time.c

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -296,30 +296,23 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
296296
return IRQ_HANDLED;
297297
}
298298

299-
static int arc_timer_cpu_notify(struct notifier_block *self,
300-
unsigned long action, void *hcpu)
299+
300+
static int arc_timer_starting_cpu(unsigned int cpu)
301301
{
302302
struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
303303

304304
evt->cpumask = cpumask_of(smp_processor_id());
305305

306-
switch (action & ~CPU_TASKS_FROZEN) {
307-
case CPU_STARTING:
308-
clockevents_config_and_register(evt, arc_timer_freq,
309-
0, ULONG_MAX);
310-
enable_percpu_irq(arc_timer_irq, 0);
311-
break;
312-
case CPU_DYING:
313-
disable_percpu_irq(arc_timer_irq);
314-
break;
315-
}
316-
317-
return NOTIFY_OK;
306+
clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
307+
enable_percpu_irq(arc_timer_irq, 0);
308+
return 0;
318309
}
319310

320-
static struct notifier_block arc_timer_cpu_nb = {
321-
.notifier_call = arc_timer_cpu_notify,
322-
};
311+
static int arc_timer_dying_cpu(unsigned int cpu)
312+
{
313+
disable_percpu_irq(arc_timer_irq);
314+
return 0;
315+
}
323316

324317
/*
325318
* clockevent setup for boot CPU
@@ -329,12 +322,6 @@ static int __init arc_clockevent_setup(struct device_node *node)
329322
struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
330323
int ret;
331324

332-
ret = register_cpu_notifier(&arc_timer_cpu_nb);
333-
if (ret) {
334-
pr_err("Failed to register cpu notifier");
335-
return ret;
336-
}
337-
338325
arc_timer_irq = irq_of_parse_and_map(node, 0);
339326
if (arc_timer_irq <= 0) {
340327
pr_err("clockevent: missing irq");
@@ -347,11 +334,6 @@ static int __init arc_clockevent_setup(struct device_node *node)
347334
return ret;
348335
}
349336

350-
evt->irq = arc_timer_irq;
351-
evt->cpumask = cpumask_of(smp_processor_id());
352-
clockevents_config_and_register(evt, arc_timer_freq,
353-
0, ARC_TIMER_MAX);
354-
355337
/* Needs apriori irq_set_percpu_devid() done in intc map function */
356338
ret = request_percpu_irq(arc_timer_irq, timer_irq_handler,
357339
"Timer0 (per-cpu-tick)", evt);
@@ -360,8 +342,14 @@ static int __init arc_clockevent_setup(struct device_node *node)
360342
return ret;
361343
}
362344

363-
enable_percpu_irq(arc_timer_irq, 0);
364-
345+
ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING,
346+
"AP_ARC_TIMER_STARTING",
347+
arc_timer_starting_cpu,
348+
arc_timer_dying_cpu);
349+
if (ret) {
350+
pr_err("Failed to setup hotplug state");
351+
return ret;
352+
}
365353
return 0;
366354
}
367355

arch/arm/kernel/smp_twd.c

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -310,24 +310,17 @@ static void twd_timer_setup(void)
310310
enable_percpu_irq(clk->irq, 0);
311311
}
312312

313-
static int twd_timer_cpu_notify(struct notifier_block *self,
314-
unsigned long action, void *hcpu)
313+
static int twd_timer_starting_cpu(unsigned int cpu)
315314
{
316-
switch (action & ~CPU_TASKS_FROZEN) {
317-
case CPU_STARTING:
318-
twd_timer_setup();
319-
break;
320-
case CPU_DYING:
321-
twd_timer_stop();
322-
break;
323-
}
324-
325-
return NOTIFY_OK;
315+
twd_timer_setup();
316+
return 0;
326317
}
327318

328-
static struct notifier_block twd_timer_cpu_nb = {
329-
.notifier_call = twd_timer_cpu_notify,
330-
};
319+
static int twd_timer_dying_cpu(unsigned int cpu)
320+
{
321+
twd_timer_stop();
322+
return 0;
323+
}
331324

332325
static int __init twd_local_timer_common_register(struct device_node *np)
333326
{
@@ -345,9 +338,9 @@ static int __init twd_local_timer_common_register(struct device_node *np)
345338
goto out_free;
346339
}
347340

348-
err = register_cpu_notifier(&twd_timer_cpu_nb);
349-
if (err)
350-
goto out_irq;
341+
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_TWD_STARTING,
342+
"AP_ARM_TWD_STARTING",
343+
twd_timer_starting_cpu, twd_timer_dying_cpu);
351344

352345
twd_get_clock(np);
353346
if (!of_property_read_bool(np, "always-on"))
@@ -365,8 +358,6 @@ static int __init twd_local_timer_common_register(struct device_node *np)
365358

366359
return 0;
367360

368-
out_irq:
369-
free_percpu_irq(twd_ppi, twd_evt);
370361
out_free:
371362
iounmap(twd_base);
372363
twd_base = NULL;

arch/arm/mach-mvebu/coherency.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,12 @@ static struct notifier_block mvebu_hwcc_pci_nb __maybe_unused = {
111111
.notifier_call = mvebu_hwcc_notifier,
112112
};
113113

114-
static int armada_xp_clear_shared_l2_notifier_func(struct notifier_block *nfb,
115-
unsigned long action, void *hcpu)
114+
static int armada_xp_clear_l2_starting(unsigned int cpu)
116115
{
117-
if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
118-
armada_xp_clear_shared_l2();
119-
120-
return NOTIFY_OK;
116+
armada_xp_clear_shared_l2();
117+
return 0;
121118
}
122119

123-
static struct notifier_block armada_xp_clear_shared_l2_notifier = {
124-
.notifier_call = armada_xp_clear_shared_l2_notifier_func,
125-
.priority = 100,
126-
};
127-
128120
static void __init armada_370_coherency_init(struct device_node *np)
129121
{
130122
struct resource res;
@@ -155,8 +147,9 @@ static void __init armada_370_coherency_init(struct device_node *np)
155147

156148
of_node_put(cpu_config_np);
157149

158-
register_cpu_notifier(&armada_xp_clear_shared_l2_notifier);
159-
150+
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_MVEBU_COHERENCY,
151+
"AP_ARM_MVEBU_COHERENCY",
152+
armada_xp_clear_l2_starting, NULL);
160153
exit:
161154
set_cpu_coherent();
162155
}

arch/arm/mm/cache-l2x0.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -597,17 +597,16 @@ static void l2c310_configure(void __iomem *base)
597597
L310_POWER_CTRL);
598598
}
599599

600-
static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
600+
static int l2c310_starting_cpu(unsigned int cpu)
601601
{
602-
switch (act & ~CPU_TASKS_FROZEN) {
603-
case CPU_STARTING:
604-
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
605-
break;
606-
case CPU_DYING:
607-
set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
608-
break;
609-
}
610-
return NOTIFY_OK;
602+
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
603+
return 0;
604+
}
605+
606+
static int l2c310_dying_cpu(unsigned int cpu)
607+
{
608+
set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
609+
return 0;
611610
}
612611

613612
static void __init l2c310_enable(void __iomem *base, unsigned num_lock)
@@ -678,10 +677,10 @@ static void __init l2c310_enable(void __iomem *base, unsigned num_lock)
678677
power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
679678
}
680679

681-
if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
682-
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
683-
cpu_notifier(l2c310_cpu_enable_flz, 0);
684-
}
680+
if (aux & L310_AUX_CTRL_FULL_LINE_ZERO)
681+
cpuhp_setup_state(CPUHP_AP_ARM_L2X0_STARTING,
682+
"AP_ARM_L2X0_STARTING", l2c310_starting_cpu,
683+
l2c310_dying_cpu);
685684
}
686685

687686
static void __init l2c310_fixup(void __iomem *base, u32 cache_id,

arch/arm/vfp/vfpmodule.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -643,19 +643,19 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
643643
* hardware state at every thread switch. We clear our held state when
644644
* a CPU has been killed, indicating that the VFP hardware doesn't contain
645645
* a threads VFP state. When a CPU starts up, we re-enable access to the
646-
* VFP hardware.
647-
*
648-
* Both CPU_DYING and CPU_STARTING are called on the CPU which
646+
* VFP hardware. The callbacks below are called on the CPU which
649647
* is being offlined/onlined.
650648
*/
651-
static int vfp_hotplug(struct notifier_block *b, unsigned long action,
652-
void *hcpu)
649+
static int vfp_dying_cpu(unsigned int cpu)
653650
{
654-
if (action == CPU_DYING || action == CPU_DYING_FROZEN)
655-
vfp_current_hw_state[(long)hcpu] = NULL;
656-
else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
657-
vfp_enable(NULL);
658-
return NOTIFY_OK;
651+
vfp_force_reload(cpu, current_thread_info());
652+
return 0;
653+
}
654+
655+
static int vfp_starting_cpu(unsigned int unused)
656+
{
657+
vfp_enable(NULL);
658+
return 0;
659659
}
660660

661661
void vfp_kmode_exception(void)
@@ -732,6 +732,10 @@ static int __init vfp_init(void)
732732
unsigned int vfpsid;
733733
unsigned int cpu_arch = cpu_architecture();
734734

735+
/*
736+
* Enable the access to the VFP on all online CPUs so the
737+
* following test on FPSID will succeed.
738+
*/
735739
if (cpu_arch >= CPU_ARCH_ARMv6)
736740
on_each_cpu(vfp_enable, NULL, 1);
737741

@@ -794,7 +798,9 @@ static int __init vfp_init(void)
794798
VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT;
795799
}
796800

797-
hotcpu_notifier(vfp_hotplug, 0);
801+
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_VFP_STARTING,
802+
"AP_ARM_VFP_STARTING", vfp_starting_cpu,
803+
vfp_dying_cpu);
798804

799805
vfp_vector = vfp_support_entry;
800806

arch/arm/xen/enlighten.c

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,11 @@ static struct notifier_block xen_pvclock_gtod_notifier = {
153153
.notifier_call = xen_pvclock_gtod_notify,
154154
};
155155

156-
static void xen_percpu_init(void)
156+
static int xen_starting_cpu(unsigned int cpu)
157157
{
158158
struct vcpu_register_vcpu_info info;
159159
struct vcpu_info *vcpup;
160160
int err;
161-
int cpu = get_cpu();
162161

163162
/*
164163
* VCPUOP_register_vcpu_info cannot be called twice for the same
@@ -186,7 +185,13 @@ static void xen_percpu_init(void)
186185

187186
after_register_vcpu_info:
188187
enable_percpu_irq(xen_events_irq, 0);
189-
put_cpu();
188+
return 0;
189+
}
190+
191+
static int xen_dying_cpu(unsigned int cpu)
192+
{
193+
disable_percpu_irq(xen_events_irq);
194+
return 0;
190195
}
191196

192197
static void xen_restart(enum reboot_mode reboot_mode, const char *cmd)
@@ -205,28 +210,6 @@ static void xen_power_off(void)
205210
BUG_ON(rc);
206211
}
207212

208-
static int xen_cpu_notification(struct notifier_block *self,
209-
unsigned long action,
210-
void *hcpu)
211-
{
212-
switch (action) {
213-
case CPU_STARTING:
214-
xen_percpu_init();
215-
break;
216-
case CPU_DYING:
217-
disable_percpu_irq(xen_events_irq);
218-
break;
219-
default:
220-
break;
221-
}
222-
223-
return NOTIFY_OK;
224-
}
225-
226-
static struct notifier_block xen_cpu_notifier = {
227-
.notifier_call = xen_cpu_notification,
228-
};
229-
230213
static irqreturn_t xen_arm_callback(int irq, void *arg)
231214
{
232215
xen_hvm_evtchn_do_upcall();
@@ -425,16 +408,14 @@ static int __init xen_guest_init(void)
425408
return -EINVAL;
426409
}
427410

428-
xen_percpu_init();
429-
430-
register_cpu_notifier(&xen_cpu_notifier);
431-
432411
xen_time_setup_guest();
433412

434413
if (xen_initial_domain())
435414
pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);
436415

437-
return 0;
416+
return cpuhp_setup_state(CPUHP_AP_ARM_XEN_STARTING,
417+
"AP_ARM_XEN_STARTING", xen_starting_cpu,
418+
xen_dying_cpu);
438419
}
439420
early_initcall(xen_guest_init);
440421

arch/arm64/kernel/armv8_deprecated.c

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool enable)
121121
* 0 - If all the hooks ran successfully.
122122
* -EINVAL - At least one hook is not supported by the CPU.
123123
*/
124-
static int run_all_insn_set_hw_mode(unsigned long cpu)
124+
static int run_all_insn_set_hw_mode(unsigned int cpu)
125125
{
126126
int rc = 0;
127127
unsigned long flags;
@@ -131,7 +131,7 @@ static int run_all_insn_set_hw_mode(unsigned long cpu)
131131
list_for_each_entry(insn, &insn_emulation, node) {
132132
bool enable = (insn->current_mode == INSN_HW);
133133
if (insn->ops->set_hw_mode && insn->ops->set_hw_mode(enable)) {
134-
pr_warn("CPU[%ld] cannot support the emulation of %s",
134+
pr_warn("CPU[%u] cannot support the emulation of %s",
135135
cpu, insn->ops->name);
136136
rc = -EINVAL;
137137
}
@@ -611,20 +611,6 @@ static struct insn_emulation_ops setend_ops = {
611611
.set_hw_mode = setend_set_hw_mode,
612612
};
613613

614-
static int insn_cpu_hotplug_notify(struct notifier_block *b,
615-
unsigned long action, void *hcpu)
616-
{
617-
int rc = 0;
618-
if ((action & ~CPU_TASKS_FROZEN) == CPU_STARTING)
619-
rc = run_all_insn_set_hw_mode((unsigned long)hcpu);
620-
621-
return notifier_from_errno(rc);
622-
}
623-
624-
static struct notifier_block insn_cpu_hotplug_notifier = {
625-
.notifier_call = insn_cpu_hotplug_notify,
626-
};
627-
628614
/*
629615
* Invoked as late_initcall, since not needed before init spawned.
630616
*/
@@ -643,7 +629,9 @@ static int __init armv8_deprecated_init(void)
643629
pr_info("setend instruction emulation is not supported on the system");
644630
}
645631

646-
register_cpu_notifier(&insn_cpu_hotplug_notifier);
632+
cpuhp_setup_state_nocalls(CPUHP_AP_ARM64_ISNDEP_STARTING,
633+
"AP_ARM64_ISNDEP_STARTING",
634+
run_all_insn_set_hw_mode, NULL);
647635
register_insn_emulation_sysctl(ctl_abi);
648636

649637
return 0;

0 commit comments

Comments
 (0)