]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf: arm_pmuv3: Factor out PMCCNTR_EL0 use conditions
authorYicong Yang <yangyicong@hisilicon.com>
Wed, 20 Aug 2025 08:45:33 +0000 (16:45 +0800)
committerWill Deacon <will@kernel.org>
Thu, 18 Sep 2025 13:35:54 +0000 (14:35 +0100)
PMCCNTR_EL0 is preferred for counting CPU_CYCLES under certain
conditions. Factor out the condition check to a separate function
for further extension. Add documents for better understanding.
No functional changes intended.

Reviewed-by: James Clark <james.clark@linaro.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Signed-off-by: Will Deacon <will@kernel.org>
drivers/perf/arm_pmuv3.c

index f6d7bab5d555c069528f151bce8dedd957680dc3..69c5cc8f56067cd00aba8509d21b984cb8f30d2e 100644 (file)
@@ -978,6 +978,32 @@ static int armv8pmu_get_chain_idx(struct pmu_hw_events *cpuc,
        return -EAGAIN;
 }
 
+static bool armv8pmu_can_use_pmccntr(struct pmu_hw_events *cpuc,
+                                    struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned long evtype = hwc->config_base & ARMV8_PMU_EVTYPE_EVENT;
+
+       if (evtype != ARMV8_PMUV3_PERFCTR_CPU_CYCLES)
+               return false;
+
+       /*
+        * A CPU_CYCLES event with threshold counting cannot use PMCCNTR_EL0
+        * since it lacks threshold support.
+        */
+       if (armv8pmu_event_get_threshold(&event->attr))
+               return false;
+
+       /*
+        * PMCCNTR_EL0 is not affected by BRBE controls like BRBCR_ELx.FZP.
+        * So don't use it for branch events.
+        */
+       if (has_branch_stack(event))
+               return false;
+
+       return true;
+}
+
 static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
                                  struct perf_event *event)
 {
@@ -986,8 +1012,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
        unsigned long evtype = hwc->config_base & ARMV8_PMU_EVTYPE_EVENT;
 
        /* Always prefer to place a cycle counter into the cycle counter. */
-       if ((evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) &&
-           !armv8pmu_event_get_threshold(&event->attr) && !has_branch_stack(event)) {
+       if (armv8pmu_can_use_pmccntr(cpuc, event)) {
                if (!test_and_set_bit(ARMV8_PMU_CYCLE_IDX, cpuc->used_mask))
                        return ARMV8_PMU_CYCLE_IDX;
                else if (armv8pmu_event_is_64bit(event) &&