diff options
Diffstat (limited to 'arch/x86/events/intel/rapl.c')
| -rw-r--r-- | arch/x86/events/intel/rapl.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 17c3564d087a..22ef4f72cf32 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c | |||
| @@ -161,7 +161,13 @@ static u64 rapl_timer_ms; | |||
| 161 | 161 | ||
| 162 | static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu) | 162 | static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu) |
| 163 | { | 163 | { |
| 164 | return rapl_pmus->pmus[topology_logical_package_id(cpu)]; | 164 | unsigned int pkgid = topology_logical_package_id(cpu); |
| 165 | |||
| 166 | /* | ||
| 167 | * The unsigned check also catches the '-1' return value for non | ||
| 168 | * existent mappings in the topology map. | ||
| 169 | */ | ||
| 170 | return pkgid < rapl_pmus->maxpkg ? rapl_pmus->pmus[pkgid] : NULL; | ||
| 165 | } | 171 | } |
| 166 | 172 | ||
| 167 | static inline u64 rapl_read_counter(struct perf_event *event) | 173 | static inline u64 rapl_read_counter(struct perf_event *event) |
| @@ -402,6 +408,8 @@ static int rapl_pmu_event_init(struct perf_event *event) | |||
| 402 | 408 | ||
| 403 | /* must be done before validate_group */ | 409 | /* must be done before validate_group */ |
| 404 | pmu = cpu_to_rapl_pmu(event->cpu); | 410 | pmu = cpu_to_rapl_pmu(event->cpu); |
| 411 | if (!pmu) | ||
| 412 | return -EINVAL; | ||
| 405 | event->cpu = pmu->cpu; | 413 | event->cpu = pmu->cpu; |
| 406 | event->pmu_private = pmu; | 414 | event->pmu_private = pmu; |
| 407 | event->hw.event_base = msr; | 415 | event->hw.event_base = msr; |
| @@ -585,6 +593,20 @@ static int rapl_cpu_online(unsigned int cpu) | |||
| 585 | struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu); | 593 | struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu); |
| 586 | int target; | 594 | int target; |
| 587 | 595 | ||
| 596 | if (!pmu) { | ||
| 597 | pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); | ||
| 598 | if (!pmu) | ||
| 599 | return -ENOMEM; | ||
| 600 | |||
| 601 | raw_spin_lock_init(&pmu->lock); | ||
| 602 | INIT_LIST_HEAD(&pmu->active_list); | ||
| 603 | pmu->pmu = &rapl_pmus->pmu; | ||
| 604 | pmu->timer_interval = ms_to_ktime(rapl_timer_ms); | ||
| 605 | rapl_hrtimer_init(pmu); | ||
| 606 | |||
| 607 | rapl_pmus->pmus[topology_logical_package_id(cpu)] = pmu; | ||
| 608 | } | ||
| 609 | |||
| 588 | /* | 610 | /* |
| 589 | * Check if there is an online cpu in the package which collects rapl | 611 | * Check if there is an online cpu in the package which collects rapl |
| 590 | * events already. | 612 | * events already. |
| @@ -598,27 +620,6 @@ static int rapl_cpu_online(unsigned int cpu) | |||
| 598 | return 0; | 620 | return 0; |
| 599 | } | 621 | } |
| 600 | 622 | ||
| 601 | static int rapl_cpu_prepare(unsigned int cpu) | ||
| 602 | { | ||
| 603 | struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu); | ||
| 604 | |||
| 605 | if (pmu) | ||
| 606 | return 0; | ||
| 607 | |||
| 608 | pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); | ||
| 609 | if (!pmu) | ||
| 610 | return -ENOMEM; | ||
| 611 | |||
| 612 | raw_spin_lock_init(&pmu->lock); | ||
| 613 | INIT_LIST_HEAD(&pmu->active_list); | ||
| 614 | pmu->pmu = &rapl_pmus->pmu; | ||
| 615 | pmu->timer_interval = ms_to_ktime(rapl_timer_ms); | ||
| 616 | pmu->cpu = -1; | ||
| 617 | rapl_hrtimer_init(pmu); | ||
| 618 | rapl_pmus->pmus[topology_logical_package_id(cpu)] = pmu; | ||
| 619 | return 0; | ||
| 620 | } | ||
| 621 | |||
| 622 | static int rapl_check_hw_unit(bool apply_quirk) | 623 | static int rapl_check_hw_unit(bool apply_quirk) |
| 623 | { | 624 | { |
| 624 | u64 msr_rapl_power_unit_bits; | 625 | u64 msr_rapl_power_unit_bits; |
| @@ -803,29 +804,21 @@ static int __init rapl_pmu_init(void) | |||
| 803 | /* | 804 | /* |
| 804 | * Install callbacks. Core will call them for each online cpu. | 805 | * Install callbacks. Core will call them for each online cpu. |
| 805 | */ | 806 | */ |
| 806 | |||
| 807 | ret = cpuhp_setup_state(CPUHP_PERF_X86_RAPL_PREP, "perf/x86/rapl:prepare", | ||
| 808 | rapl_cpu_prepare, NULL); | ||
| 809 | if (ret) | ||
| 810 | goto out; | ||
| 811 | |||
| 812 | ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_RAPL_ONLINE, | 807 | ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_RAPL_ONLINE, |
| 813 | "perf/x86/rapl:online", | 808 | "perf/x86/rapl:online", |
| 814 | rapl_cpu_online, rapl_cpu_offline); | 809 | rapl_cpu_online, rapl_cpu_offline); |
| 815 | if (ret) | 810 | if (ret) |
| 816 | goto out1; | 811 | goto out; |
| 817 | 812 | ||
| 818 | ret = perf_pmu_register(&rapl_pmus->pmu, "power", -1); | 813 | ret = perf_pmu_register(&rapl_pmus->pmu, "power", -1); |
| 819 | if (ret) | 814 | if (ret) |
| 820 | goto out2; | 815 | goto out1; |
| 821 | 816 | ||
| 822 | rapl_advertise(); | 817 | rapl_advertise(); |
| 823 | return 0; | 818 | return 0; |
| 824 | 819 | ||
| 825 | out2: | ||
| 826 | cpuhp_remove_state(CPUHP_AP_PERF_X86_RAPL_ONLINE); | ||
| 827 | out1: | 820 | out1: |
| 828 | cpuhp_remove_state(CPUHP_PERF_X86_RAPL_PREP); | 821 | cpuhp_remove_state(CPUHP_AP_PERF_X86_RAPL_ONLINE); |
| 829 | out: | 822 | out: |
| 830 | pr_warn("Initialization failed (%d), disabled\n", ret); | 823 | pr_warn("Initialization failed (%d), disabled\n", ret); |
| 831 | cleanup_rapl_pmus(); | 824 | cleanup_rapl_pmus(); |
| @@ -836,7 +829,6 @@ module_init(rapl_pmu_init); | |||
| 836 | static void __exit intel_rapl_exit(void) | 829 | static void __exit intel_rapl_exit(void) |
| 837 | { | 830 | { |
| 838 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_RAPL_ONLINE); | 831 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_RAPL_ONLINE); |
| 839 | cpuhp_remove_state_nocalls(CPUHP_PERF_X86_RAPL_PREP); | ||
| 840 | perf_pmu_unregister(&rapl_pmus->pmu); | 832 | perf_pmu_unregister(&rapl_pmus->pmu); |
| 841 | cleanup_rapl_pmus(); | 833 | cleanup_rapl_pmus(); |
| 842 | } | 834 | } |
