perf: arm_cspmu: Support implementation specific validation
authorIlkka Koskinen <ilkka@os.amperecomputing.com>
Wed, 13 Sep 2023 23:39:40 +0000 (16:39 -0700)
committerWill Deacon <will@kernel.org>
Thu, 5 Oct 2023 13:19:25 +0000 (14:19 +0100)
Some platforms may use e.g. different filtering mechanism and, thus,
may need different way to validate the events and group.

Signed-off-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20230913233941.9814-4-ilkka@os.amperecomputing.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/perf/arm_cspmu/arm_cspmu.c
drivers/perf/arm_cspmu/arm_cspmu.h

index 2ecbf8d7714b1d07ab3f1649b72fcfac01bd93fc..1ba00d640352f7e1da406bdd64ca02dc2e71e338 100644 (file)
@@ -576,7 +576,7 @@ static void arm_cspmu_disable(struct pmu *pmu)
 static int arm_cspmu_get_event_idx(struct arm_cspmu_hw_events *hw_events,
                                struct perf_event *event)
 {
-       int idx;
+       int idx, ret;
        struct arm_cspmu *cspmu = to_arm_cspmu(event->pmu);
 
        if (supports_cycle_counter(cspmu)) {
@@ -610,6 +610,12 @@ static int arm_cspmu_get_event_idx(struct arm_cspmu_hw_events *hw_events,
        if (idx >= cspmu->num_logical_ctrs)
                return -EAGAIN;
 
+       if (cspmu->impl.ops.validate_event) {
+               ret = cspmu->impl.ops.validate_event(cspmu, event);
+               if (ret)
+                       return ret;
+       }
+
        set_bit(idx, hw_events->used_ctrs);
 
        return idx;
index e0cca5b4aab97cf5ba4db7997a790e702fca63fd..a30c8372214c2403f1aa17609808bb5f58bb16d1 100644 (file)
@@ -107,6 +107,9 @@ struct arm_cspmu_impl_ops {
        /* Set event filter */
        void (*set_ev_filter)(struct arm_cspmu *cspmu,
                              struct hw_perf_event *hwc, u32 filter);
+       /* Implementation specific event validation */
+       int (*validate_event)(struct arm_cspmu *cspmu,
+                             struct perf_event *event);
        /* Hide/show unsupported events */
        umode_t (*event_attr_is_visible)(struct kobject *kobj,
                                         struct attribute *attr, int unused);