Skip to content

Commit

Permalink
Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…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
  ...
  • Loading branch information
torvalds committed Jul 29, 2016
2 parents 1a81a8f + 4fae16d commit a6408f6
Show file tree
Hide file tree
Showing 75 changed files with 1,316 additions and 2,013 deletions.
48 changes: 18 additions & 30 deletions arch/arc/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,30 +296,23 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}

static int arc_timer_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)

static int arc_timer_starting_cpu(unsigned int cpu)
{
struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);

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

switch (action & ~CPU_TASKS_FROZEN) {
case CPU_STARTING:
clockevents_config_and_register(evt, arc_timer_freq,
0, ULONG_MAX);
enable_percpu_irq(arc_timer_irq, 0);
break;
case CPU_DYING:
disable_percpu_irq(arc_timer_irq);
break;
}

return NOTIFY_OK;
clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
enable_percpu_irq(arc_timer_irq, 0);
return 0;
}

static struct notifier_block arc_timer_cpu_nb = {
.notifier_call = arc_timer_cpu_notify,
};
static int arc_timer_dying_cpu(unsigned int cpu)
{
disable_percpu_irq(arc_timer_irq);
return 0;
}

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

ret = register_cpu_notifier(&arc_timer_cpu_nb);
if (ret) {
pr_err("Failed to register cpu notifier");
return ret;
}

arc_timer_irq = irq_of_parse_and_map(node, 0);
if (arc_timer_irq <= 0) {
pr_err("clockevent: missing irq");
Expand All @@ -347,11 +334,6 @@ static int __init arc_clockevent_setup(struct device_node *node)
return ret;
}

evt->irq = arc_timer_irq;
evt->cpumask = cpumask_of(smp_processor_id());
clockevents_config_and_register(evt, arc_timer_freq,
0, ARC_TIMER_MAX);

/* Needs apriori irq_set_percpu_devid() done in intc map function */
ret = request_percpu_irq(arc_timer_irq, timer_irq_handler,
"Timer0 (per-cpu-tick)", evt);
Expand All @@ -360,8 +342,14 @@ static int __init arc_clockevent_setup(struct device_node *node)
return ret;
}

enable_percpu_irq(arc_timer_irq, 0);

ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING,
"AP_ARC_TIMER_STARTING",
arc_timer_starting_cpu,
arc_timer_dying_cpu);
if (ret) {
pr_err("Failed to setup hotplug state");
return ret;
}
return 0;
}

Expand Down
31 changes: 11 additions & 20 deletions arch/arm/kernel/smp_twd.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,24 +310,17 @@ static void twd_timer_setup(void)
enable_percpu_irq(clk->irq, 0);
}

static int twd_timer_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
static int twd_timer_starting_cpu(unsigned int cpu)
{
switch (action & ~CPU_TASKS_FROZEN) {
case CPU_STARTING:
twd_timer_setup();
break;
case CPU_DYING:
twd_timer_stop();
break;
}

return NOTIFY_OK;
twd_timer_setup();
return 0;
}

static struct notifier_block twd_timer_cpu_nb = {
.notifier_call = twd_timer_cpu_notify,
};
static int twd_timer_dying_cpu(unsigned int cpu)
{
twd_timer_stop();
return 0;
}

static int __init twd_local_timer_common_register(struct device_node *np)
{
Expand All @@ -345,9 +338,9 @@ static int __init twd_local_timer_common_register(struct device_node *np)
goto out_free;
}

err = register_cpu_notifier(&twd_timer_cpu_nb);
if (err)
goto out_irq;
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_TWD_STARTING,
"AP_ARM_TWD_STARTING",
twd_timer_starting_cpu, twd_timer_dying_cpu);

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

return 0;

out_irq:
free_percpu_irq(twd_ppi, twd_evt);
out_free:
iounmap(twd_base);
twd_base = NULL;
Expand Down
19 changes: 6 additions & 13 deletions arch/arm/mach-mvebu/coherency.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,12 @@ static struct notifier_block mvebu_hwcc_pci_nb __maybe_unused = {
.notifier_call = mvebu_hwcc_notifier,
};

static int armada_xp_clear_shared_l2_notifier_func(struct notifier_block *nfb,
unsigned long action, void *hcpu)
static int armada_xp_clear_l2_starting(unsigned int cpu)
{
if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
armada_xp_clear_shared_l2();

return NOTIFY_OK;
armada_xp_clear_shared_l2();
return 0;
}

static struct notifier_block armada_xp_clear_shared_l2_notifier = {
.notifier_call = armada_xp_clear_shared_l2_notifier_func,
.priority = 100,
};

static void __init armada_370_coherency_init(struct device_node *np)
{
struct resource res;
Expand Down Expand Up @@ -155,8 +147,9 @@ static void __init armada_370_coherency_init(struct device_node *np)

of_node_put(cpu_config_np);

register_cpu_notifier(&armada_xp_clear_shared_l2_notifier);

cpuhp_setup_state_nocalls(CPUHP_AP_ARM_MVEBU_COHERENCY,
"AP_ARM_MVEBU_COHERENCY",
armada_xp_clear_l2_starting, NULL);
exit:
set_cpu_coherent();
}
Expand Down
27 changes: 13 additions & 14 deletions arch/arm/mm/cache-l2x0.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,17 +597,16 @@ static void l2c310_configure(void __iomem *base)
L310_POWER_CTRL);
}

static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
static int l2c310_starting_cpu(unsigned int cpu)
{
switch (act & ~CPU_TASKS_FROZEN) {
case CPU_STARTING:
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
break;
case CPU_DYING:
set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
break;
}
return NOTIFY_OK;
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
return 0;
}

static int l2c310_dying_cpu(unsigned int cpu)
{
set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
return 0;
}

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

if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
cpu_notifier(l2c310_cpu_enable_flz, 0);
}
if (aux & L310_AUX_CTRL_FULL_LINE_ZERO)
cpuhp_setup_state(CPUHP_AP_ARM_L2X0_STARTING,
"AP_ARM_L2X0_STARTING", l2c310_starting_cpu,
l2c310_dying_cpu);
}

static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
Expand Down
28 changes: 17 additions & 11 deletions arch/arm/vfp/vfpmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,19 +643,19 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
* hardware state at every thread switch. We clear our held state when
* a CPU has been killed, indicating that the VFP hardware doesn't contain
* a threads VFP state. When a CPU starts up, we re-enable access to the
* VFP hardware.
*
* Both CPU_DYING and CPU_STARTING are called on the CPU which
* VFP hardware. The callbacks below are called on the CPU which
* is being offlined/onlined.
*/
static int vfp_hotplug(struct notifier_block *b, unsigned long action,
void *hcpu)
static int vfp_dying_cpu(unsigned int cpu)
{
if (action == CPU_DYING || action == CPU_DYING_FROZEN)
vfp_current_hw_state[(long)hcpu] = NULL;
else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
vfp_enable(NULL);
return NOTIFY_OK;
vfp_force_reload(cpu, current_thread_info());
return 0;
}

static int vfp_starting_cpu(unsigned int unused)
{
vfp_enable(NULL);
return 0;
}

void vfp_kmode_exception(void)
Expand Down Expand Up @@ -732,6 +732,10 @@ static int __init vfp_init(void)
unsigned int vfpsid;
unsigned int cpu_arch = cpu_architecture();

/*
* Enable the access to the VFP on all online CPUs so the
* following test on FPSID will succeed.
*/
if (cpu_arch >= CPU_ARCH_ARMv6)
on_each_cpu(vfp_enable, NULL, 1);

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

hotcpu_notifier(vfp_hotplug, 0);
cpuhp_setup_state_nocalls(CPUHP_AP_ARM_VFP_STARTING,
"AP_ARM_VFP_STARTING", vfp_starting_cpu,
vfp_dying_cpu);

vfp_vector = vfp_support_entry;

Expand Down
41 changes: 11 additions & 30 deletions arch/arm/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,11 @@ static struct notifier_block xen_pvclock_gtod_notifier = {
.notifier_call = xen_pvclock_gtod_notify,
};

static void xen_percpu_init(void)
static int xen_starting_cpu(unsigned int cpu)
{
struct vcpu_register_vcpu_info info;
struct vcpu_info *vcpup;
int err;
int cpu = get_cpu();

/*
* VCPUOP_register_vcpu_info cannot be called twice for the same
Expand Down Expand Up @@ -186,7 +185,13 @@ static void xen_percpu_init(void)

after_register_vcpu_info:
enable_percpu_irq(xen_events_irq, 0);
put_cpu();
return 0;
}

static int xen_dying_cpu(unsigned int cpu)
{
disable_percpu_irq(xen_events_irq);
return 0;
}

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

static int xen_cpu_notification(struct notifier_block *self,
unsigned long action,
void *hcpu)
{
switch (action) {
case CPU_STARTING:
xen_percpu_init();
break;
case CPU_DYING:
disable_percpu_irq(xen_events_irq);
break;
default:
break;
}

return NOTIFY_OK;
}

static struct notifier_block xen_cpu_notifier = {
.notifier_call = xen_cpu_notification,
};

static irqreturn_t xen_arm_callback(int irq, void *arg)
{
xen_hvm_evtchn_do_upcall();
Expand Down Expand Up @@ -425,16 +408,14 @@ static int __init xen_guest_init(void)
return -EINVAL;
}

xen_percpu_init();

register_cpu_notifier(&xen_cpu_notifier);

xen_time_setup_guest();

if (xen_initial_domain())
pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);

return 0;
return cpuhp_setup_state(CPUHP_AP_ARM_XEN_STARTING,
"AP_ARM_XEN_STARTING", xen_starting_cpu,
xen_dying_cpu);
}
early_initcall(xen_guest_init);

Expand Down
22 changes: 5 additions & 17 deletions arch/arm64/kernel/armv8_deprecated.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool enable)
* 0 - If all the hooks ran successfully.
* -EINVAL - At least one hook is not supported by the CPU.
*/
static int run_all_insn_set_hw_mode(unsigned long cpu)
static int run_all_insn_set_hw_mode(unsigned int cpu)
{
int rc = 0;
unsigned long flags;
Expand All @@ -131,7 +131,7 @@ static int run_all_insn_set_hw_mode(unsigned long cpu)
list_for_each_entry(insn, &insn_emulation, node) {
bool enable = (insn->current_mode == INSN_HW);
if (insn->ops->set_hw_mode && insn->ops->set_hw_mode(enable)) {
pr_warn("CPU[%ld] cannot support the emulation of %s",
pr_warn("CPU[%u] cannot support the emulation of %s",
cpu, insn->ops->name);
rc = -EINVAL;
}
Expand Down Expand Up @@ -611,20 +611,6 @@ static struct insn_emulation_ops setend_ops = {
.set_hw_mode = setend_set_hw_mode,
};

static int insn_cpu_hotplug_notify(struct notifier_block *b,
unsigned long action, void *hcpu)
{
int rc = 0;
if ((action & ~CPU_TASKS_FROZEN) == CPU_STARTING)
rc = run_all_insn_set_hw_mode((unsigned long)hcpu);

return notifier_from_errno(rc);
}

static struct notifier_block insn_cpu_hotplug_notifier = {
.notifier_call = insn_cpu_hotplug_notify,
};

/*
* Invoked as late_initcall, since not needed before init spawned.
*/
Expand All @@ -643,7 +629,9 @@ static int __init armv8_deprecated_init(void)
pr_info("setend instruction emulation is not supported on the system");
}

register_cpu_notifier(&insn_cpu_hotplug_notifier);
cpuhp_setup_state_nocalls(CPUHP_AP_ARM64_ISNDEP_STARTING,
"AP_ARM64_ISNDEP_STARTING",
run_all_insn_set_hw_mode, NULL);
register_insn_emulation_sysctl(ctl_abi);

return 0;
Expand Down
Loading

0 comments on commit a6408f6

Please sign in to comment.