diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-29 16:55:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-29 16:55:30 -0400 |
commit | a6408f6cb63ac0958fee7dbce7861ffb540d8a49 (patch) | |
tree | c94a835d343974171951e3b805e6bbbb02852ebc /drivers/perf | |
parent | 1a81a8f2a5918956e214bb718099a89e500e7ec5 (diff) | |
parent | 4fae16dffb812f0e0d98a0b2b0856ca48ca63e6c (diff) |
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
...
Diffstat (limited to 'drivers/perf')
-rw-r--r-- | drivers/perf/arm_pmu.c | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 8e4d7f590b06..6ccb994bdfcb 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c | |||
@@ -688,30 +688,29 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler) | |||
688 | return 0; | 688 | return 0; |
689 | } | 689 | } |
690 | 690 | ||
691 | static DEFINE_MUTEX(arm_pmu_mutex); | ||
692 | static LIST_HEAD(arm_pmu_list); | ||
693 | |||
691 | /* | 694 | /* |
692 | * PMU hardware loses all context when a CPU goes offline. | 695 | * PMU hardware loses all context when a CPU goes offline. |
693 | * When a CPU is hotplugged back in, since some hardware registers are | 696 | * When a CPU is hotplugged back in, since some hardware registers are |
694 | * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading | 697 | * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading |
695 | * junk values out of them. | 698 | * junk values out of them. |
696 | */ | 699 | */ |
697 | static int cpu_pmu_notify(struct notifier_block *b, unsigned long action, | 700 | static int arm_perf_starting_cpu(unsigned int cpu) |
698 | void *hcpu) | ||
699 | { | 701 | { |
700 | int cpu = (unsigned long)hcpu; | 702 | struct arm_pmu *pmu; |
701 | struct arm_pmu *pmu = container_of(b, struct arm_pmu, hotplug_nb); | ||
702 | |||
703 | if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING) | ||
704 | return NOTIFY_DONE; | ||
705 | |||
706 | if (!cpumask_test_cpu(cpu, &pmu->supported_cpus)) | ||
707 | return NOTIFY_DONE; | ||
708 | 703 | ||
709 | if (pmu->reset) | 704 | mutex_lock(&arm_pmu_mutex); |
710 | pmu->reset(pmu); | 705 | list_for_each_entry(pmu, &arm_pmu_list, entry) { |
711 | else | ||
712 | return NOTIFY_DONE; | ||
713 | 706 | ||
714 | return NOTIFY_OK; | 707 | if (!cpumask_test_cpu(cpu, &pmu->supported_cpus)) |
708 | continue; | ||
709 | if (pmu->reset) | ||
710 | pmu->reset(pmu); | ||
711 | } | ||
712 | mutex_unlock(&arm_pmu_mutex); | ||
713 | return 0; | ||
715 | } | 714 | } |
716 | 715 | ||
717 | #ifdef CONFIG_CPU_PM | 716 | #ifdef CONFIG_CPU_PM |
@@ -822,10 +821,9 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu) | |||
822 | if (!cpu_hw_events) | 821 | if (!cpu_hw_events) |
823 | return -ENOMEM; | 822 | return -ENOMEM; |
824 | 823 | ||
825 | cpu_pmu->hotplug_nb.notifier_call = cpu_pmu_notify; | 824 | mutex_lock(&arm_pmu_mutex); |
826 | err = register_cpu_notifier(&cpu_pmu->hotplug_nb); | 825 | list_add_tail(&cpu_pmu->entry, &arm_pmu_list); |
827 | if (err) | 826 | mutex_unlock(&arm_pmu_mutex); |
828 | goto out_hw_events; | ||
829 | 827 | ||
830 | err = cpu_pm_pmu_register(cpu_pmu); | 828 | err = cpu_pm_pmu_register(cpu_pmu); |
831 | if (err) | 829 | if (err) |
@@ -861,8 +859,9 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu) | |||
861 | return 0; | 859 | return 0; |
862 | 860 | ||
863 | out_unregister: | 861 | out_unregister: |
864 | unregister_cpu_notifier(&cpu_pmu->hotplug_nb); | 862 | mutex_lock(&arm_pmu_mutex); |
865 | out_hw_events: | 863 | list_del(&cpu_pmu->entry); |
864 | mutex_unlock(&arm_pmu_mutex); | ||
866 | free_percpu(cpu_hw_events); | 865 | free_percpu(cpu_hw_events); |
867 | return err; | 866 | return err; |
868 | } | 867 | } |
@@ -870,7 +869,9 @@ out_hw_events: | |||
870 | static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) | 869 | static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu) |
871 | { | 870 | { |
872 | cpu_pm_pmu_unregister(cpu_pmu); | 871 | cpu_pm_pmu_unregister(cpu_pmu); |
873 | unregister_cpu_notifier(&cpu_pmu->hotplug_nb); | 872 | mutex_lock(&arm_pmu_mutex); |
873 | list_del(&cpu_pmu->entry); | ||
874 | mutex_unlock(&arm_pmu_mutex); | ||
874 | free_percpu(cpu_pmu->hw_events); | 875 | free_percpu(cpu_pmu->hw_events); |
875 | } | 876 | } |
876 | 877 | ||
@@ -1061,3 +1062,17 @@ out_free: | |||
1061 | kfree(pmu); | 1062 | kfree(pmu); |
1062 | return ret; | 1063 | return ret; |
1063 | } | 1064 | } |
1065 | |||
1066 | static int arm_pmu_hp_init(void) | ||
1067 | { | ||
1068 | int ret; | ||
1069 | |||
1070 | ret = cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_STARTING, | ||
1071 | "AP_PERF_ARM_STARTING", | ||
1072 | arm_perf_starting_cpu, NULL); | ||
1073 | if (ret) | ||
1074 | pr_err("CPU hotplug notifier for ARM PMU could not be registered: %d\n", | ||
1075 | ret); | ||
1076 | return ret; | ||
1077 | } | ||
1078 | subsys_initcall(arm_pmu_hp_init); | ||