Use per-implementation event tables to allow supporting implementations
with a different list of events and event affinities.
Signed-off-by: Nick Chan <towinchenmi@gmail.com>
---
drivers/perf/apple_m1_cpu_pmu.c | 65 +++++++++++++++++++++++++----------------
1 file changed, 40 insertions(+), 25 deletions(-)
diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index b800da3f7f61ffa972fcab5f24b42127f2c55ac6..d1bc850809993de044df8fd5d4dfc61341482ee7 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -43,9 +43,6 @@
* moment, we don't really need to distinguish between the two because we
* know next to nothing about the events themselves, and we already have
* per cpu-type PMU abstractions.
- *
- * If we eventually find out that the events are different across
- * implementations, we'll have to introduce per cpu-type tables.
*/
enum m1_pmu_events {
M1_PMU_PERFCTR_RETIRE_UOP = 0x1,
@@ -494,11 +491,12 @@ static void m1_pmu_write_counter(struct perf_event *event, u64 value)
isb();
}
-static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct perf_event *event)
+static int apple_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event,
+ const u16 event_affinities[M1_PMU_CFG_EVENT])
{
unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
- unsigned long affinity = m1_pmu_event_affinity[evtype];
+ unsigned long affinity = event_affinities[evtype];
int idx;
/*
@@ -517,6 +515,12 @@ static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
return -EAGAIN;
}
+static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ return apple_pmu_get_event_idx(cpuc, event, m1_pmu_event_affinity);
+}
+
static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
struct perf_event *event)
{
@@ -544,7 +548,8 @@ static void m1_pmu_stop(struct arm_pmu *cpu_pmu)
__m1_pmu_set_mode(PMCR0_IMODE_OFF);
}
-static int m1_pmu_map_event(struct perf_event *event)
+static int apple_pmu_map_event_47(struct perf_event *event,
+ const unsigned int (*perf_map)[])
{
/*
* Although the counters are 48bit wide, bit 47 is what
@@ -552,18 +557,29 @@ static int m1_pmu_map_event(struct perf_event *event)
* being 47bit wide to mimick the behaviour of the ARM PMU.
*/
event->hw.flags |= ARMPMU_EVT_47BIT;
- return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT);
+ return armpmu_map_event(event, perf_map, NULL, M1_PMU_CFG_EVENT);
}
-static int m2_pmu_map_event(struct perf_event *event)
+static int apple_pmu_map_event_63(struct perf_event *event,
+ const unsigned int (*perf_map)[])
{
/*
- * Same deal as the above, except that M2 has 64bit counters.
+ * Same deal as the above, except with 64bit counters.
* Which, as far as we're concerned, actually means 63 bits.
* Yes, this is getting awkward.
*/
event->hw.flags |= ARMPMU_EVT_63BIT;
- return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT);
+ return armpmu_map_event(event, perf_map, NULL, M1_PMU_CFG_EVENT);
+}
+
+static int m1_pmu_map_event(struct perf_event *event)
+{
+ return apple_pmu_map_event_47(event, &m1_pmu_perf_map);
+}
+
+static int m2_pmu_map_event(struct perf_event *event)
+{
+ return apple_pmu_map_event_63(event, &m1_pmu_perf_map);
}
static int m1_pmu_map_pmuv3_event(unsigned int eventsel)
@@ -624,25 +640,16 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
return 0;
}
-static int m1_pmu_init(struct arm_pmu *cpu_pmu, u32 flags)
+static int apple_pmu_init(struct arm_pmu *cpu_pmu)
{
cpu_pmu->handle_irq = m1_pmu_handle_irq;
cpu_pmu->enable = m1_pmu_enable_event;
cpu_pmu->disable = m1_pmu_disable_event;
cpu_pmu->read_counter = m1_pmu_read_counter;
cpu_pmu->write_counter = m1_pmu_write_counter;
- cpu_pmu->get_event_idx = m1_pmu_get_event_idx;
cpu_pmu->clear_event_idx = m1_pmu_clear_event_idx;
cpu_pmu->start = m1_pmu_start;
cpu_pmu->stop = m1_pmu_stop;
-
- if (flags & ARMPMU_EVT_47BIT)
- cpu_pmu->map_event = m1_pmu_map_event;
- else if (flags & ARMPMU_EVT_63BIT)
- cpu_pmu->map_event = m2_pmu_map_event;
- else
- return WARN_ON(-EINVAL);
-
cpu_pmu->reset = m1_pmu_reset;
cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
@@ -661,25 +668,33 @@ static int m1_pmu_init(struct arm_pmu *cpu_pmu, u32 flags)
static int m1_pmu_ice_init(struct arm_pmu *cpu_pmu)
{
cpu_pmu->name = "apple_icestorm_pmu";
- return m1_pmu_init(cpu_pmu, ARMPMU_EVT_47BIT);
+ cpu_pmu->get_event_idx = m1_pmu_get_event_idx;
+ cpu_pmu->map_event = m1_pmu_map_event;
+ return apple_pmu_init(cpu_pmu);
}
static int m1_pmu_fire_init(struct arm_pmu *cpu_pmu)
{
cpu_pmu->name = "apple_firestorm_pmu";
- return m1_pmu_init(cpu_pmu, ARMPMU_EVT_47BIT);
+ cpu_pmu->get_event_idx = m1_pmu_get_event_idx;
+ cpu_pmu->map_event = m1_pmu_map_event;
+ return apple_pmu_init(cpu_pmu);
}
static int m2_pmu_avalanche_init(struct arm_pmu *cpu_pmu)
{
cpu_pmu->name = "apple_avalanche_pmu";
- return m1_pmu_init(cpu_pmu, ARMPMU_EVT_63BIT);
+ cpu_pmu->get_event_idx = m1_pmu_get_event_idx;
+ cpu_pmu->map_event = m2_pmu_map_event;
+ return apple_pmu_init(cpu_pmu);
}
static int m2_pmu_blizzard_init(struct arm_pmu *cpu_pmu)
{
cpu_pmu->name = "apple_blizzard_pmu";
- return m1_pmu_init(cpu_pmu, ARMPMU_EVT_63BIT);
+ cpu_pmu->get_event_idx = m1_pmu_get_event_idx;
+ cpu_pmu->map_event = m2_pmu_map_event;
+ return apple_pmu_init(cpu_pmu);
}
static const struct of_device_id m1_pmu_of_device_ids[] = {
--
2.49.0
Hi Nick,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 0af2f6be1b4281385b618cb86ad946eded089ac8]
url: https://github.com/intel-lab-lkp/linux/commits/Nick-Chan/dt-bindings-arm-pmu-Add-Apple-A7-A11-SoC-CPU-PMU-compatibles/20250429-114920
base: 0af2f6be1b4281385b618cb86ad946eded089ac8
patch link: https://lore.kernel.org/r/20250429-apple-cpmu-v6-3-ed21815f0c3f%40gmail.com
patch subject: [PATCH RESEND v6 03/21] drivers/perf: apple_m1: Support per-implementation event tables
config: arm64-randconfig-004-20250501 (https://download.01.org/0day-ci/archive/20250507/202505071747.2b2WEajY-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 9.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250507/202505071747.2b2WEajY-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202505071747.2b2WEajY-lkp@intel.com/
All warnings (new ones prefixed by >>):
include/linux/bits.h:34:2: note: (near initialization for 'm1_pmu_event_affinity[248]')
34 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
| ^
drivers/perf/apple_m1_cpu_pmu.c:27:23: note: in expansion of macro 'GENMASK'
27 | #define ONLY_2_TO_7 GENMASK(7, 2)
| ^~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:163:35: note: in expansion of macro 'ONLY_2_TO_7'
163 | [M1_PMU_PERFCTR_UNKNOWN_f8] = ONLY_2_TO_7,
| ^~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:28:22: warning: initialized field overwritten [-Woverride-init]
28 | #define ONLY_2_4_6 (BIT(2) | BIT(4) | BIT(6))
| ^
drivers/perf/apple_m1_cpu_pmu.c:164:35: note: in expansion of macro 'ONLY_2_4_6'
164 | [M1_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6,
| ^~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:28:22: note: (near initialization for 'm1_pmu_event_affinity[253]')
28 | #define ONLY_2_4_6 (BIT(2) | BIT(4) | BIT(6))
| ^
drivers/perf/apple_m1_cpu_pmu.c:164:35: note: in expansion of macro 'ONLY_2_4_6'
164 | [M1_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6,
| ^~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:169:32: warning: initialized field overwritten [-Woverride-init]
169 | [PERF_COUNT_HW_CPU_CYCLES] = M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:169:32: note: (near initialization for 'm1_pmu_perf_map[0]')
drivers/perf/apple_m1_cpu_pmu.c:170:34: warning: initialized field overwritten [-Woverride-init]
170 | [PERF_COUNT_HW_INSTRUCTIONS] = M1_PMU_PERFCTR_INST_ALL,
| ^~~~~~~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:170:34: note: (near initialization for 'm1_pmu_perf_map[1]')
drivers/perf/apple_m1_cpu_pmu.c:171:40: warning: initialized field overwritten [-Woverride-init]
171 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = M1_PMU_PERFCTR_INST_BRANCH,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:171:40: note: (near initialization for 'm1_pmu_perf_map[4]')
drivers/perf/apple_m1_cpu_pmu.c:172:35: warning: initialized field overwritten [-Woverride-init]
172 | [PERF_COUNT_HW_BRANCH_MISSES] = M1_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:172:35: note: (near initialization for 'm1_pmu_perf_map[5]')
drivers/perf/apple_m1_cpu_pmu.c:176:40: warning: initialized field overwritten [-Woverride-init]
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:180:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
180 | M1_PMUV3_EVENT_MAP(INST_RETIRED, INST_ALL),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:176:40: note: (near initialization for 'm1_pmu_pmceid_map[8]')
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:180:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
180 | M1_PMUV3_EVENT_MAP(INST_RETIRED, INST_ALL),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:176:40: warning: initialized field overwritten [-Woverride-init]
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:181:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
181 | M1_PMUV3_EVENT_MAP(CPU_CYCLES, CORE_ACTIVE_CYCLE),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:176:40: note: (near initialization for 'm1_pmu_pmceid_map[17]')
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:181:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
181 | M1_PMUV3_EVENT_MAP(CPU_CYCLES, CORE_ACTIVE_CYCLE),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:176:40: warning: initialized field overwritten [-Woverride-init]
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:182:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
182 | M1_PMUV3_EVENT_MAP(BR_RETIRED, INST_BRANCH),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:176:40: note: (near initialization for 'm1_pmu_pmceid_map[33]')
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:182:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
182 | M1_PMUV3_EVENT_MAP(BR_RETIRED, INST_BRANCH),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:176:40: warning: initialized field overwritten [-Woverride-init]
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:183:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
183 | M1_PMUV3_EVENT_MAP(BR_MIS_PRED_RETIRED, BRANCH_MISPRED_NONSPEC),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:176:40: note: (near initialization for 'm1_pmu_pmceid_map[34]')
176 | [ARMV8_PMUV3_PERFCTR_##pmuv3_event] = M1_PMU_PERFCTR_##m1_event
| ^~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:183:2: note: in expansion of macro 'M1_PMUV3_EVENT_MAP'
183 | M1_PMUV3_EVENT_MAP(BR_MIS_PRED_RETIRED, BRANCH_MISPRED_NONSPEC),
| ^~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c: In function 'm1_pmu_enable_event':
drivers/perf/apple_m1_cpu_pmu.c:422:5: warning: variable 'evt' set but not used [-Wunused-but-set-variable]
422 | u8 evt;
| ^~~
drivers/perf/apple_m1_cpu_pmu.c:421:13: warning: variable 'kernel' set but not used [-Wunused-but-set-variable]
421 | bool user, kernel;
| ^~~~~~
drivers/perf/apple_m1_cpu_pmu.c:421:7: warning: variable 'user' set but not used [-Wunused-but-set-variable]
421 | bool user, kernel;
| ^~~~
In file included from include/linux/bits.h:22,
from include/linux/bitops.h:6,
from include/linux/of.h:15,
from drivers/perf/apple_m1_cpu_pmu.c:13:
drivers/perf/apple_m1_cpu_pmu.c: At top level:
>> include/linux/build_bug.h:16:44: warning: anonymous struct declared inside parameter list will not be visible outside of this definition or declaration
16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
| ^~~~~~
include/linux/bits.h:24:35: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
24 | #define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(const_true((l) > (h)))
| ^~~~~~~~~~~~~~~~~
include/linux/bits.h:34:3: note: in expansion of macro 'GENMASK_INPUT_CHECK'
34 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
| ^~~~~~~~~~~~~~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:24:27: note: in expansion of macro 'GENMASK'
24 | #define M1_PMU_CFG_EVENT GENMASK(7, 0)
| ^~~~~~~
drivers/perf/apple_m1_cpu_pmu.c:496:32: note: in expansion of macro 'M1_PMU_CFG_EVENT'
496 | const u16 event_affinities[M1_PMU_CFG_EVENT])
| ^~~~~~~~~~~~~~~~
vim +16 include/linux/build_bug.h
bc6245e5efd70c Ian Abbott 2017-07-10 6
bc6245e5efd70c Ian Abbott 2017-07-10 7 #ifdef __CHECKER__
bc6245e5efd70c Ian Abbott 2017-07-10 8 #define BUILD_BUG_ON_ZERO(e) (0)
bc6245e5efd70c Ian Abbott 2017-07-10 9 #else /* __CHECKER__ */
bc6245e5efd70c Ian Abbott 2017-07-10 10 /*
bc6245e5efd70c Ian Abbott 2017-07-10 11 * Force a compilation error if condition is true, but also produce a
8788994376d84d Rikard Falkeborn 2019-12-04 12 * result (of value 0 and type int), so the expression can be used
bc6245e5efd70c Ian Abbott 2017-07-10 13 * e.g. in a structure initializer (or where-ever else comma expressions
bc6245e5efd70c Ian Abbott 2017-07-10 14 * aren't permitted).
bc6245e5efd70c Ian Abbott 2017-07-10 15 */
8788994376d84d Rikard Falkeborn 2019-12-04 @16 #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
527edbc18a70e7 Masahiro Yamada 2019-01-03 17 #endif /* __CHECKER__ */
527edbc18a70e7 Masahiro Yamada 2019-01-03 18
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
#syz test
diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 365b4ecaedb1..81443e5158b2 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -1082,7 +1082,7 @@ static void m1_pmu_write_counter(struct perf_event *event, u64 value)
static int apple_pmu_get_event_idx(struct pmu_hw_events *cpuc,
struct perf_event *event,
- const u16 event_affinities[M1_PMU_CFG_EVENT])
+ const u16 event_affinities[])
{
unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
unsigned long affinity = event_affinities[evtype];
© 2016 - 2026 Red Hat, Inc.