drm/xe/pmu: Add GT C6 events

Provide a PMU interface for GT C6 residency counters. The interface is
similar to the one available for i915, but gt is passed in the config
when creating the event.

Sample usage and output:

	$ perf list | grep gt-c6
	  xe_0000_00_02.0/gt-c6-residency/                   [Kernel PMU event]

	$ tail /sys/bus/event_source/devices/xe_0000_00_02.0/events/gt-c6-residency*
	==> /sys/bus/event_source/devices/xe_0000_00_02.0/events/gt-c6-residency <==
	event=0x01

	==> /sys/bus/event_source/devices/xe_0000_00_02.0/events/gt-c6-residency.unit <==
	ms

	$ perf stat -e xe_0000_00_02.0/gt-c6-residency,gt=0/ -I1000
	#           time             counts unit events
	     1.001196056              1,001 ms   xe_0000_00_02.0/gt-c6-residency,gt=0/
	     2.005216219              1,003 ms   xe_0000_00_02.0/gt-c6-residency,gt=0/

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Riana Tauro <riana.tauro@intel.com>
Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250124050411.2189060-6-lucas.demarchi@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
This commit is contained in:
Vinay Belgaumkar 2025-01-23 21:04:11 -08:00 committed by Lucas De Marchi
parent 6ea5bf169a
commit 897286f294

View File

@ -7,6 +7,7 @@
#include <linux/device.h>
#include "xe_device.h"
#include "xe_gt_idle.h"
#include "xe_pm.h"
#include "xe_pmu.h"
@ -47,6 +48,8 @@ static unsigned int config_to_gt_id(u64 config)
return FIELD_GET(XE_PMU_EVENT_GT_MASK, config);
}
#define XE_PMU_EVENT_GT_C6_RESIDENCY 0x01
static struct xe_gt *event_to_gt(struct perf_event *event)
{
struct xe_device *xe = container_of(event->pmu, typeof(*xe), pmu.base);
@ -113,12 +116,16 @@ static int xe_pmu_event_init(struct perf_event *event)
static u64 __xe_pmu_event_read(struct perf_event *event)
{
struct xe_gt *gt = event_to_gt(event);
u64 val = 0;
if (!gt)
return 0;
return val;
switch (config_to_event_id(event->attr.config)) {
case XE_PMU_EVENT_GT_C6_RESIDENCY:
return xe_gt_idle_residency_msec(&gt->gtidle);
}
return 0;
}
static void xe_pmu_event_update(struct perf_event *event)
@ -214,8 +221,8 @@ static const struct attribute_group pmu_format_attr_group = {
.attrs = pmu_format_attrs,
};
__maybe_unused static ssize_t event_attr_show(struct device *dev,
struct device_attribute *attr, char *buf)
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);
@ -262,6 +269,8 @@ __maybe_unused static ssize_t event_attr_show(struct device *dev,
XE_EVENT_ATTR(name_, v_, id_) \
XE_EVENT_ATTR_GROUP(v_, id_, &pmu_event_ ##v_.attr.attr)
XE_EVENT_ATTR_SIMPLE(gt-c6-residency, gt_c6_residency, XE_PMU_EVENT_GT_C6_RESIDENCY, "ms");
static struct attribute *pmu_empty_event_attrs[] = {
/* Empty - all events are added as groups with .attr_update() */
NULL,
@ -273,12 +282,16 @@ static const struct attribute_group pmu_events_attr_group = {
};
static const struct attribute_group *pmu_events_attr_update[] = {
/* No events yet */
&pmu_group_gt_c6_residency,
NULL,
};
static void set_supported_events(struct xe_pmu *pmu)
{
struct xe_device *xe = container_of(pmu, typeof(*xe), pmu);
if (!xe->info.skip_guc_pc)
pmu->supported_events |= BIT_ULL(XE_PMU_EVENT_GT_C6_RESIDENCY);
}
/**