@@ -103,6 +103,19 @@ static struct perf_pmu_events_attr event_attr_##v = { \
103103 .event_str = str, \
104104};
105105
106+ /*
107+ * RAPL Package energy counter scope:
108+ * 1. AMD/HYGON platforms have a per-PKG package energy counter
109+ * 2. For Intel platforms
110+ * 2.1. CLX-AP is multi-die and its RAPL MSRs are die-scope
111+ * 2.2. Other Intel platforms are single die systems so the scope can be
112+ * considered as either pkg-scope or die-scope, and we are considering
113+ * them as die-scope.
114+ */
115+ #define rapl_pmu_is_pkg_scope () \
116+ (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || \
117+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
118+
106119struct rapl_pmu {
107120 raw_spinlock_t lock ;
108121 int n_active ;
@@ -140,9 +153,25 @@ static unsigned int rapl_cntr_mask;
140153static u64 rapl_timer_ms ;
141154static struct perf_msr * rapl_msrs ;
142155
156+ /*
157+ * Helper functions to get the correct topology macros according to the
158+ * RAPL PMU scope.
159+ */
160+ static inline unsigned int get_rapl_pmu_idx (int cpu )
161+ {
162+ return rapl_pmu_is_pkg_scope () ? topology_logical_package_id (cpu ) :
163+ topology_logical_die_id (cpu );
164+ }
165+
166+ static inline const struct cpumask * get_rapl_pmu_cpumask (int cpu )
167+ {
168+ return rapl_pmu_is_pkg_scope () ? topology_core_cpumask (cpu ) :
169+ topology_die_cpumask (cpu );
170+ }
171+
143172static inline struct rapl_pmu * cpu_to_rapl_pmu (unsigned int cpu )
144173{
145- unsigned int rapl_pmu_idx = topology_logical_die_id (cpu );
174+ unsigned int rapl_pmu_idx = get_rapl_pmu_idx (cpu );
146175
147176 /*
148177 * The unsigned check also catches the '-1' return value for non
@@ -552,7 +581,7 @@ static int rapl_cpu_offline(unsigned int cpu)
552581
553582 pmu -> cpu = -1 ;
554583 /* Find a new cpu to collect rapl events */
555- target = cpumask_any_but (topology_die_cpumask (cpu ), cpu );
584+ target = cpumask_any_but (get_rapl_pmu_cpumask (cpu ), cpu );
556585
557586 /* Migrate rapl events to the new target */
558587 if (target < nr_cpu_ids ) {
@@ -565,6 +594,11 @@ static int rapl_cpu_offline(unsigned int cpu)
565594
566595static int rapl_cpu_online (unsigned int cpu )
567596{
597+ s32 rapl_pmu_idx = get_rapl_pmu_idx (cpu );
598+ if (rapl_pmu_idx < 0 ) {
599+ pr_err ("topology_logical_(package/die)_id() returned a negative value" );
600+ return - EINVAL ;
601+ }
568602 struct rapl_pmu * pmu = cpu_to_rapl_pmu (cpu );
569603 int target ;
570604
@@ -579,14 +613,14 @@ static int rapl_cpu_online(unsigned int cpu)
579613 pmu -> timer_interval = ms_to_ktime (rapl_timer_ms );
580614 rapl_hrtimer_init (pmu );
581615
582- rapl_pmus -> pmus [topology_logical_die_id ( cpu ) ] = pmu ;
616+ rapl_pmus -> pmus [rapl_pmu_idx ] = pmu ;
583617 }
584618
585619 /*
586620 * Check if there is an online cpu in the package which collects rapl
587621 * events already.
588622 */
589- target = cpumask_any_and (& rapl_cpu_mask , topology_die_cpumask (cpu ));
623+ target = cpumask_any_and (& rapl_cpu_mask , get_rapl_pmu_cpumask (cpu ));
590624 if (target < nr_cpu_ids )
591625 return 0 ;
592626
@@ -675,7 +709,10 @@ static const struct attribute_group *rapl_attr_update[] = {
675709
676710static int __init init_rapl_pmus (void )
677711{
678- int nr_rapl_pmu = topology_max_packages () * topology_max_dies_per_package ();
712+ int nr_rapl_pmu = topology_max_packages ();
713+
714+ if (!rapl_pmu_is_pkg_scope ())
715+ nr_rapl_pmu *= topology_max_dies_per_package ();
679716
680717 rapl_pmus = kzalloc (struct_size (rapl_pmus , pmus , nr_rapl_pmu ), GFP_KERNEL );
681718 if (!rapl_pmus )
0 commit comments