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 ...
This commit is contained in:
@@ -688,30 +688,29 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(arm_pmu_mutex);
|
||||
static LIST_HEAD(arm_pmu_list);
|
||||
|
||||
/*
|
||||
* PMU hardware loses all context when a CPU goes offline.
|
||||
* When a CPU is hotplugged back in, since some hardware registers are
|
||||
* UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
|
||||
* junk values out of them.
|
||||
*/
|
||||
static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
|
||||
void *hcpu)
|
||||
static int arm_perf_starting_cpu(unsigned int cpu)
|
||||
{
|
||||
int cpu = (unsigned long)hcpu;
|
||||
struct arm_pmu *pmu = container_of(b, struct arm_pmu, hotplug_nb);
|
||||
struct arm_pmu *pmu;
|
||||
|
||||
if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
|
||||
return NOTIFY_DONE;
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
list_for_each_entry(pmu, &arm_pmu_list, entry) {
|
||||
|
||||
if (!cpumask_test_cpu(cpu, &pmu->supported_cpus))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (pmu->reset)
|
||||
pmu->reset(pmu);
|
||||
else
|
||||
return NOTIFY_DONE;
|
||||
|
||||
return NOTIFY_OK;
|
||||
if (!cpumask_test_cpu(cpu, &pmu->supported_cpus))
|
||||
continue;
|
||||
if (pmu->reset)
|
||||
pmu->reset(pmu);
|
||||
}
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_PM
|
||||
@@ -822,10 +821,9 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu)
|
||||
if (!cpu_hw_events)
|
||||
return -ENOMEM;
|
||||
|
||||
cpu_pmu->hotplug_nb.notifier_call = cpu_pmu_notify;
|
||||
err = register_cpu_notifier(&cpu_pmu->hotplug_nb);
|
||||
if (err)
|
||||
goto out_hw_events;
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
list_add_tail(&cpu_pmu->entry, &arm_pmu_list);
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
|
||||
err = cpu_pm_pmu_register(cpu_pmu);
|
||||
if (err)
|
||||
@@ -861,8 +859,9 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu)
|
||||
return 0;
|
||||
|
||||
out_unregister:
|
||||
unregister_cpu_notifier(&cpu_pmu->hotplug_nb);
|
||||
out_hw_events:
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
list_del(&cpu_pmu->entry);
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
free_percpu(cpu_hw_events);
|
||||
return err;
|
||||
}
|
||||
@@ -870,7 +869,9 @@ out_hw_events:
|
||||
static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu)
|
||||
{
|
||||
cpu_pm_pmu_unregister(cpu_pmu);
|
||||
unregister_cpu_notifier(&cpu_pmu->hotplug_nb);
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
list_del(&cpu_pmu->entry);
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
free_percpu(cpu_pmu->hw_events);
|
||||
}
|
||||
|
||||
@@ -1061,3 +1062,17 @@ out_free:
|
||||
kfree(pmu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int arm_pmu_hp_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_STARTING,
|
||||
"AP_PERF_ARM_STARTING",
|
||||
arm_perf_starting_cpu, NULL);
|
||||
if (ret)
|
||||
pr_err("CPU hotplug notifier for ARM PMU could not be registered: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
subsys_initcall(arm_pmu_hp_init);
|
||||
|
Reference in New Issue
Block a user