]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/pmu: Add attribute skeleton
authorLucas De Marchi <lucas.demarchi@intel.com>
Fri, 24 Jan 2025 05:04:10 +0000 (21:04 -0800)
committerLucas De Marchi <lucas.demarchi@intel.com>
Mon, 27 Jan 2025 16:55:04 +0000 (08:55 -0800)
Add the generic support for defining new attributes. This only adds
the macros and common infra for the event counters, but no counters
yet. This is going to be added as follow up changes.

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250124050411.2189060-5-lucas.demarchi@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
drivers/gpu/drm/xe/xe_pmu.c
drivers/gpu/drm/xe/xe_pmu_types.h

index 6678340d6195bc5333285b8a4102526a528e5d2b..6e19e08dd61769e6011885cb4204627ac25c69ef 100644 (file)
@@ -61,7 +61,8 @@ static bool event_supported(struct xe_pmu *pmu, unsigned int gt,
        if (gt >= XE_MAX_GT_PER_TILE)
                return false;
 
-       return false;
+       return id < sizeof(pmu->supported_events) * BITS_PER_BYTE &&
+               pmu->supported_events & BIT_ULL(id);
 }
 
 static void xe_pmu_event_destroy(struct perf_event *event)
@@ -213,16 +214,73 @@ static const struct attribute_group pmu_format_attr_group = {
        .attrs = pmu_format_attrs,
 };
 
-static struct attribute *pmu_event_attrs[] = {
-       /* No events yet */
+__maybe_unused static ssize_t event_attr_show(struct device *dev,
+                                             struct device_attribute *attr, char *buf)
+{
+       struct perf_pmu_events_attr *pmu_attr =
+               container_of(attr, struct perf_pmu_events_attr, attr);
+
+       return sprintf(buf, "event=%#04llx\n", pmu_attr->id);
+}
+
+#define XE_EVENT_ATTR(name_, v_, id_)                                  \
+       PMU_EVENT_ATTR(name_, pmu_event_ ## v_, id_, event_attr_show)
+
+#define XE_EVENT_ATTR_UNIT(name_, v_, unit_)                           \
+       PMU_EVENT_ATTR_STRING(name_.unit, pmu_event_unit_ ## v_, unit_)
+
+#define XE_EVENT_ATTR_GROUP(v_, id_, ...)                              \
+       static struct attribute *pmu_attr_ ##v_[] = {                   \
+               __VA_ARGS__,                                            \
+               NULL                                                    \
+       };                                                              \
+       static umode_t is_visible_##v_(struct kobject *kobj,            \
+                                      struct attribute *attr, int idx) \
+       {                                                               \
+               struct perf_pmu_events_attr *pmu_attr;                  \
+               struct xe_pmu *pmu;                                     \
+                                                                       \
+               pmu_attr = container_of(attr, typeof(*pmu_attr), attr.attr); \
+               pmu = container_of(dev_get_drvdata(kobj_to_dev(kobj)),  \
+                                  typeof(*pmu), base);                 \
+                                                                       \
+               return event_supported(pmu, 0, id_) ? attr->mode : 0;   \
+       }                                                               \
+       static const struct attribute_group pmu_group_ ##v_ = {         \
+               .name = "events",                                       \
+               .attrs = pmu_attr_ ## v_,                               \
+               .is_visible = is_visible_ ## v_,                        \
+       }
+
+#define XE_EVENT_ATTR_SIMPLE(name_, v_, id_, unit_)                    \
+       XE_EVENT_ATTR(name_, v_, id_)                                   \
+       XE_EVENT_ATTR_UNIT(name_, v_, unit_)                            \
+       XE_EVENT_ATTR_GROUP(v_, id_, &pmu_event_ ##v_.attr.attr,        \
+                           &pmu_event_unit_ ##v_.attr.attr)
+
+#define XE_EVENT_ATTR_NOUNIT(name_, v_, id_)                           \
+       XE_EVENT_ATTR(name_, v_, id_)                                   \
+       XE_EVENT_ATTR_GROUP(v_, id_, &pmu_event_ ##v_.attr.attr)
+
+static struct attribute *pmu_empty_event_attrs[] = {
+       /* Empty - all events are added as groups with .attr_update() */
        NULL,
 };
 
 static const struct attribute_group pmu_events_attr_group = {
        .name = "events",
-       .attrs = pmu_event_attrs,
+       .attrs = pmu_empty_event_attrs,
 };
 
+static const struct attribute_group *pmu_events_attr_update[] = {
+       /* No events yet */
+       NULL,
+};
+
+static void set_supported_events(struct xe_pmu *pmu)
+{
+}
+
 /**
  * xe_pmu_unregister() - Remove/cleanup PMU registration
  * @arg: Ptr to pmu
@@ -273,6 +331,7 @@ int xe_pmu_register(struct xe_pmu *pmu)
 
        pmu->name               = name;
        pmu->base.attr_groups   = attr_groups;
+       pmu->base.attr_update   = pmu_events_attr_update;
        pmu->base.scope         = PERF_PMU_SCOPE_SYS_WIDE;
        pmu->base.module        = THIS_MODULE;
        pmu->base.task_ctx_nr   = perf_invalid_context;
@@ -283,6 +342,8 @@ int xe_pmu_register(struct xe_pmu *pmu)
        pmu->base.stop          = xe_pmu_event_stop;
        pmu->base.read          = xe_pmu_event_read;
 
+       set_supported_events(pmu);
+
        ret = perf_pmu_register(&pmu->base, pmu->name, -1);
        if (ret)
                goto err_name;
index 0e8faae6bc1b3f9eb2c309b28c05b71b0265dc0e..f5ba4d56622cbeb1f69e5aab6a08eb7d23df76f0 100644 (file)
@@ -30,6 +30,10 @@ struct xe_pmu {
         * @name: Name as registered with perf core.
         */
        const char *name;
+       /**
+        * @supported_events: Bitmap of supported events, indexed by event id
+        */
+       u64 supported_events;
 };
 
 #endif