aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/events/intel/rapl.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/events/intel/rapl.c')
-rw-r--r--arch/x86/events/intel/rapl.c60
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
162static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu) 162static 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
167static inline u64 rapl_read_counter(struct perf_event *event) 173static 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
601static 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
622static int rapl_check_hw_unit(bool apply_quirk) 623static 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
825out2:
826 cpuhp_remove_state(CPUHP_AP_PERF_X86_RAPL_ONLINE);
827out1: 820out1:
828 cpuhp_remove_state(CPUHP_PERF_X86_RAPL_PREP); 821 cpuhp_remove_state(CPUHP_AP_PERF_X86_RAPL_ONLINE);
829out: 822out:
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);
836static void __exit intel_rapl_exit(void) 829static 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}