All of lore.kernel.org
 help / color / mirror / Atom feed
From: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
To: Ashutosh Dixit <ashutosh.dixit@intel.com>
Cc: intel-xe@lists.freedesktop.org
Subject: Re: [PATCH 06/17] drm/xe/oa/uapi: Add/remove OA config perf ops
Date: Tue, 19 Dec 2023 11:10:22 -0800	[thread overview]
Message-ID: <ZYHqnlasZsweeh2C@unerlige-ril> (raw)
In-Reply-To: <20231208064329.2387604-7-ashutosh.dixit@intel.com>

On Thu, Dec 07, 2023 at 10:43:18PM -0800, Ashutosh Dixit wrote:
>Introduce add/remove config perf ops for OA. OA configurations consist of a
>set of event/counter select register address/value pairs. The add_config
>perf op validates and stores such configurations and also exposes them in
>the metrics sysfs. These configurations will be programmed to OA unit HW
>when an OA stream using a configuration is opened. The OA stream can also
>switch to other stored configurations.
>
>Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
>---
> drivers/gpu/drm/xe/xe_device.c   |   4 +
> drivers/gpu/drm/xe/xe_oa.c       | 406 +++++++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_oa.h       |   9 +
> drivers/gpu/drm/xe/xe_oa_types.h |  10 +
> drivers/gpu/drm/xe/xe_perf.c     |  16 ++
> include/uapi/drm/xe_drm.h        |  25 ++
> 6 files changed, 470 insertions(+)
>
>diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
>index 744d573eb2720..23fdd045b470a 100644
>--- a/drivers/gpu/drm/xe/xe_device.c
>+++ b/drivers/gpu/drm/xe/xe_device.c
>@@ -495,6 +495,8 @@ int xe_device_probe(struct xe_device *xe)
>
> 	xe_display_register(xe);
>
>+	xe_oa_register(xe);
>+
> 	xe_debugfs_register(xe);
>
> 	xe_pmu_register(&xe->pmu);
>@@ -527,6 +529,8 @@ static void xe_device_remove_display(struct xe_device *xe)
>
> void xe_device_remove(struct xe_device *xe)
> {
>+	xe_oa_unregister(xe);
>+
> 	xe_device_remove_display(xe);
>
> 	xe_display_fini(xe);
>diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
>index 5ad3c9c78b4e9..6a903bf4f87d1 100644
>--- a/drivers/gpu/drm/xe/xe_oa.c
>+++ b/drivers/gpu/drm/xe/xe_oa.c
>@@ -10,6 +10,7 @@
> #include "xe_gt.h"
> #include "xe_mmio.h"
> #include "xe_oa.h"
>+#include "xe_perf.h"
>
> static int xe_oa_sample_rate_hard_limit;
> static u32 xe_oa_max_sample_rate = 100000;
>@@ -23,6 +24,28 @@ enum {
> 	XE_OA_UNIT_INVALID = U32_MAX,
> };
>
>+struct xe_oa_reg {
>+	struct xe_reg addr;
>+	u32 value;
>+};
>+
>+struct xe_oa_config {
>+	struct xe_oa *oa;
>+
>+	char uuid[UUID_STRING_LEN + 1];
>+	int id;
>+
>+	const struct xe_oa_reg *regs;
>+	u32 regs_len;
>+
>+	struct attribute_group sysfs_metric;
>+	struct attribute *attrs[2];
>+	struct kobj_attribute sysfs_metric_id;
>+
>+	struct kref ref;
>+	struct rcu_head rcu;
>+};
>+
> #define DRM_FMT(x) DRM_XE_OA_FMT_TYPE_##x
>
> static const struct xe_oa_format oa_formats[] = {
>@@ -47,6 +70,377 @@ static const struct xe_oa_format oa_formats[] = {
> 	[XE_OA_FORMAT_PEC36u64_G1_4_G2_32]	= { 4, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 },
> };
>
>+static void xe_oa_config_release(struct kref *ref)
>+{
>+	struct xe_oa_config *oa_config =
>+		container_of(ref, typeof(*oa_config), ref);
>+
>+	kfree(oa_config->regs);
>+
>+	kfree_rcu(oa_config, rcu);
>+}
>+
>+static void xe_oa_config_put(struct xe_oa_config *oa_config)
>+{
>+	if (!oa_config)
>+		return;
>+
>+	kref_put(&oa_config->ref, xe_oa_config_release);
>+}
>+
>+static bool xe_oa_is_valid_flex_addr(struct xe_oa *oa, u32 addr)
>+{
>+	static const struct xe_reg flex_eu_regs[] = {
>+		EU_PERF_CNTL0,
>+		EU_PERF_CNTL1,
>+		EU_PERF_CNTL2,
>+		EU_PERF_CNTL3,
>+		EU_PERF_CNTL4,
>+		EU_PERF_CNTL5,
>+		EU_PERF_CNTL6,
>+	};
>+	int i;
>+
>+	for (i = 0; i < ARRAY_SIZE(flex_eu_regs); i++) {
>+		if (flex_eu_regs[i].addr == addr)
>+			return true;
>+	}
>+	return false;
>+}
>+
>+static bool xe_oa_reg_in_range_table(u32 addr, const struct xe_mmio_range *table)
>+{
>+	while (table->start || table->end) {

nit: why not start && end? I would expect both start and end defined for 
a range.
>+		if (addr >= table->start && addr <= table->end)
>+			return true;
>+
>+		table++;
>+	}
>+
>+	return false;
>+}
>+
>+static const struct xe_mmio_range xehp_oa_b_counters[] = {
>+	{ .start = 0xdc48, .end = 0xdc48 },	/* OAA_ENABLE_REG */
>+	{ .start = 0xdd00, .end = 0xdd48 },	/* OAG_LCE0_0 - OAA_LENABLE_REG */
>+	{}
>+};
>+
>+static const struct xe_mmio_range gen12_oa_b_counters[] = {
>+	{ .start = 0x2b2c, .end = 0x2b2c },	/* OAG_OA_PESS */
>+	{ .start = 0xd900, .end = 0xd91c },	/* OAG_OASTARTTRIG[1-8] */
>+	{ .start = 0xd920, .end = 0xd93c },	/* OAG_OAREPORTTRIG1[1-8] */
>+	{ .start = 0xd940, .end = 0xd97c },	/* OAG_CEC[0-7][0-1] */
>+	{ .start = 0xdc00, .end = 0xdc3c },	/* OAG_SCEC[0-7][0-1] */
>+	{ .start = 0xdc40, .end = 0xdc40 },	/* OAG_SPCTR_CNF */
>+	{ .start = 0xdc44, .end = 0xdc44 },	/* OAA_DBG_REG */
>+	{}
>+};
>+
>+static const struct xe_mmio_range mtl_oam_b_counters[] = {
>+	{ .start = 0x393000, .end = 0x39301c },	/* OAM_STARTTRIG1[1-8] */
>+	{ .start = 0x393020, .end = 0x39303c },	/* OAM_REPORTTRIG1[1-8] */
>+	{ .start = 0x393040, .end = 0x39307c },	/* OAM_CEC[0-7][0-1] */
>+	{ .start = 0x393200, .end = 0x39323C },	/* MPES[0-7] */
>+	{}
>+};
>+
>+static const struct xe_mmio_range xe2_oa_b_counters[] = {
>+	{ .start = 0x393200, .end = 0x39323C },	/* MPES_0_MPES_SAG - MPES_7_UPPER_MPES_SAG */
>+	{ .start = 0x394200, .end = 0x39423C },	/* MPES_0_MPES_SCMI0 - MPES_7_UPPER_MPES_SCMI0 */
>+	{ .start = 0x394A00, .end = 0x394A3C },	/* MPES_0_MPES_SCMI1 - MPES_7_UPPER_MPES_SCMI1 */
>+	{},
>+};
>+
>+static bool xe_oa_is_valid_b_counter_addr(struct xe_oa *oa, u32 addr)
>+{
>+	return xe_oa_reg_in_range_table(addr, xehp_oa_b_counters) ||
>+		xe_oa_reg_in_range_table(addr, gen12_oa_b_counters) ||
>+		xe_oa_reg_in_range_table(addr, mtl_oam_b_counters) ||
>+		(GRAPHICS_VER(oa->xe) >= 20 &&
>+		 xe_oa_reg_in_range_table(addr, xe2_oa_b_counters));
>+}
>+
>+static const struct xe_mmio_range mtl_oa_mux_regs[] = {
>+	{ .start = 0x0d00, .end = 0x0d04 },	/* RPM_CONFIG[0-1] */
>+	{ .start = 0x0d0c, .end = 0x0d2c },	/* NOA_CONFIG[0-8] */
>+	{ .start = 0x9840, .end = 0x9840 },	/* GDT_CHICKEN_BITS */
>+	{ .start = 0x9884, .end = 0x9888 },	/* NOA_WRITE */
>+	{ .start = 0x38d100, .end = 0x38d114},	/* VISACTL */
>+	{}
>+};
>+
>+static const struct xe_mmio_range gen12_oa_mux_regs[] = {
>+	{ .start = 0x0d00, .end = 0x0d04 },     /* RPM_CONFIG[0-1] */
>+	{ .start = 0x0d0c, .end = 0x0d2c },     /* NOA_CONFIG[0-8] */
>+	{ .start = 0x9840, .end = 0x9840 },	/* GDT_CHICKEN_BITS */
>+	{ .start = 0x9884, .end = 0x9888 },	/* NOA_WRITE */
>+	{ .start = 0x20cc, .end = 0x20cc },	/* WAIT_FOR_RC6_EXIT */
>+	{}
>+};
>+
>+static const struct xe_mmio_range xe2_oa_mux_regs[] = {
>+	{ .start = 0x13000,  .end = 0x137FC },	/* PES_0_PESL0 - PES_63_UPPER_PESL3 */
>+	{},
>+};
>+
>+static bool xe_oa_is_valid_mux_addr(struct xe_oa *oa, u32 addr)
>+{
>+	if (GRAPHICS_VER(oa->xe) >= 20)
>+		return xe_oa_reg_in_range_table(addr, xe2_oa_mux_regs);
>+	else if (GRAPHICS_VERx100(oa->xe) >= 1270)
>+		return xe_oa_reg_in_range_table(addr, mtl_oa_mux_regs);
>+	else
>+		return xe_oa_reg_in_range_table(addr, gen12_oa_mux_regs);
>+}
>+
>+static bool xe_oa_is_valid_config_reg_addr(struct xe_oa *oa, u32 addr)
>+{
>+	return xe_oa_is_valid_flex_addr(oa, addr) ||
>+		xe_oa_is_valid_b_counter_addr(oa, addr) ||
>+		xe_oa_is_valid_mux_addr(oa, addr);
>+}
>+
>+static struct xe_oa_reg *
>+xe_oa_alloc_regs(struct xe_oa *oa, bool (*is_valid)(struct xe_oa *oa, u32 addr),
>+		 u32 __user *regs, u32 n_regs)
>+{
>+	struct xe_oa_reg *oa_regs;
>+	int err;
>+	u32 i;
>+
>+	oa_regs = kmalloc_array(n_regs, sizeof(*oa_regs), GFP_KERNEL);
>+	if (!oa_regs)
>+		return ERR_PTR(-ENOMEM);
>+
>+	for (i = 0; i < n_regs; i++) {
>+		u32 addr, value;
>+
>+		err = get_user(addr, regs);
>+		if (err)
>+			goto addr_err;
>+
>+		if (!is_valid(oa, addr)) {
>+			drm_dbg(&oa->xe->drm, "Invalid oa_reg address: %X\n", addr);
>+			err = -EINVAL;
>+			goto addr_err;
>+		}
>+
>+		err = get_user(value, regs + 1);
>+		if (err)
>+			goto addr_err;
>+
>+		oa_regs[i].addr = XE_REG(addr);
>+		oa_regs[i].value = value;
>+
>+		regs += 2;
>+	}
>+
>+	return oa_regs;
>+
>+addr_err:
>+	kfree(oa_regs);
>+	return ERR_PTR(err);
>+}
>+
>+static ssize_t show_dynamic_id(struct kobject *kobj,
>+			       struct kobj_attribute *attr,
>+			       char *buf)
>+{
>+	struct xe_oa_config *oa_config =
>+		container_of(attr, typeof(*oa_config), sysfs_metric_id);
>+
>+	return sprintf(buf, "%d\n", oa_config->id);
>+}
>+
>+static int create_dynamic_oa_sysfs_entry(struct xe_oa *oa,
>+					 struct xe_oa_config *oa_config)
>+{
>+	sysfs_attr_init(&oa_config->sysfs_metric_id.attr);
>+	oa_config->sysfs_metric_id.attr.name = "id";
>+	oa_config->sysfs_metric_id.attr.mode = 0444;
>+	oa_config->sysfs_metric_id.show = show_dynamic_id;
>+	oa_config->sysfs_metric_id.store = NULL;
>+
>+	oa_config->attrs[0] = &oa_config->sysfs_metric_id.attr;
>+	oa_config->attrs[1] = NULL;
>+
>+	oa_config->sysfs_metric.name = oa_config->uuid;
>+	oa_config->sysfs_metric.attrs = oa_config->attrs;
>+
>+	return sysfs_create_group(oa->metrics_kobj, &oa_config->sysfs_metric);
>+}
>+
>+int xe_oa_add_config_ioctl(struct drm_device *dev, void *data,
>+			   struct drm_file *file)
>+{
>+	struct xe_oa *oa = &to_xe_device(dev)->oa;
>+	struct drm_xe_oa_config param;
>+	struct drm_xe_oa_config *arg = &param;
>+	struct xe_oa_config *oa_config, *tmp;
>+	struct xe_oa_reg *regs;
>+	int err, id;
>+
>+	if (!oa->xe) {
>+		drm_dbg(&oa->xe->drm, "xe oa interface not available for this system\n");
>+		return -ENODEV;
>+	}
>+
>+	if (xe_perf_stream_paranoid && !perfmon_capable()) {
>+		drm_dbg(&oa->xe->drm, "Insufficient privileges to add xe OA config\n");
>+		return -EACCES;
>+	}
>+
>+	err = __copy_from_user(&param, data, sizeof(param));
>+	if (XE_IOCTL_DBG(oa->xe, err))
>+		return -EFAULT;
>+
>+	if (!arg->regs_ptr || !arg->n_regs) {
>+		drm_dbg(&oa->xe->drm, "No OA registers given\n");
>+		return -EINVAL;
>+	}
>+
>+	oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL);
>+	if (!oa_config)
>+		return -ENOMEM;
>+
>+	oa_config->oa = oa;
>+	kref_init(&oa_config->ref);
>+
>+	if (!uuid_is_valid(arg->uuid)) {
>+		drm_dbg(&oa->xe->drm, "Invalid uuid format for OA config\n");
>+		err = -EINVAL;
>+		goto reg_err;
>+	}
>+
>+	/* Last character in oa_config->uuid will be 0 because oa_config is kzalloc */
>+	memcpy(oa_config->uuid, arg->uuid, sizeof(arg->uuid));
>+
>+	oa_config->regs_len = arg->n_regs;
>+	regs = xe_oa_alloc_regs(oa, xe_oa_is_valid_config_reg_addr,
>+				u64_to_user_ptr(arg->regs_ptr),
>+				arg->n_regs);
>+	if (IS_ERR(regs)) {
>+		drm_dbg(&oa->xe->drm, "Failed to create OA config for mux_regs\n");
>+		err = PTR_ERR(regs);
>+		goto reg_err;
>+	}
>+	oa_config->regs = regs;
>+
>+	err = mutex_lock_interruptible(&oa->metrics_lock);
>+	if (err)
>+		goto reg_err;
>+
>+	/* We shouldn't have too many configs, so this iteration shouldn't be too costly */
>+	idr_for_each_entry(&oa->metrics_idr, tmp, id) {
>+		if (!strcmp(tmp->uuid, oa_config->uuid)) {
>+			drm_dbg(&oa->xe->drm, "OA config already exists with this uuid\n");
>+			err = -EADDRINUSE;
>+			goto sysfs_err;
>+		}
>+	}
>+
>+	err = create_dynamic_oa_sysfs_entry(oa, oa_config);
>+	if (err) {
>+		drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n");
>+		goto sysfs_err;
>+	}
>+
>+	/* Config id 0 is invalid, id 1 for kernel stored test config */

kernel doesn't store a test config anymore, so the comment can be 
updated. You can start with 1 below though, but that's up to you.

>+	oa_config->id = idr_alloc(&oa->metrics_idr, oa_config, 2, 0, GFP_KERNEL);
>+	if (oa_config->id < 0) {
>+		drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n");
>+		err = oa_config->id;
>+		goto sysfs_err;
>+	}
>+
>+	mutex_unlock(&oa->metrics_lock);
>+
>+	drm_dbg(&oa->xe->drm, "Added config %s id=%i\n", oa_config->uuid, oa_config->id);
>+
>+	return oa_config->id;
>+
>+sysfs_err:
>+	mutex_unlock(&oa->metrics_lock);
>+reg_err:
>+	xe_oa_config_put(oa_config);
>+	drm_dbg(&oa->xe->drm, "Failed to add new OA config\n");
>+	return err;
>+}
>+
>+int xe_oa_remove_config_ioctl(struct drm_device *dev, void *data,
>+			      struct drm_file *file)
>+{
>+	struct xe_oa *oa = &to_xe_device(dev)->oa;
>+	struct xe_oa_config *oa_config;
>+	u64 arg, *ptr = data;
>+	int ret;
>+
>+	if (!oa->xe) {
>+		drm_dbg(&oa->xe->drm, "xe oa interface not available for this system\n");
>+		return -ENODEV;
>+	}
>+
>+	if (xe_perf_stream_paranoid && !perfmon_capable()) {
>+		drm_dbg(&oa->xe->drm, "Insufficient privileges to remove xe OA config\n");
>+		return -EACCES;
>+	}
>+
>+	ret = get_user(arg, ptr);
>+	if (XE_IOCTL_DBG(oa->xe, ret))
>+		return ret;
>+
>+	ret = mutex_lock_interruptible(&oa->metrics_lock);
>+	if (ret)
>+		return ret;
>+
>+	oa_config = idr_find(&oa->metrics_idr, arg);
>+	if (!oa_config) {
>+		drm_dbg(&oa->xe->drm, "Failed to remove unknown OA config\n");
>+		ret = -ENOENT;
>+		goto err_unlock;
>+	}
>+
>+	WARN_ON(arg != oa_config->id);
>+
>+	sysfs_remove_group(oa->metrics_kobj, &oa_config->sysfs_metric);
>+	idr_remove(&oa->metrics_idr, arg);
>+
>+	mutex_unlock(&oa->metrics_lock);
>+
>+	drm_dbg(&oa->xe->drm, "Removed config %s id=%i\n", oa_config->uuid, oa_config->id);
>+
>+	xe_oa_config_put(oa_config);
>+
>+	return 0;
>+
>+err_unlock:
>+	mutex_unlock(&oa->metrics_lock);
>+	return ret;
>+}
>+
>+void xe_oa_register(struct xe_device *xe)
>+{
>+	struct xe_oa *oa = &xe->oa;
>+
>+	if (!oa->xe)
>+		return;
>+
>+	oa->metrics_kobj = kobject_create_and_add("metrics",
>+						  &xe->drm.primary->kdev->kobj);
>+}
>+
>+void xe_oa_unregister(struct xe_device *xe)
>+{
>+	struct xe_oa *oa = &xe->oa;
>+
>+	if (!oa->metrics_kobj)
>+		return;
>+
>+	kobject_put(oa->metrics_kobj);
>+	oa->metrics_kobj = NULL;
>+}
>+
> static u32 num_oa_units_per_gt(struct xe_gt *gt)
> {
> 	return 1;
>@@ -259,6 +653,9 @@ int xe_oa_init(struct xe_device *xe)
> 	/* Choose a representative limit */
> 	xe_oa_sample_rate_hard_limit = xe_root_mmio_gt(xe)->info.reference_clock / 2;
>
>+	mutex_init(&oa->metrics_lock);
>+	idr_init_base(&oa->metrics_idr, 1);
>+
> 	ret = xe_oa_init_oa_units(oa);
> 	if (ret) {
> 		drm_err(&xe->drm, "OA initialization failed %d\n", ret);
>@@ -272,6 +669,12 @@ int xe_oa_init(struct xe_device *xe)
> 	return ret;
> }
>
>+static int destroy_config(int id, void *p, void *data)
>+{
>+	xe_oa_config_put(p);
>+	return 0;
>+}
>+
> void xe_oa_fini(struct xe_device *xe)
> {
> 	struct xe_oa *oa = &xe->oa;
>@@ -284,6 +687,9 @@ void xe_oa_fini(struct xe_device *xe)
> 	for_each_gt(gt, xe, i)
> 		kfree(gt->oa.oa_unit);
>
>+	idr_for_each(&oa->metrics_idr, destroy_config, oa);
>+	idr_destroy(&oa->metrics_idr);
>+
> 	oa->xe = NULL;
> }
>
>diff --git a/drivers/gpu/drm/xe/xe_oa.h b/drivers/gpu/drm/xe/xe_oa.h
>index 2145c73176953..e4863f8681b14 100644
>--- a/drivers/gpu/drm/xe/xe_oa.h
>+++ b/drivers/gpu/drm/xe/xe_oa.h
>@@ -8,11 +8,20 @@
>
> #include "xe_oa_types.h"
>
>+struct drm_device;
>+struct drm_file;
> struct xe_device;
>
> int xe_oa_init(struct xe_device *xe);
> void xe_oa_fini(struct xe_device *xe);
>+void xe_oa_register(struct xe_device *xe);
>+void xe_oa_unregister(struct xe_device *xe);
> int xe_oa_sysctl_register(void);
> void xe_oa_sysctl_unregister(void);
>
>+int xe_oa_add_config_ioctl(struct drm_device *dev, void *data,
>+			   struct drm_file *file);
>+int xe_oa_remove_config_ioctl(struct drm_device *dev, void *data,
>+			      struct drm_file *file);
>+
> #endif
>diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h
>index 8f8cf6a2bf556..2985443df3080 100644
>--- a/drivers/gpu/drm/xe/xe_oa_types.h
>+++ b/drivers/gpu/drm/xe/xe_oa_types.h
>@@ -6,6 +6,7 @@
> #ifndef _XE_OA_TYPES_H_
> #define _XE_OA_TYPES_H__
>
>+#include <linux/idr.h>
> #include <linux/math.h>
> #include <linux/types.h>
> #include <linux/mutex.h>
>@@ -120,6 +121,15 @@ struct xe_oa {
> 	/** @xe: back pointer to xe device */
> 	struct xe_device *xe;
>
>+	/** @metrics_kobj: kobj for metrics sysfs */
>+	struct kobject *metrics_kobj;
>+
>+	/** @metrics_lock: lock protecting add/remove configs */
>+	struct mutex metrics_lock;
>+
>+	/** @metrics_idr: List of dynamic configurations (struct xe_oa_config) */
>+	struct idr metrics_idr;
>+
> 	/** @oa_formats: tracks all OA formats across platforms */
> 	const struct xe_oa_format *oa_formats;
>
>diff --git a/drivers/gpu/drm/xe/xe_perf.c b/drivers/gpu/drm/xe/xe_perf.c
>index 37538e98dcc04..2aee4c7989486 100644
>--- a/drivers/gpu/drm/xe/xe_perf.c
>+++ b/drivers/gpu/drm/xe/xe_perf.c
>@@ -6,11 +6,25 @@
> #include <linux/errno.h>
> #include <linux/sysctl.h>
>
>+#include "xe_oa.h"
> #include "xe_perf.h"
>
> u32 xe_perf_stream_paranoid = true;
> static struct ctl_table_header *sysctl_header;
>
>+static int xe_oa_ioctl(struct drm_device *dev, struct drm_xe_perf_param *arg,
>+		       struct drm_file *file)
>+{
>+	switch (arg->perf_op) {
>+	case DRM_XE_PERF_OP_ADD_CONFIG:
>+		return xe_oa_add_config_ioctl(dev, (void *)arg->param, file);
>+	case DRM_XE_PERF_OP_REMOVE_CONFIG:
>+		return xe_oa_remove_config_ioctl(dev, (void *)arg->param, file);
>+	default:
>+		return -EINVAL;
>+	}
>+}
>+
> int xe_perf_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
> {
> 	struct drm_xe_perf_param *arg = data;
>@@ -19,6 +33,8 @@ int xe_perf_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
> 		return -EINVAL;
>
> 	switch (arg->perf_type) {
>+	case DRM_XE_PERF_TYPE_OA:
>+		return xe_oa_ioctl(dev, arg, file);
> 	default:
> 		return -EINVAL;
> 	}
>diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
>index 778862a5b76d4..f17134828c093 100644
>--- a/include/uapi/drm/xe_drm.h
>+++ b/include/uapi/drm/xe_drm.h
>@@ -1126,6 +1126,7 @@ struct drm_xe_wait_user_fence {
>  * enum drm_xe_perf_type - Perf stream types
>  */
> enum drm_xe_perf_type {
>+	DRM_XE_PERF_TYPE_OA,
> 	DRM_XE_PERF_TYPE_MAX,
> };
>
>@@ -1191,6 +1192,30 @@ enum drm_xe_oa_format_type {
> 	DRM_XE_OA_FMT_TYPE_PEC,
> };
>
>+/**
>+ * struct drm_xe_oa_config - OA metric configuration
>+ *
>+ * Multiple OA configs can be added using @DRM_XE_PERF_OP_ADD_CONFIG. A
>+ * particular config can be specified when opening an OA stream using
>+ * @DRM_XE_OA_PROPERTY_OA_METRIC_SET property.
>+ */
>+struct drm_xe_oa_config {
>+	/** @extensions: Pointer to the first extension struct, if any */
>+	__u64 extensions;
>+
>+	/** * @uuid: String formatted like "%\08x-%\04x-%\04x-%\04x-%\012x" */
>+	char uuid[36];
>+
>+	/** @n_regs: Number of regs in @regs_ptr */
>+	__u32 n_regs;
>+
>+	/**
>+	 * @regs_ptr: Pointer to (register address, value) pairs for OA config
>+	 * registers. Expected length of buffer is: (2 * sizeof(u32) * @n_regs).
>+	 */
>+	__u64 regs_ptr;
>+};

minor nits above, otherwise lgtm,

Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Umesh
>+
> #if defined(__cplusplus)
> }
> #endif
>-- 
>2.41.0
>

  reply	other threads:[~2023-12-19 19:10 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-08  6:43 [PATCH v7 00/17] Add OA functionality to Xe Ashutosh Dixit
2023-12-08  6:43 ` [PATCH 01/17] drm/xe/perf/uapi: "Perf" layer to support multiple perf counter stream types Ashutosh Dixit
2023-12-08  6:43 ` [PATCH 02/17] drm/xe/perf/uapi: Add perf_stream_paranoid sysctl Ashutosh Dixit
2023-12-14  0:57   ` Umesh Nerlige Ramappa
2023-12-19 20:28   ` Dixit, Ashutosh
2024-01-20  2:35     ` Dixit, Ashutosh
2024-01-24 14:10   ` Joel Granados
2023-12-08  6:43 ` [PATCH 03/17] drm/xe/oa/uapi: Add oa_max_sample_rate sysctl Ashutosh Dixit
2023-12-14  0:58   ` Umesh Nerlige Ramappa
2024-01-20  2:36     ` Dixit, Ashutosh
2024-01-24 14:11   ` Joel Granados
2023-12-08  6:43 ` [PATCH 04/17] drm/xe/oa/uapi: Add OA data formats Ashutosh Dixit
2023-12-19  1:11   ` Umesh Nerlige Ramappa
2023-12-19  1:17     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 05/17] drm/xe/oa/uapi: Initialize OA units Ashutosh Dixit
2023-12-19 16:11   ` Umesh Nerlige Ramappa
2024-01-20  2:43     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 06/17] drm/xe/oa/uapi: Add/remove OA config perf ops Ashutosh Dixit
2023-12-19 19:10   ` Umesh Nerlige Ramappa [this message]
2024-01-20  2:44     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 07/17] drm/xe/oa/uapi: Define and parse OA stream properties Ashutosh Dixit
2023-12-09 22:53   ` Dixit, Ashutosh
2023-12-19  2:59   ` Dixit, Ashutosh
2023-12-19 16:26     ` Umesh Nerlige Ramappa
2023-12-19 16:29       ` Lionel Landwerlin
2023-12-19 16:40         ` Umesh Nerlige Ramappa
2023-12-19 17:48           ` Lionel Landwerlin
2023-12-19 23:23   ` Umesh Nerlige Ramappa
2024-01-20  2:48     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 08/17] drm/xe/oa: OA stream initialization (OAG) Ashutosh Dixit
2023-12-20  2:31   ` Umesh Nerlige Ramappa
2024-01-20  2:49     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 09/17] drm/xe/oa/uapi: Expose OA stream fd Ashutosh Dixit
2023-12-20  2:52   ` Umesh Nerlige Ramappa
2024-01-20  2:50     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 10/17] drm/xe/oa/uapi: Read file_operation Ashutosh Dixit
2023-12-20  3:01   ` Umesh Nerlige Ramappa
2024-01-20  2:51     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 11/17] drm/xe/oa: Disable overrun mode for Xe2+ OAG Ashutosh Dixit
2023-12-20  3:05   ` Umesh Nerlige Ramappa
2024-01-20  2:51     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 12/17] drm/xe/oa: Add OAR support Ashutosh Dixit
2023-12-20  4:37   ` Umesh Nerlige Ramappa
2023-12-08  6:43 ` [PATCH 13/17] drm/xe/oa: Add OAC support Ashutosh Dixit
2023-12-20  4:59   ` Umesh Nerlige Ramappa
2024-01-20  2:52     ` FIXME " Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 14/17] drm/xe/oa/uapi: Query OA unit properties Ashutosh Dixit
2023-12-23  0:40   ` Umesh Nerlige Ramappa
2024-01-20  3:10     ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 15/17] drm/xe/oa/uapi: OA buffer mmap Ashutosh Dixit
2023-12-23  2:39   ` Umesh Nerlige Ramappa
2024-01-20  3:11     ` Dixit, Ashutosh
2024-02-06 23:51       ` Umesh Nerlige Ramappa
2024-01-02 11:16   ` Thomas Hellström
2024-01-08 19:50     ` Umesh Nerlige Ramappa
2024-01-09  5:14       ` Dixit, Ashutosh
2023-12-08  6:43 ` [PATCH 16/17] drm/xe/oa: Add MMIO trigger support Ashutosh Dixit
2023-12-20  4:35   ` Umesh Nerlige Ramappa
2023-12-08  6:43 ` [PATCH 17/17] drm/xe/oa: Override GuC RC with OA on PVC Ashutosh Dixit
2023-12-08  9:22 ` ✗ CI.Patch_applied: failure for Add OA functionality to Xe (rev7) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZYHqnlasZsweeh2C@unerlige-ril \
    --to=umesh.nerlige.ramappa@intel.com \
    --cc=ashutosh.dixit@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.