Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
@ 2023-06-27 16:31 Venkata Ramana Nayana
  2023-06-28 12:05 ` Kumar, Janga Rahul
  0 siblings, 1 reply; 8+ messages in thread
From: Venkata Ramana Nayana @ 2023-06-27 16:31 UTC (permalink / raw)
  To: igt-dev

There are set of engine group busyness counters provided by HW which are
exposed via PMU events. Adding a basic unit tests to read those counters.

Signed-off-by: Venkata Ramana Nayana <venkata.ramana.nayana@intel.com>
---
 include/drm-uapi/xe_drm.h |  21 +++
 lib/igt_perf.c            |  36 ++++
 lib/igt_perf.h            |   5 +
 tests/meson.build         |   1 +
 tests/xe/xe_perf_pmu.c    | 335 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 398 insertions(+)
 create mode 100644 tests/xe/xe_perf_pmu.c

diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index 432bd87ca..7bfd46c02 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -732,6 +732,27 @@ struct drm_xe_engine_create {
 	__u64 reserved[2];
 };
 
+/**
+ * DOC: perf_events exposed by xe through /sys/bus/event_sources/drivers/xe
+ *
+ */
+
+
+/* PMU event config IDs */
+
+/*
+ * Top 4 bits of every counter are GT id.
+ */
+#define __XE_PMU_GT_SHIFT (60)
+
+#define ___XE_PMU_OTHER(gt, x) \
+	(((__u64)(x)) | ((__u64)(gt) << __XE_PMU_GT_SHIFT))
+
+#define XE_PMU_RENDER_GROUP_BUSY(gt)		___XE_PMU_OTHER(gt, 1)
+#define XE_PMU_COPY_GROUP_BUSY(gt)		___XE_PMU_OTHER(gt, 2)
+#define XE_PMU_MEDIA_GROUP_BUSY(gt)		___XE_PMU_OTHER(gt, 3)
+#define XE_PMU_ANY_ENGINE_GROUP_BUSY(gt)	___XE_PMU_OTHER(gt, 4)
+
 struct drm_xe_engine_get_property {
 	/** @extensions: Pointer to the first extension struct, if any */
 	__u64 extensions;
diff --git a/lib/igt_perf.c b/lib/igt_perf.c
index ffe078adc..3866c6d77 100644
--- a/lib/igt_perf.c
+++ b/lib/igt_perf.c
@@ -69,6 +69,36 @@ const char *i915_perf_device(int i915, char *buf, int buflen)
 	return buf;
 }
 
+const char *xe_perf_device(int xe, char *buf, int buflen)
+{
+	char *s;
+	char pref[] = "xe_";
+	int len = strlen(pref);
+
+
+	if (!buf || buflen < len)
+		return "xe";
+
+	memcpy(buf, pref, len);
+
+	if (!bus_address(xe, buf + len, buflen - len))
+		buf[len - 1] = '\0';
+
+	/* Convert all colons in the address to '_', thanks perf! */
+	for (s = buf; *s; s++)
+		if (*s == ':')
+			*s = '_';
+
+	return buf;
+}
+
+uint64_t xe_perf_type_id(int xe)
+{
+	char buf[80];
+
+	return igt_perf_type_id(xe_perf_device(xe, buf, sizeof(buf)));
+}
+
 uint64_t i915_perf_type_id(int i915)
 {
 	char buf[80];
@@ -147,6 +177,12 @@ int perf_igfx_open_group(uint64_t config, int group)
 			  PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
 }
 
+int perf_xe_open(int xe, uint64_t config)
+{
+	return _perf_open(xe_perf_type_id(xe), config, -1,
+			PERF_FORMAT_TOTAL_TIME_ENABLED);
+}
+
 int perf_i915_open(int i915, uint64_t config)
 {
 	return _perf_open(i915_perf_type_id(i915), config, -1,
diff --git a/lib/igt_perf.h b/lib/igt_perf.h
index 4d86e31ae..3d9ba2917 100644
--- a/lib/igt_perf.h
+++ b/lib/igt_perf.h
@@ -61,10 +61,15 @@ int igt_perf_open_group(uint64_t type, uint64_t config, int group);
 const char *i915_perf_device(int i915, char *buf, int buflen);
 uint64_t i915_perf_type_id(int i915);
 
+const char *xe_perf_device(int xe, char *buf, int buflen);
+uint64_t xe_perf_type_id(int);
+
 int perf_igfx_open(uint64_t config);
 int perf_igfx_open_group(uint64_t config, int group);
 
 int perf_i915_open(int i915, uint64_t config);
 int perf_i915_open_group(int i915, uint64_t config, int group);
 
+int perf_xe_open(int xe, uint64_t config);
+
 #endif /* I915_PERF_H */
diff --git a/tests/meson.build b/tests/meson.build
index 85ea7e74e..e64d8232e 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -270,6 +270,7 @@ xe_progs = [
 	'xe_vm',
 	'xe_waitfence',
 	'xe_spin_batch',
+	'xe_perf_pmu',
 ]
 
 msm_progs = [
diff --git a/tests/xe/xe_perf_pmu.c b/tests/xe/xe_perf_pmu.c
new file mode 100644
index 000000000..97c2f84a3
--- /dev/null
+++ b/tests/xe/xe_perf_pmu.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+/**
+ * TEST: Basic tests for verify pmu perf interface
+ * Category: Hardware building block
+ * Sub-category: pmu interface
+ * Functionality: pmu
+ * Test category: functionality test
+ */
+
+#include <fcntl.h>
+
+#include "igt.h"
+#include "lib/igt_syncobj.h"
+#include "lib/intel_reg.h"
+#include "lib/igt_perf.h"
+#include "xe_drm.h"
+
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+#include "xe/xe_spin.h"
+#include <string.h>
+
+#define MAX_INSTANCE 9
+
+static uint64_t pmu_read(int fd)
+{
+	uint64_t  data[2];
+
+	igt_assert_eq(read(fd, data, sizeof(data)), sizeof(data));
+
+	return data[0];
+}
+
+static int open_pmu(int fd, uint64_t config)
+{
+	int perf_fd;
+
+	perf_fd = perf_xe_open(fd, config);
+	igt_skip_on(perf_fd < 0 && errno == ENODEV);
+	igt_assert(perf_fd >= 0);
+
+	return perf_fd;
+}
+
+static uint64_t engine_group_get_config(int gt, int class)
+{
+	uint64_t config;
+
+	switch (class) {
+	case DRM_XE_ENGINE_CLASS_COPY:
+		config = XE_PMU_COPY_GROUP_BUSY(gt);
+		break;
+	case DRM_XE_ENGINE_CLASS_RENDER:
+	case DRM_XE_ENGINE_CLASS_COMPUTE:
+		config = XE_PMU_RENDER_GROUP_BUSY(gt);
+		break;
+	case DRM_XE_ENGINE_CLASS_VIDEO_DECODE:
+	case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
+		config = XE_PMU_MEDIA_GROUP_BUSY(gt);
+		break;
+	}
+
+	return config;
+}
+
+/**
+ * Test: Basic test for measure the active time when engine of any class active
+ *
+ * SUBTEST: any-engine-group-busy
+ * Description:
+ *      Run a test to measure the global activity time by submitting
+ *      the WL to all existing engines.
+ * Run type: FULL
+ * TODO: change ``'Run type' == FULL`` to a better category
+ */
+static void test_any_engine_busyness(int fd, struct drm_xe_engine_class_instance *eci)
+{
+	uint32_t vm;
+	uint64_t addr = 0x1a0000;
+	struct drm_xe_sync sync[2] = {
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+	};
+	struct drm_xe_exec exec = {
+		.num_batch_buffer = 1,
+		.num_syncs = 2,
+		.syncs = to_user_pointer(sync),
+	};
+	uint32_t engine;
+	uint32_t syncobj;
+	size_t bo_size;
+	uint32_t bo = 0;
+	struct xe_spin *spin;
+	uint32_t pmu_fd;
+	uint64_t count, idle = 0;
+
+	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
+	bo_size = sizeof(*spin);
+	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
+			xe_get_default_alignment(fd));
+
+	bo = xe_bo_create(fd, eci->gt_id, vm, bo_size);
+	spin = xe_bo_map(fd, bo, bo_size);
+
+	engine = xe_engine_create(fd, vm, eci, 0);
+	syncobj = syncobj_create(fd, 0);
+
+	sync[0].handle = syncobj_create(fd, 0);
+	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
+
+	pmu_fd = open_pmu(fd, XE_PMU_ANY_ENGINE_GROUP_BUSY(eci->gt_id));
+
+	xe_spin_init(spin, addr, false);
+
+	sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
+	sync[1].flags |= DRM_XE_SYNC_SIGNAL;
+	sync[1].handle = syncobj;
+
+	exec.engine_id = engine;
+	exec.address = addr;
+	xe_exec(fd, &exec);
+
+	xe_spin_wait_started(spin);
+	usleep(50000);
+
+	igt_assert(!syncobj_wait(fd, &syncobj, 1, 1, 0, NULL));
+	xe_spin_end(spin);
+
+	igt_assert(syncobj_wait(fd, &syncobj, 1, INT64_MAX, 0, NULL));
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
+	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+	syncobj_destroy(fd, sync[0].handle);
+	syncobj_destroy(fd, syncobj);
+
+	count = pmu_read(pmu_fd);
+	igt_assert_lt_u64(idle, count);
+	igt_debug("Incrementing counter all-busy-group %ld ns\n", count);
+
+	xe_engine_destroy(fd, engine);
+	munmap(spin, bo_size);
+	gem_close(fd, bo);
+	xe_vm_destroy(fd, vm);
+	close(pmu_fd);
+}
+
+/**
+ * Test: Basic test for measure the active time across engine class
+ *
+ * SUBTEST: render-busy
+ * Description:
+ *	Run a test to measure the active engine class time by submitting the
+ *	WL to all instances of a class
+ * Run type: FULL
+ * TODO: change ``'Run type' == FULL`` to a better category
+ *
+ * SUBTEST: compute-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ * TODO: change ``'Run type' == FULL`` to a better category
+ *
+ * SUBTEST: copy-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ * TODO: change ``'Run type' == FULL`` to a better category
+ *
+ * SUBTEST: vcs-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ * TODO: change ``'Run type' == FULL`` to a better category
+ *
+ * SUBTEST: vecs-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ * TODO: change ``'Run type' == FULL`` to a better category
+ *
+ */
+
+static void test_engine_group_busyness(int fd, int gt, int class, const char *name)
+{
+	uint32_t vm;
+	uint64_t addr = 0x1a0000;
+	struct drm_xe_sync sync[2] = {
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+	};
+	struct drm_xe_exec exec = {
+		.num_batch_buffer = 1,
+		.num_syncs = 2,
+		.syncs = to_user_pointer(sync),
+	};
+	uint32_t engines[MAX_INSTANCE];
+	uint32_t syncobjs[MAX_INSTANCE];
+	int    pmu_fd;
+	size_t bo_size;
+	uint32_t bo = 0, i = 0;
+	struct {
+		struct xe_spin spin;
+	} *data;
+	struct drm_xe_engine_class_instance *hwe;
+	struct drm_xe_engine_class_instance eci[MAX_INSTANCE];
+	int num_placements = 0;
+	uint64_t config, count, idle = 0;
+
+	config = engine_group_get_config(gt, class);
+
+	xe_for_each_hw_engine(fd, hwe) {
+		if (hwe->engine_class != class || hwe->gt_id != gt)
+			continue;
+
+		eci[num_placements++] = *hwe;
+	}
+
+	if (!num_placements) {
+		igt_info("Engine class:%d gt:%d not enabled on this platform\n", class, gt);
+		return;
+	}
+
+	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
+	bo_size = sizeof(*data) * num_placements;
+	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd), xe_get_default_alignment(fd));
+
+	bo = xe_bo_create(fd, gt, vm, bo_size);
+	data = xe_bo_map(fd, bo, bo_size);
+
+	for (i = 0; i < num_placements; i++) {
+		struct drm_xe_engine_create create = {
+			.vm_id = vm,
+			.width = 1,
+			.num_placements = num_placements,
+			.instances = to_user_pointer(eci),
+		};
+
+		igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_ENGINE_CREATE,
+					&create), 0);
+		engines[i] = create.engine_id;
+		syncobjs[i] = syncobj_create(fd, 0);
+	};
+
+	sync[0].handle = syncobj_create(fd, 0);
+	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
+
+	pmu_fd = open_pmu(fd, config);
+
+	for (i = 0; i < num_placements; i++) {
+		uint64_t spin_offset = (char *)&data[i].spin - (char *)data;
+		uint64_t spin_addr = addr + spin_offset;
+
+		xe_spin_init(&data[i].spin, spin_addr, false);
+		sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
+		sync[1].flags |= DRM_XE_SYNC_SIGNAL;
+		sync[1].handle = syncobjs[i];
+
+		exec.engine_id = engines[i];
+		exec.address = spin_addr;
+		xe_exec(fd, &exec);
+		xe_spin_wait_started(&data[i].spin);
+	}
+
+	for (i = 0; i < num_placements; i++) {
+		xe_spin_end(&data[i].spin);
+		igt_assert(syncobj_wait(fd, &syncobjs[i], 1, INT64_MAX, 0,
+					NULL));
+	}
+
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
+	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+
+	syncobj_destroy(fd, sync[0].handle);
+	for (i = 0; i < num_placements; i++) {
+		syncobj_destroy(fd, syncobjs[i]);
+		xe_engine_destroy(fd, engines[i]);
+	}
+
+	count = pmu_read(pmu_fd);
+	igt_assert_lt_u64(idle, count);
+	igt_debug("Incrementing counter %s-gt-%d  %ld ns\n", name, gt, count);
+
+	munmap(data, bo_size);
+	gem_close(fd, bo);
+	xe_vm_destroy(fd, vm);
+	close(pmu_fd);
+}
+
+igt_main
+{
+	struct drm_xe_engine_class_instance *hwe;
+	const struct section {
+		const char *name;
+		int class;
+	} sections[] = {
+		{ "render-busy", DRM_XE_ENGINE_CLASS_RENDER },
+		{ "compute-busy", DRM_XE_ENGINE_CLASS_COMPUTE },
+		{ "copy-busy", DRM_XE_ENGINE_CLASS_COPY },
+		{ "vcs-busy", DRM_XE_ENGINE_CLASS_VIDEO_DECODE },
+		{ "vecs-busy", DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE },
+		{ NULL },
+	};
+	int gt;
+	int class;
+	int fd;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_XE);
+		xe_device_get(fd);
+	}
+
+	for (const struct section *s = sections; s->name; s++) {
+		igt_subtest_f("%s", s->name)
+			xe_for_each_gt(fd, gt)
+				xe_for_each_hw_engine_class(class)
+					if (class == s->class)
+						test_engine_group_busyness(fd, gt, class, s->name);
+	}
+
+	igt_subtest("any-engine-group-busy")
+		xe_for_each_hw_engine(fd, hwe)
+			test_any_engine_busyness(fd, hwe);
+
+	igt_fixture {
+		xe_device_put(fd);
+		close(fd);
+	}
+}
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
  2023-06-27 16:31 Venkata Ramana Nayana
@ 2023-06-28 12:05 ` Kumar, Janga Rahul
  2023-07-04  9:59   ` Nayana, Venkata Ramana
  0 siblings, 1 reply; 8+ messages in thread
From: Kumar, Janga Rahul @ 2023-06-28 12:05 UTC (permalink / raw)
  To: Nayana, Venkata Ramana, igt-dev@lists.freedesktop.org



> -----Original Message-----
> From: igt-dev <igt-dev-bounces@lists.freedesktop.org> On Behalf Of Venkata
> Ramana Nayana
> Sent: 27 June 2023 22:02
> To: igt-dev@lists.freedesktop.org
> Subject: [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
> 
> There are set of engine group busyness counters provided by HW which are
> exposed via PMU events. Adding a basic unit tests to read those counters.

Pls mention driver patch details exposing PMU events if It is in review.
 
> Signed-off-by: Venkata Ramana Nayana <venkata.ramana.nayana@intel.com>
> ---
>  include/drm-uapi/xe_drm.h |  21 +++
>  lib/igt_perf.c            |  36 ++++
>  lib/igt_perf.h            |   5 +
>  tests/meson.build         |   1 +
>  tests/xe/xe_perf_pmu.c    | 335 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 398 insertions(+)
>  create mode 100644 tests/xe/xe_perf_pmu.c
> 
> diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h index
> 432bd87ca..7bfd46c02 100644
> --- a/include/drm-uapi/xe_drm.h
> +++ b/include/drm-uapi/xe_drm.h
Do not edit this file.
See "drm-uapi/xe_drm: Sync from drm-xe-next" commit to sync this file.

> @@ -732,6 +732,27 @@ struct drm_xe_engine_create {
>  	__u64 reserved[2];
>  };
> 
> +/**
> + * DOC: perf_events exposed by xe through
> +/sys/bus/event_sources/drivers/xe
> + *
> + */
> +
> +
> +/* PMU event config IDs */
> +
> +/*
> + * Top 4 bits of every counter are GT id.
> + */
> +#define __XE_PMU_GT_SHIFT (60)
> +
> +#define ___XE_PMU_OTHER(gt, x) \
> +	(((__u64)(x)) | ((__u64)(gt) << __XE_PMU_GT_SHIFT))
> +
> +#define XE_PMU_RENDER_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 1)
> +#define XE_PMU_COPY_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 2)
> +#define XE_PMU_MEDIA_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 3)
> +#define XE_PMU_ANY_ENGINE_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 4)
> +
>  struct drm_xe_engine_get_property {
>  	/** @extensions: Pointer to the first extension struct, if any */
>  	__u64 extensions;
> diff --git a/lib/igt_perf.c b/lib/igt_perf.c index ffe078adc..3866c6d77 100644
> --- a/lib/igt_perf.c
> +++ b/lib/igt_perf.c
> @@ -69,6 +69,36 @@ const char *i915_perf_device(int i915, char *buf, int
> buflen)
>  	return buf;
>  }
> 
> +const char *xe_perf_device(int xe, char *buf, int buflen) {
> +	char *s;
> +	char pref[] = "xe_";
> +	int len = strlen(pref);
> +
> +
> +	if (!buf || buflen < len)
> +		return "xe";
> +
> +	memcpy(buf, pref, len);
> +
> +	if (!bus_address(xe, buf + len, buflen - len))
> +		buf[len - 1] = '\0';
> +
> +	/* Convert all colons in the address to '_', thanks perf! */
> +	for (s = buf; *s; s++)
> +		if (*s == ':')
> +			*s = '_';
> +
> +	return buf;
> +}
> +
> +uint64_t xe_perf_type_id(int xe)
> +{
> +	char buf[80];
> +
> +	return igt_perf_type_id(xe_perf_device(xe, buf, sizeof(buf))); }
> +
>  uint64_t i915_perf_type_id(int i915)
>  {
>  	char buf[80];
> @@ -147,6 +177,12 @@ int perf_igfx_open_group(uint64_t config, int group)
>  			  PERF_FORMAT_TOTAL_TIME_ENABLED |
> PERF_FORMAT_GROUP);  }
> 
> +int perf_xe_open(int xe, uint64_t config) {
> +	return _perf_open(xe_perf_type_id(xe), config, -1,
> +			PERF_FORMAT_TOTAL_TIME_ENABLED);
> +}
> +
>  int perf_i915_open(int i915, uint64_t config)  {
>  	return _perf_open(i915_perf_type_id(i915), config, -1, diff --git
> a/lib/igt_perf.h b/lib/igt_perf.h index 4d86e31ae..3d9ba2917 100644
> --- a/lib/igt_perf.h
> +++ b/lib/igt_perf.h
> @@ -61,10 +61,15 @@ int igt_perf_open_group(uint64_t type, uint64_t config,
> int group);  const char *i915_perf_device(int i915, char *buf, int buflen);
> uint64_t i915_perf_type_id(int i915);
> 
> +const char *xe_perf_device(int xe, char *buf, int buflen); uint64_t
> +xe_perf_type_id(int);
> +
>  int perf_igfx_open(uint64_t config);
>  int perf_igfx_open_group(uint64_t config, int group);
> 
>  int perf_i915_open(int i915, uint64_t config);  int perf_i915_open_group(int
> i915, uint64_t config, int group);
> 
> +int perf_xe_open(int xe, uint64_t config);
> +
>  #endif /* I915_PERF_H */
> diff --git a/tests/meson.build b/tests/meson.build index 85ea7e74e..e64d8232e
> 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -270,6 +270,7 @@ xe_progs = [
>  	'xe_vm',
>  	'xe_waitfence',
>  	'xe_spin_batch',
> +	'xe_perf_pmu',
>  ]
> 
>  msm_progs = [
> diff --git a/tests/xe/xe_perf_pmu.c b/tests/xe/xe_perf_pmu.c new file mode
> 100644 index 000000000..97c2f84a3
> --- /dev/null
> +++ b/tests/xe/xe_perf_pmu.c
> @@ -0,0 +1,335 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +/**
> + * TEST: Basic tests for verify pmu perf interface
> + * Category: Hardware building block
> + * Sub-category: pmu interface
> + * Functionality: pmu
> + * Test category: functionality test
Add Run Type here.

> + */
> +
> +#include <fcntl.h>
> +
> +#include "igt.h"
> +#include "lib/igt_syncobj.h"
> +#include "lib/intel_reg.h"
> +#include "lib/igt_perf.h"
> +#include "xe_drm.h"
> +
> +#include "xe/xe_ioctl.h"
> +#include "xe/xe_query.h"
> +#include "xe/xe_spin.h"
> +#include <string.h>
Keep includes sorted alphabetically, also please put system includes 
first, then write one newline, then igt includes.

> +
> +#define MAX_INSTANCE 9
> +
> +static uint64_t pmu_read(int fd)
> +{
> +	uint64_t  data[2];
> +
> +	igt_assert_eq(read(fd, data, sizeof(data)), sizeof(data));
> +
> +	return data[0];
> +}
> +
> +static int open_pmu(int fd, uint64_t config) {
> +	int perf_fd;
> +
> +	perf_fd = perf_xe_open(fd, config);
> +	igt_skip_on(perf_fd < 0 && errno == ENODEV);
> +	igt_assert(perf_fd >= 0);
> +
> +	return perf_fd;
> +}
> +
> +static uint64_t engine_group_get_config(int gt, int class) {
> +	uint64_t config;
> +
> +	switch (class) {
> +	case DRM_XE_ENGINE_CLASS_COPY:
> +		config = XE_PMU_COPY_GROUP_BUSY(gt);
> +		break;
> +	case DRM_XE_ENGINE_CLASS_RENDER:
> +	case DRM_XE_ENGINE_CLASS_COMPUTE:
> +		config = XE_PMU_RENDER_GROUP_BUSY(gt);
> +		break;
> +	case DRM_XE_ENGINE_CLASS_VIDEO_DECODE:
> +	case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
> +		config = XE_PMU_MEDIA_GROUP_BUSY(gt);
> +		break;
> +	}
> +
> +	return config;
> +}
> +
> +/**
> + * Test: Basic test for measure the active time when engine of any
> +class active
> + *
> + * SUBTEST: any-engine-group-busy
> + * Description:
> + *      Run a test to measure the global activity time by submitting
> + *      the WL to all existing engines.
> + * Run type: FULL
> + * TODO: change ``'Run type' == FULL`` to a better category  */ static
> +void test_any_engine_busyness(int fd, struct
> +drm_xe_engine_class_instance *eci) {
> +	uint32_t vm;
> +	uint64_t addr = 0x1a0000;
> +	struct drm_xe_sync sync[2] = {
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
> +	};
> +	struct drm_xe_exec exec = {
> +		.num_batch_buffer = 1,
> +		.num_syncs = 2,
> +		.syncs = to_user_pointer(sync),
> +	};
> +	uint32_t engine;
> +	uint32_t syncobj;
> +	size_t bo_size;
> +	uint32_t bo = 0;
> +	struct xe_spin *spin;
> +	uint32_t pmu_fd;
> +	uint64_t count, idle = 0;
> +
> +	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
> +	bo_size = sizeof(*spin);
> +	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
> +			xe_get_default_alignment(fd));
> +
> +	bo = xe_bo_create(fd, eci->gt_id, vm, bo_size);
> +	spin = xe_bo_map(fd, bo, bo_size);
> +
> +	engine = xe_engine_create(fd, vm, eci, 0);
> +	syncobj = syncobj_create(fd, 0);
> +
> +	sync[0].handle = syncobj_create(fd, 0);
> +	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
> +
> +	pmu_fd = open_pmu(fd, XE_PMU_ANY_ENGINE_GROUP_BUSY(eci-
> >gt_id));
> +
> +	xe_spin_init(spin, addr, false);
> +
> +	sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
> +	sync[1].flags |= DRM_XE_SYNC_SIGNAL;
> +	sync[1].handle = syncobj;
> +
> +	exec.engine_id = engine;
> +	exec.address = addr;
> +	xe_exec(fd, &exec);
> +
> +	xe_spin_wait_started(spin);
> +	usleep(50000);
> +
> +	igt_assert(!syncobj_wait(fd, &syncobj, 1, 1, 0, NULL));
> +	xe_spin_end(spin);
> +
> +	igt_assert(syncobj_wait(fd, &syncobj, 1, INT64_MAX, 0, NULL));
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
> +	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +	syncobj_destroy(fd, sync[0].handle);
> +	syncobj_destroy(fd, syncobj);
> +
> +	count = pmu_read(pmu_fd);
> +	igt_assert_lt_u64(idle, count);
> +	igt_debug("Incrementing counter all-busy-group %ld ns\n", count);
> +
> +	xe_engine_destroy(fd, engine);
> +	munmap(spin, bo_size);
> +	gem_close(fd, bo);
> +	xe_vm_destroy(fd, vm);
> +	close(pmu_fd);
> +}
> +
> +/**
> + * Test: Basic test for measure the active time across engine class
> + *
> + * SUBTEST: render-busy
> + * Description:
> + *	Run a test to measure the active engine class time by submitting the
> + *	WL to all instances of a class
> + * Run type: FULL
> + * TODO: change ``'Run type' == FULL`` to a better category
Remove TODO's these are not required now.
Existing ones are removed by  "tests/xe: remove an useless TODO message"
> + *
> + * SUBTEST: compute-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + * TODO: change ``'Run type' == FULL`` to a better category
> + *
> + * SUBTEST: copy-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + * TODO: change ``'Run type' == FULL`` to a better category
> + *
> + * SUBTEST: vcs-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + * TODO: change ``'Run type' == FULL`` to a better category
> + *
> + * SUBTEST: vecs-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + * TODO: change ``'Run type' == FULL`` to a better category
> + *
> + */
> +
> +static void test_engine_group_busyness(int fd, int gt, int class, const
> +char *name) {
> +	uint32_t vm;
> +	uint64_t addr = 0x1a0000;
> +	struct drm_xe_sync sync[2] = {
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
> +	};
> +	struct drm_xe_exec exec = {
> +		.num_batch_buffer = 1,
> +		.num_syncs = 2,
> +		.syncs = to_user_pointer(sync),
> +	};
> +	uint32_t engines[MAX_INSTANCE];
> +	uint32_t syncobjs[MAX_INSTANCE];
> +	int    pmu_fd;
> +	size_t bo_size;
> +	uint32_t bo = 0, i = 0;
> +	struct {
> +		struct xe_spin spin;
> +	} *data;
> +	struct drm_xe_engine_class_instance *hwe;
> +	struct drm_xe_engine_class_instance eci[MAX_INSTANCE];
> +	int num_placements = 0;
> +	uint64_t config, count, idle = 0;
> +
> +	config = engine_group_get_config(gt, class);
> +
> +	xe_for_each_hw_engine(fd, hwe) {
> +		if (hwe->engine_class != class || hwe->gt_id != gt)
> +			continue;
> +
> +		eci[num_placements++] = *hwe;
> +	}
> +
> +	if (!num_placements) {
> +		igt_info("Engine class:%d gt:%d not enabled on this
> platform\n", class, gt);
> +		return;
> +	}
> +
> +	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
> +	bo_size = sizeof(*data) * num_placements;
> +	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
> +xe_get_default_alignment(fd));
> +
> +	bo = xe_bo_create(fd, gt, vm, bo_size);
> +	data = xe_bo_map(fd, bo, bo_size);
> +
> +	for (i = 0; i < num_placements; i++) {
> +		struct drm_xe_engine_create create = {
> +			.vm_id = vm,
> +			.width = 1,
> +			.num_placements = num_placements,
> +			.instances = to_user_pointer(eci),
> +		};
> +
> +		igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_ENGINE_CREATE,
> +					&create), 0);
> +		engines[i] = create.engine_id;
> +		syncobjs[i] = syncobj_create(fd, 0);
> +	};
> +
> +	sync[0].handle = syncobj_create(fd, 0);
> +	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
> +
> +	pmu_fd = open_pmu(fd, config);
Pls check for engine idleness before submitting the workload.

Thanks,
Rahul
> +
> +	for (i = 0; i < num_placements; i++) {
> +		uint64_t spin_offset = (char *)&data[i].spin - (char *)data;
> +		uint64_t spin_addr = addr + spin_offset;
> +
> +		xe_spin_init(&data[i].spin, spin_addr, false);
> +		sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
> +		sync[1].flags |= DRM_XE_SYNC_SIGNAL;
> +		sync[1].handle = syncobjs[i];
> +
> +		exec.engine_id = engines[i];
> +		exec.address = spin_addr;
> +		xe_exec(fd, &exec);
> +		xe_spin_wait_started(&data[i].spin);
> +	}
> +
> +	for (i = 0; i < num_placements; i++) {
> +		xe_spin_end(&data[i].spin);
> +		igt_assert(syncobj_wait(fd, &syncobjs[i], 1, INT64_MAX, 0,
> +					NULL));
> +	}
> +
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
> +	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +
> +	syncobj_destroy(fd, sync[0].handle);
> +	for (i = 0; i < num_placements; i++) {
> +		syncobj_destroy(fd, syncobjs[i]);
> +		xe_engine_destroy(fd, engines[i]);
> +	}
> +
> +	count = pmu_read(pmu_fd);
> +	igt_assert_lt_u64(idle, count);
> +	igt_debug("Incrementing counter %s-gt-%d  %ld ns\n", name, gt, count);
> +
> +	munmap(data, bo_size);
> +	gem_close(fd, bo);
> +	xe_vm_destroy(fd, vm);
> +	close(pmu_fd);
> +}
> +
> +igt_main
> +{
> +	struct drm_xe_engine_class_instance *hwe;
> +	const struct section {
> +		const char *name;
> +		int class;
> +	} sections[] = {
> +		{ "render-busy", DRM_XE_ENGINE_CLASS_RENDER },
> +		{ "compute-busy", DRM_XE_ENGINE_CLASS_COMPUTE },
> +		{ "copy-busy", DRM_XE_ENGINE_CLASS_COPY },
> +		{ "vcs-busy", DRM_XE_ENGINE_CLASS_VIDEO_DECODE },
> +		{ "vecs-busy", DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE },
> +		{ NULL },
> +	};
> +	int gt;
> +	int class;
> +	int fd;
> +
> +	igt_fixture {
> +		fd = drm_open_driver(DRIVER_XE);
> +		xe_device_get(fd);
> +	}
> +
> +	for (const struct section *s = sections; s->name; s++) {
> +		igt_subtest_f("%s", s->name)
> +			xe_for_each_gt(fd, gt)
> +				xe_for_each_hw_engine_class(class)
> +					if (class == s->class)
> +
> 	test_engine_group_busyness(fd, gt, class, s->name);
> +	}
> +
> +	igt_subtest("any-engine-group-busy")
> +		xe_for_each_hw_engine(fd, hwe)
> +			test_any_engine_busyness(fd, hwe);
> +
> +	igt_fixture {
> +		xe_device_put(fd);
> +		close(fd);
> +	}
> +}
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
  2023-06-28 12:05 ` Kumar, Janga Rahul
@ 2023-07-04  9:59   ` Nayana, Venkata Ramana
  0 siblings, 0 replies; 8+ messages in thread
From: Nayana, Venkata Ramana @ 2023-07-04  9:59 UTC (permalink / raw)
  To: Kumar, Janga Rahul, igt-dev@lists.freedesktop.org

Thanks for the review.. comments inline.

> -----Original Message-----
> From: Kumar, Janga Rahul <janga.rahul.kumar@intel.com>
> Sent: Wednesday, June 28, 2023 5:35 PM
> To: Nayana, Venkata Ramana <venkata.ramana.nayana@intel.com>; igt-
> dev@lists.freedesktop.org
> Subject: RE: [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu
> interface
> 
> 
> 
> > -----Original Message-----
> > From: igt-dev <igt-dev-bounces@lists.freedesktop.org> On Behalf Of
> > Venkata Ramana Nayana
> > Sent: 27 June 2023 22:02
> > To: igt-dev@lists.freedesktop.org
> > Subject: [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu
> > interface
> >
> > There are set of engine group busyness counters provided by HW which
> > are exposed via PMU events. Adding a basic unit tests to read those
> counters.
> 
> Pls mention driver patch details exposing PMU events if It is in review.
> 
sure. Will include driver patch in the next series.
> > Signed-off-by: Venkata Ramana Nayana
> <venkata.ramana.nayana@intel.com>
> > ---
> >  include/drm-uapi/xe_drm.h |  21 +++
> >  lib/igt_perf.c            |  36 ++++
> >  lib/igt_perf.h            |   5 +
> >  tests/meson.build         |   1 +
> >  tests/xe/xe_perf_pmu.c    | 335
> ++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 398 insertions(+)
> >  create mode 100644 tests/xe/xe_perf_pmu.c
> >
> > diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
> > index
> > 432bd87ca..7bfd46c02 100644
> > --- a/include/drm-uapi/xe_drm.h
> > +++ b/include/drm-uapi/xe_drm.h
> Do not edit this file.
> See "drm-uapi/xe_drm: Sync from drm-xe-next" commit to sync this file.
> 
Currently the PMU xe kmd changes not yet merged so to avoid compilation issues and
to verify the functionality including/editing these header files.
> > @@ -732,6 +732,27 @@ struct drm_xe_engine_create {
> >  	__u64 reserved[2];
> >  };
> >
> > +/**
> > + * DOC: perf_events exposed by xe through
> > +/sys/bus/event_sources/drivers/xe
> > + *
> > + */
> > +
> > +
> > +/* PMU event config IDs */
> > +
> > +/*
> > + * Top 4 bits of every counter are GT id.
> > + */
> > +#define __XE_PMU_GT_SHIFT (60)
> > +
> > +#define ___XE_PMU_OTHER(gt, x) \
> > +	(((__u64)(x)) | ((__u64)(gt) << __XE_PMU_GT_SHIFT))
> > +
> > +#define XE_PMU_RENDER_GROUP_BUSY(gt)
> > 	___XE_PMU_OTHER(gt, 1)
> > +#define XE_PMU_COPY_GROUP_BUSY(gt)
> > 	___XE_PMU_OTHER(gt, 2)
> > +#define XE_PMU_MEDIA_GROUP_BUSY(gt)
> > 	___XE_PMU_OTHER(gt, 3)
> > +#define XE_PMU_ANY_ENGINE_GROUP_BUSY(gt)
> > 	___XE_PMU_OTHER(gt, 4)
> > +
> >  struct drm_xe_engine_get_property {
> >  	/** @extensions: Pointer to the first extension struct, if any */
> >  	__u64 extensions;
> > diff --git a/lib/igt_perf.c b/lib/igt_perf.c index
> > ffe078adc..3866c6d77 100644
> > --- a/lib/igt_perf.c
> > +++ b/lib/igt_perf.c
> > @@ -69,6 +69,36 @@ const char *i915_perf_device(int i915, char *buf,
> > int
> > buflen)
> >  	return buf;
> >  }
> >
> > +const char *xe_perf_device(int xe, char *buf, int buflen) {
> > +	char *s;
> > +	char pref[] = "xe_";
> > +	int len = strlen(pref);
> > +
> > +
> > +	if (!buf || buflen < len)
> > +		return "xe";
> > +
> > +	memcpy(buf, pref, len);
> > +
> > +	if (!bus_address(xe, buf + len, buflen - len))
> > +		buf[len - 1] = '\0';
> > +
> > +	/* Convert all colons in the address to '_', thanks perf! */
> > +	for (s = buf; *s; s++)
> > +		if (*s == ':')
> > +			*s = '_';
> > +
> > +	return buf;
> > +}
> > +
> > +uint64_t xe_perf_type_id(int xe)
> > +{
> > +	char buf[80];
> > +
> > +	return igt_perf_type_id(xe_perf_device(xe, buf, sizeof(buf))); }
> > +
> >  uint64_t i915_perf_type_id(int i915)
> >  {
> >  	char buf[80];
> > @@ -147,6 +177,12 @@ int perf_igfx_open_group(uint64_t config, int
> group)
> >  			  PERF_FORMAT_TOTAL_TIME_ENABLED |
> PERF_FORMAT_GROUP);  }
> >
> > +int perf_xe_open(int xe, uint64_t config) {
> > +	return _perf_open(xe_perf_type_id(xe), config, -1,
> > +			PERF_FORMAT_TOTAL_TIME_ENABLED);
> > +}
> > +
> >  int perf_i915_open(int i915, uint64_t config)  {
> >  	return _perf_open(i915_perf_type_id(i915), config, -1, diff --git
> > a/lib/igt_perf.h b/lib/igt_perf.h index 4d86e31ae..3d9ba2917 100644
> > --- a/lib/igt_perf.h
> > +++ b/lib/igt_perf.h
> > @@ -61,10 +61,15 @@ int igt_perf_open_group(uint64_t type, uint64_t
> > config, int group);  const char *i915_perf_device(int i915, char *buf,
> > int buflen); uint64_t i915_perf_type_id(int i915);
> >
> > +const char *xe_perf_device(int xe, char *buf, int buflen); uint64_t
> > +xe_perf_type_id(int);
> > +
> >  int perf_igfx_open(uint64_t config);
> >  int perf_igfx_open_group(uint64_t config, int group);
> >
> >  int perf_i915_open(int i915, uint64_t config);  int
> > perf_i915_open_group(int i915, uint64_t config, int group);
> >
> > +int perf_xe_open(int xe, uint64_t config);
> > +
> >  #endif /* I915_PERF_H */
> > diff --git a/tests/meson.build b/tests/meson.build index
> > 85ea7e74e..e64d8232e
> > 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -270,6 +270,7 @@ xe_progs = [
> >  	'xe_vm',
> >  	'xe_waitfence',
> >  	'xe_spin_batch',
> > +	'xe_perf_pmu',
> >  ]
> >
> >  msm_progs = [
> > diff --git a/tests/xe/xe_perf_pmu.c b/tests/xe/xe_perf_pmu.c new file
> > mode
> > 100644 index 000000000..97c2f84a3
> > --- /dev/null
> > +++ b/tests/xe/xe_perf_pmu.c
> > @@ -0,0 +1,335 @@
> > +// SPDX-License-Identifier: MIT
> > +/*
> > + * Copyright © 2021 Intel Corporation  */
> > +
> > +/**
> > + * TEST: Basic tests for verify pmu perf interface
> > + * Category: Hardware building block
> > + * Sub-category: pmu interface
> > + * Functionality: pmu
> > + * Test category: functionality test
> Add Run Type here.
>
I have gone through some other igt's.. looks like sub-test comments require "Run Type".
Here it is not required.
 
> > + */
> > +
> > +#include <fcntl.h>
> > +
> > +#include "igt.h"
> > +#include "lib/igt_syncobj.h"
> > +#include "lib/intel_reg.h"
> > +#include "lib/igt_perf.h"
> > +#include "xe_drm.h"
> > +
> > +#include "xe/xe_ioctl.h"
> > +#include "xe/xe_query.h"
> > +#include "xe/xe_spin.h"
> > +#include <string.h>
> Keep includes sorted alphabetically, also please put system includes first,
> then write one newline, then igt includes.
> 
Will make the changes and send the new series.
> > +
> > +#define MAX_INSTANCE 9
> > +
> > +static uint64_t pmu_read(int fd)
> > +{
> > +	uint64_t  data[2];
> > +
> > +	igt_assert_eq(read(fd, data, sizeof(data)), sizeof(data));
> > +
> > +	return data[0];
> > +}
> > +
> > +static int open_pmu(int fd, uint64_t config) {
> > +	int perf_fd;
> > +
> > +	perf_fd = perf_xe_open(fd, config);
> > +	igt_skip_on(perf_fd < 0 && errno == ENODEV);
> > +	igt_assert(perf_fd >= 0);
> > +
> > +	return perf_fd;
> > +}
> > +
> > +static uint64_t engine_group_get_config(int gt, int class) {
> > +	uint64_t config;
> > +
> > +	switch (class) {
> > +	case DRM_XE_ENGINE_CLASS_COPY:
> > +		config = XE_PMU_COPY_GROUP_BUSY(gt);
> > +		break;
> > +	case DRM_XE_ENGINE_CLASS_RENDER:
> > +	case DRM_XE_ENGINE_CLASS_COMPUTE:
> > +		config = XE_PMU_RENDER_GROUP_BUSY(gt);
> > +		break;
> > +	case DRM_XE_ENGINE_CLASS_VIDEO_DECODE:
> > +	case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
> > +		config = XE_PMU_MEDIA_GROUP_BUSY(gt);
> > +		break;
> > +	}
> > +
> > +	return config;
> > +}
> > +
> > +/**
> > + * Test: Basic test for measure the active time when engine of any
> > +class active
> > + *
> > + * SUBTEST: any-engine-group-busy
> > + * Description:
> > + *      Run a test to measure the global activity time by submitting
> > + *      the WL to all existing engines.
> > + * Run type: FULL
> > + * TODO: change ``'Run type' == FULL`` to a better category  */
> > +static void test_any_engine_busyness(int fd, struct
> > +drm_xe_engine_class_instance *eci) {
> > +	uint32_t vm;
> > +	uint64_t addr = 0x1a0000;
> > +	struct drm_xe_sync sync[2] = {
> > +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> > +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> > +	};
> > +	struct drm_xe_exec exec = {
> > +		.num_batch_buffer = 1,
> > +		.num_syncs = 2,
> > +		.syncs = to_user_pointer(sync),
> > +	};
> > +	uint32_t engine;
> > +	uint32_t syncobj;
> > +	size_t bo_size;
> > +	uint32_t bo = 0;
> > +	struct xe_spin *spin;
> > +	uint32_t pmu_fd;
> > +	uint64_t count, idle = 0;
> > +
> > +	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
> > +	bo_size = sizeof(*spin);
> > +	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
> > +			xe_get_default_alignment(fd));
> > +
> > +	bo = xe_bo_create(fd, eci->gt_id, vm, bo_size);
> > +	spin = xe_bo_map(fd, bo, bo_size);
> > +
> > +	engine = xe_engine_create(fd, vm, eci, 0);
> > +	syncobj = syncobj_create(fd, 0);
> > +
> > +	sync[0].handle = syncobj_create(fd, 0);
> > +	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
> > +
> > +	pmu_fd = open_pmu(fd, XE_PMU_ANY_ENGINE_GROUP_BUSY(eci-
> > >gt_id));
> > +
> > +	xe_spin_init(spin, addr, false);
> > +
> > +	sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
> > +	sync[1].flags |= DRM_XE_SYNC_SIGNAL;
> > +	sync[1].handle = syncobj;
> > +
> > +	exec.engine_id = engine;
> > +	exec.address = addr;
> > +	xe_exec(fd, &exec);
> > +
> > +	xe_spin_wait_started(spin);
> > +	usleep(50000);
> > +
> > +	igt_assert(!syncobj_wait(fd, &syncobj, 1, 1, 0, NULL));
> > +	xe_spin_end(spin);
> > +
> > +	igt_assert(syncobj_wait(fd, &syncobj, 1, INT64_MAX, 0, NULL));
> > +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0,
> > +NULL));
> > +
> > +	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
> > +	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
> > +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0,
> > +NULL));
> > +
> > +	syncobj_destroy(fd, sync[0].handle);
> > +	syncobj_destroy(fd, syncobj);
> > +
> > +	count = pmu_read(pmu_fd);
> > +	igt_assert_lt_u64(idle, count);
> > +	igt_debug("Incrementing counter all-busy-group %ld ns\n", count);
> > +
> > +	xe_engine_destroy(fd, engine);
> > +	munmap(spin, bo_size);
> > +	gem_close(fd, bo);
> > +	xe_vm_destroy(fd, vm);
> > +	close(pmu_fd);
> > +}
> > +
> > +/**
> > + * Test: Basic test for measure the active time across engine class
> > + *
> > + * SUBTEST: render-busy
> > + * Description:
> > + *	Run a test to measure the active engine class time by submitting the
> > + *	WL to all instances of a class
> > + * Run type: FULL
> > + * TODO: change ``'Run type' == FULL`` to a better category
> Remove TODO's these are not required now.
> Existing ones are removed by  "tests/xe: remove an useless TODO message"
> > + *
> > + * SUBTEST: compute-busy
> > + * Description: Run copy-group-busy test
> > + * Run type: FULL
> > + * TODO: change ``'Run type' == FULL`` to a better category
> > + *
> > + * SUBTEST: copy-busy
> > + * Description: Run copy-group-busy test
> > + * Run type: FULL
> > + * TODO: change ``'Run type' == FULL`` to a better category
> > + *
> > + * SUBTEST: vcs-busy
> > + * Description: Run copy-group-busy test
> > + * Run type: FULL
> > + * TODO: change ``'Run type' == FULL`` to a better category
> > + *
> > + * SUBTEST: vecs-busy
> > + * Description: Run copy-group-busy test
> > + * Run type: FULL
> > + * TODO: change ``'Run type' == FULL`` to a better category
> > + *
> > + */
> > +
> > +static void test_engine_group_busyness(int fd, int gt, int class,
> > +const char *name) {
> > +	uint32_t vm;
> > +	uint64_t addr = 0x1a0000;
> > +	struct drm_xe_sync sync[2] = {
> > +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> > +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> > +	};
> > +	struct drm_xe_exec exec = {
> > +		.num_batch_buffer = 1,
> > +		.num_syncs = 2,
> > +		.syncs = to_user_pointer(sync),
> > +	};
> > +	uint32_t engines[MAX_INSTANCE];
> > +	uint32_t syncobjs[MAX_INSTANCE];
> > +	int    pmu_fd;
> > +	size_t bo_size;
> > +	uint32_t bo = 0, i = 0;
> > +	struct {
> > +		struct xe_spin spin;
> > +	} *data;
> > +	struct drm_xe_engine_class_instance *hwe;
> > +	struct drm_xe_engine_class_instance eci[MAX_INSTANCE];
> > +	int num_placements = 0;
> > +	uint64_t config, count, idle = 0;
> > +
> > +	config = engine_group_get_config(gt, class);
> > +
> > +	xe_for_each_hw_engine(fd, hwe) {
> > +		if (hwe->engine_class != class || hwe->gt_id != gt)
> > +			continue;
> > +
> > +		eci[num_placements++] = *hwe;
> > +	}
> > +
> > +	if (!num_placements) {
> > +		igt_info("Engine class:%d gt:%d not enabled on this
> > platform\n", class, gt);
> > +		return;
> > +	}
> > +
> > +	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
> > +	bo_size = sizeof(*data) * num_placements;
> > +	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
> > +xe_get_default_alignment(fd));
> > +
> > +	bo = xe_bo_create(fd, gt, vm, bo_size);
> > +	data = xe_bo_map(fd, bo, bo_size);
> > +
> > +	for (i = 0; i < num_placements; i++) {
> > +		struct drm_xe_engine_create create = {
> > +			.vm_id = vm,
> > +			.width = 1,
> > +			.num_placements = num_placements,
> > +			.instances = to_user_pointer(eci),
> > +		};
> > +
> > +		igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_ENGINE_CREATE,
> > +					&create), 0);
> > +		engines[i] = create.engine_id;
> > +		syncobjs[i] = syncobj_create(fd, 0);
> > +	};
> > +
> > +	sync[0].handle = syncobj_create(fd, 0);
> > +	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
> > +
> > +	pmu_fd = open_pmu(fd, config);
> Pls check for engine idleness before submitting the workload.
> 
Will add the idle code checks and send new series.

Thanks,
Venkat.

> Thanks,
> Rahul
> > +
> > +	for (i = 0; i < num_placements; i++) {
> > +		uint64_t spin_offset = (char *)&data[i].spin - (char *)data;
> > +		uint64_t spin_addr = addr + spin_offset;
> > +
> > +		xe_spin_init(&data[i].spin, spin_addr, false);
> > +		sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
> > +		sync[1].flags |= DRM_XE_SYNC_SIGNAL;
> > +		sync[1].handle = syncobjs[i];
> > +
> > +		exec.engine_id = engines[i];
> > +		exec.address = spin_addr;
> > +		xe_exec(fd, &exec);
> > +		xe_spin_wait_started(&data[i].spin);
> > +	}
> > +
> > +	for (i = 0; i < num_placements; i++) {
> > +		xe_spin_end(&data[i].spin);
> > +		igt_assert(syncobj_wait(fd, &syncobjs[i], 1, INT64_MAX, 0,
> > +					NULL));
> > +	}
> > +
> > +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0,
> > +NULL));
> > +
> > +	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
> > +	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
> > +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0,
> > +NULL));
> > +
> > +
> > +	syncobj_destroy(fd, sync[0].handle);
> > +	for (i = 0; i < num_placements; i++) {
> > +		syncobj_destroy(fd, syncobjs[i]);
> > +		xe_engine_destroy(fd, engines[i]);
> > +	}
> > +
> > +	count = pmu_read(pmu_fd);
> > +	igt_assert_lt_u64(idle, count);
> > +	igt_debug("Incrementing counter %s-gt-%d  %ld ns\n", name, gt,
> > +count);
> > +
> > +	munmap(data, bo_size);
> > +	gem_close(fd, bo);
> > +	xe_vm_destroy(fd, vm);
> > +	close(pmu_fd);
> > +}
> > +
> > +igt_main
> > +{
> > +	struct drm_xe_engine_class_instance *hwe;
> > +	const struct section {
> > +		const char *name;
> > +		int class;
> > +	} sections[] = {
> > +		{ "render-busy", DRM_XE_ENGINE_CLASS_RENDER },
> > +		{ "compute-busy", DRM_XE_ENGINE_CLASS_COMPUTE },
> > +		{ "copy-busy", DRM_XE_ENGINE_CLASS_COPY },
> > +		{ "vcs-busy", DRM_XE_ENGINE_CLASS_VIDEO_DECODE },
> > +		{ "vecs-busy", DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE },
> > +		{ NULL },
> > +	};
> > +	int gt;
> > +	int class;
> > +	int fd;
> > +
> > +	igt_fixture {
> > +		fd = drm_open_driver(DRIVER_XE);
> > +		xe_device_get(fd);
> > +	}
> > +
> > +	for (const struct section *s = sections; s->name; s++) {
> > +		igt_subtest_f("%s", s->name)
> > +			xe_for_each_gt(fd, gt)
> > +				xe_for_each_hw_engine_class(class)
> > +					if (class == s->class)
> > +
> > 	test_engine_group_busyness(fd, gt, class, s->name);
> > +	}
> > +
> > +	igt_subtest("any-engine-group-busy")
> > +		xe_for_each_hw_engine(fd, hwe)
> > +			test_any_engine_busyness(fd, hwe);
> > +
> > +	igt_fixture {
> > +		xe_device_put(fd);
> > +		close(fd);
> > +	}
> > +}
> > --
> > 2.25.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
@ 2023-10-06  5:15 priyanka.dandamudi
  2023-10-06  7:30 ` [igt-dev] ✗ Fi.CI.BAT: failure for tests/xe/perf_pmu: Tests for the XE pmu interface (rev3) Patchwork
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: priyanka.dandamudi @ 2023-10-06  5:15 UTC (permalink / raw)
  To: janga.rahul.kumar, igt-dev, priyanka.dandamudi

From: Venkata Ramana Nayana <venkata.ramana.nayana@intel.com>

There are set of engine group busyness counters provided by HW which are
exposed via PMU events. Adding a basic unit tests to read those counters.

v2: Added idle condition checks while reading the counters. (Rahul)

v3: Moved test from tests/xe/ location to tests/intel.
Modified code to work for xe_exec_queue_create xe_spin_init changes.

Cc: Janga Rahul Kumar <janga.rahul.kumar@intel.com>
Signed-off-by: Venkata Ramana Nayana <venkata.ramana.nayana@intel.com>
Signed-off-by: Priyanka Dandamudi <priyanka.dandamudi@intel.com>
---
 include/drm-uapi/xe_drm.h |  22 +++
 lib/igt_perf.c            |  36 +++++
 lib/igt_perf.h            |   5 +
 tests/intel/xe_perf_pmu.c | 331 ++++++++++++++++++++++++++++++++++++++
 tests/meson.build         |   1 +
 5 files changed, 395 insertions(+)
 create mode 100644 tests/intel/xe_perf_pmu.c

diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index 804c02270..425b7d2b8 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -783,6 +783,28 @@ struct drm_xe_exec_queue_create {
 	__u64 reserved[2];
 };
 
+/**
+ * DOC: perf_events exposed by xe through /sys/bus/event_sources/drivers/xe
+ *
+ */
+
+
+/* PMU event config IDs */
+
+/*
+ * Top 4 bits of every counter are GT id.
+ */
+#define __XE_PMU_GT_SHIFT (60)
+
+#define ___XE_PMU_OTHER(gt, x) \
+	(((__u64)(x)) | ((__u64)(gt) << __XE_PMU_GT_SHIFT))
+
+#define XE_PMU_INTERRUPTS(gt)			___XE_PMU_OTHER(gt, 0)
+#define XE_PMU_RENDER_GROUP_BUSY(gt)		___XE_PMU_OTHER(gt, 1)
+#define XE_PMU_COPY_GROUP_BUSY(gt)		___XE_PMU_OTHER(gt, 2)
+#define XE_PMU_MEDIA_GROUP_BUSY(gt)		___XE_PMU_OTHER(gt, 3)
+#define XE_PMU_ANY_ENGINE_GROUP_BUSY(gt)	___XE_PMU_OTHER(gt, 4)
+
 struct drm_xe_exec_queue_get_property {
 	/** @extensions: Pointer to the first extension struct, if any */
 	__u64 extensions;
diff --git a/lib/igt_perf.c b/lib/igt_perf.c
index ffe078adc..3866c6d77 100644
--- a/lib/igt_perf.c
+++ b/lib/igt_perf.c
@@ -69,6 +69,36 @@ const char *i915_perf_device(int i915, char *buf, int buflen)
 	return buf;
 }
 
+const char *xe_perf_device(int xe, char *buf, int buflen)
+{
+	char *s;
+	char pref[] = "xe_";
+	int len = strlen(pref);
+
+
+	if (!buf || buflen < len)
+		return "xe";
+
+	memcpy(buf, pref, len);
+
+	if (!bus_address(xe, buf + len, buflen - len))
+		buf[len - 1] = '\0';
+
+	/* Convert all colons in the address to '_', thanks perf! */
+	for (s = buf; *s; s++)
+		if (*s == ':')
+			*s = '_';
+
+	return buf;
+}
+
+uint64_t xe_perf_type_id(int xe)
+{
+	char buf[80];
+
+	return igt_perf_type_id(xe_perf_device(xe, buf, sizeof(buf)));
+}
+
 uint64_t i915_perf_type_id(int i915)
 {
 	char buf[80];
@@ -147,6 +177,12 @@ int perf_igfx_open_group(uint64_t config, int group)
 			  PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
 }
 
+int perf_xe_open(int xe, uint64_t config)
+{
+	return _perf_open(xe_perf_type_id(xe), config, -1,
+			PERF_FORMAT_TOTAL_TIME_ENABLED);
+}
+
 int perf_i915_open(int i915, uint64_t config)
 {
 	return _perf_open(i915_perf_type_id(i915), config, -1,
diff --git a/lib/igt_perf.h b/lib/igt_perf.h
index 4d86e31ae..3d9ba2917 100644
--- a/lib/igt_perf.h
+++ b/lib/igt_perf.h
@@ -61,10 +61,15 @@ int igt_perf_open_group(uint64_t type, uint64_t config, int group);
 const char *i915_perf_device(int i915, char *buf, int buflen);
 uint64_t i915_perf_type_id(int i915);
 
+const char *xe_perf_device(int xe, char *buf, int buflen);
+uint64_t xe_perf_type_id(int);
+
 int perf_igfx_open(uint64_t config);
 int perf_igfx_open_group(uint64_t config, int group);
 
 int perf_i915_open(int i915, uint64_t config);
 int perf_i915_open_group(int i915, uint64_t config, int group);
 
+int perf_xe_open(int xe, uint64_t config);
+
 #endif /* I915_PERF_H */
diff --git a/tests/intel/xe_perf_pmu.c b/tests/intel/xe_perf_pmu.c
new file mode 100644
index 000000000..dc825f7f8
--- /dev/null
+++ b/tests/intel/xe_perf_pmu.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+/**
+ * TEST: Basic tests for verify pmu perf interface
+ * Category: Hardware building block
+ * Sub-category: pmu interface
+ * Functionality: pmu
+ * Test category: functionality test
+ */
+
+#include <fcntl.h>
+#include <string.h>
+
+#include "igt.h"
+#include "lib/igt_syncobj.h"
+#include "lib/intel_reg.h"
+#include "lib/igt_perf.h"
+#include "xe_drm.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+#include "xe/xe_spin.h"
+
+#define MAX_INSTANCE 9
+
+static uint64_t pmu_read(int fd)
+{
+	uint64_t  data[2];
+
+	igt_assert_eq(read(fd, data, sizeof(data)), sizeof(data));
+
+	return data[0];
+}
+
+static int open_pmu(int fd, uint64_t config)
+{
+	int perf_fd;
+
+	perf_fd = perf_xe_open(fd, config);
+	igt_skip_on(perf_fd < 0 && errno == ENODEV);
+	igt_assert(perf_fd >= 0);
+
+	return perf_fd;
+}
+
+static uint64_t engine_group_get_config(int gt, int class)
+{
+	uint64_t config;
+
+	switch (class) {
+	case DRM_XE_ENGINE_CLASS_COPY:
+		config = XE_PMU_COPY_GROUP_BUSY(gt);
+		break;
+	case DRM_XE_ENGINE_CLASS_RENDER:
+	case DRM_XE_ENGINE_CLASS_COMPUTE:
+		config = XE_PMU_RENDER_GROUP_BUSY(gt);
+		break;
+	case DRM_XE_ENGINE_CLASS_VIDEO_DECODE:
+	case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
+		config = XE_PMU_MEDIA_GROUP_BUSY(gt);
+		break;
+	}
+
+	return config;
+}
+
+/**
+ * Test: Basic test for measure the active time when engine of any class active
+ *
+ * SUBTEST: any-engine-group-busy
+ * Description:
+ *      Run a test to measure the global activity time by submitting
+ *      the WL to all existing engines.
+ * Run type: FULL
+ *
+ */
+static void test_any_engine_busyness(int fd, struct drm_xe_engine_class_instance *eci)
+{
+	uint32_t vm;
+	uint64_t addr = 0x1a0000;
+	struct drm_xe_sync sync[2] = {
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+	};
+	struct drm_xe_exec exec = {
+		.num_batch_buffer = 1,
+		.num_syncs = 2,
+		.syncs = to_user_pointer(sync),
+	};
+	uint32_t exec_queue;
+	uint32_t syncobj;
+	size_t bo_size;
+	uint32_t bo = 0;
+	struct xe_spin *spin;
+	struct xe_spin_opts spin_opts = { .addr = addr, .preempt = false };
+	uint32_t pmu_fd;
+	uint64_t count, idle;
+
+	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
+	bo_size = sizeof(*spin);
+	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
+			xe_get_default_alignment(fd));
+
+	bo = xe_bo_create(fd, eci->gt_id, vm, bo_size);
+	spin = xe_bo_map(fd, bo, bo_size);
+
+	exec_queue = xe_exec_queue_create(fd, vm, eci, 0);
+	syncobj = syncobj_create(fd, 0);
+
+	sync[0].handle = syncobj_create(fd, 0);
+	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
+
+	pmu_fd = open_pmu(fd, XE_PMU_ANY_ENGINE_GROUP_BUSY(eci->gt_id));
+	idle = pmu_read(pmu_fd);
+	igt_assert(!idle);
+
+	xe_spin_init(spin, &spin_opts);
+
+	sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
+	sync[1].flags |= DRM_XE_SYNC_SIGNAL;
+	sync[1].handle = syncobj;
+
+	exec.exec_queue_id = exec_queue;
+	exec.address = addr;
+	xe_exec(fd, &exec);
+
+	xe_spin_wait_started(spin);
+	usleep(50000);
+
+	igt_assert(!syncobj_wait(fd, &syncobj, 1, 1, 0, NULL));
+	xe_spin_end(spin);
+
+	igt_assert(syncobj_wait(fd, &syncobj, 1, INT64_MAX, 0, NULL));
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
+	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+	syncobj_destroy(fd, sync[0].handle);
+	syncobj_destroy(fd, syncobj);
+
+	count = pmu_read(pmu_fd);
+	igt_assert_lt_u64(idle, count);
+	igt_debug("Incrementing counter all-busy-group %ld ns\n", count);
+
+	xe_exec_queue_destroy(fd, exec_queue);
+	munmap(spin, bo_size);
+	gem_close(fd, bo);
+	xe_vm_destroy(fd, vm);
+	close(pmu_fd);
+}
+
+/**
+ * Test: Basic test for measure the active time across engine class
+ *
+ * SUBTEST: render-busy
+ * Description:
+ *	Run a test to measure the active engine class time by submitting the
+ *	WL to all instances of a class
+ * Run type: FULL
+ *
+ * SUBTEST: compute-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ *
+ * SUBTEST: copy-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ *
+ * SUBTEST: vcs-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ *
+ * SUBTEST: vecs-busy
+ * Description: Run copy-group-busy test
+ * Run type: FULL
+ *
+ */
+
+static void test_engine_group_busyness(int fd, int gt, int class, const char *name)
+{
+	uint32_t vm;
+	uint64_t addr = 0x1a0000;
+	struct drm_xe_sync sync[2] = {
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, },
+	};
+	struct drm_xe_exec exec = {
+		.num_batch_buffer = 1,
+		.num_syncs = 2,
+		.syncs = to_user_pointer(sync),
+	};
+	uint32_t exec_queues[MAX_INSTANCE];
+	uint32_t syncobjs[MAX_INSTANCE];
+	int    pmu_fd;
+	size_t bo_size;
+	uint32_t bo = 0, i = 0;
+	struct {
+		struct xe_spin spin;
+	} *data;
+	struct xe_spin_opts spin_opts = { .addr = addr, .preempt = false };
+	struct drm_xe_engine_class_instance *hwe;
+	struct drm_xe_engine_class_instance eci[MAX_INSTANCE];
+	int num_placements = 0;
+	uint64_t config, count, idle;
+
+	config = engine_group_get_config(gt, class);
+
+	xe_for_each_hw_engine(fd, hwe) {
+		if (hwe->engine_class != class || hwe->gt_id != gt)
+			continue;
+
+		eci[num_placements++] = *hwe;
+	}
+
+	igt_skip_on_f(!num_placements, "Engine class:%d gt:%d not enabled on this platform\n",
+		      class, gt);
+
+	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
+	bo_size = sizeof(*data) * num_placements;
+	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd), xe_get_default_alignment(fd));
+
+	bo = xe_bo_create(fd, gt, vm, bo_size);
+	data = xe_bo_map(fd, bo, bo_size);
+
+	for (i = 0; i < num_placements; i++) {
+		struct drm_xe_exec_queue_create create = {
+			.vm_id = vm,
+			.width = 1,
+			.num_placements = num_placements,
+			.instances = to_user_pointer(eci),
+		};
+
+		igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE,
+					&create), 0);
+		exec_queues[i] = create.exec_queue_id;
+		syncobjs[i] = syncobj_create(fd, 0);
+	};
+
+	sync[0].handle = syncobj_create(fd, 0);
+	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
+
+	pmu_fd = open_pmu(fd, config);
+	idle = pmu_read(pmu_fd);
+	igt_assert(!idle);
+
+	for (i = 0; i < num_placements; i++) {
+		spin_opts.addr = addr + (char *)&data[i].spin - (char *)data;
+		xe_spin_init(&data[i].spin, &spin_opts);
+		sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
+		sync[1].flags |= DRM_XE_SYNC_SIGNAL;
+		sync[1].handle = syncobjs[i];
+
+		exec.exec_queue_id = exec_queues[i];
+		exec.address = spin_opts.addr;
+		xe_exec(fd, &exec);
+		xe_spin_wait_started(&data[i].spin);
+	}
+
+	for (i = 0; i < num_placements; i++) {
+		xe_spin_end(&data[i].spin);
+		igt_assert(syncobj_wait(fd, &syncobjs[i], 1, INT64_MAX, 0,
+					NULL));
+	}
+
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
+	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
+	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
+
+
+	syncobj_destroy(fd, sync[0].handle);
+	for (i = 0; i < num_placements; i++) {
+		syncobj_destroy(fd, syncobjs[i]);
+		xe_exec_queue_destroy(fd, exec_queues[i]);
+	}
+
+	count = pmu_read(pmu_fd);
+	igt_assert_lt_u64(idle, count);
+	igt_debug("Incrementing counter %s-gt-%d  %ld ns\n", name, gt, count);
+
+	munmap(data, bo_size);
+	gem_close(fd, bo);
+	xe_vm_destroy(fd, vm);
+	close(pmu_fd);
+}
+
+igt_main
+{
+	struct drm_xe_engine_class_instance *hwe;
+	const struct section {
+		const char *name;
+		int class;
+	} sections[] = {
+		{ "render-busy", DRM_XE_ENGINE_CLASS_RENDER },
+		{ "compute-busy", DRM_XE_ENGINE_CLASS_COMPUTE },
+		{ "copy-busy", DRM_XE_ENGINE_CLASS_COPY },
+		{ "vcs-busy", DRM_XE_ENGINE_CLASS_VIDEO_DECODE },
+		{ "vecs-busy", DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE },
+		{ NULL },
+	};
+	int gt;
+	int class;
+	int fd;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_XE);
+		xe_device_get(fd);
+	}
+
+	for (const struct section *s = sections; s->name; s++) {
+		igt_subtest_f("%s", s->name)
+			xe_for_each_gt(fd, gt)
+				xe_for_each_hw_engine_class(class)
+					if (class == s->class)
+						test_engine_group_busyness(fd, gt, class, s->name);
+	}
+
+	igt_subtest("any-engine-group-busy")
+		xe_for_each_hw_engine(fd, hwe)
+			test_any_engine_busyness(fd, hwe);
+
+	igt_fixture {
+		xe_device_put(fd);
+		close(fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 974cb433b..51773e9fa 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -299,6 +299,7 @@ intel_xe_progs = [
 	'xe_pm',
 	'xe_pm_residency',
 	'xe_prime_self_import',
+	'xe_perf_pmu',
 	'xe_query',
 	'xe_sysfs_tile',
 	'xe_uevent',
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [igt-dev] ✗ Fi.CI.BAT: failure for tests/xe/perf_pmu: Tests for the XE pmu interface (rev3)
  2023-10-06  5:15 [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface priyanka.dandamudi
@ 2023-10-06  7:30 ` Patchwork
  2023-10-06  7:31 ` [igt-dev] ✓ CI.xeBAT: success " Patchwork
  2023-10-06  9:31 ` [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface Kumar, Janga Rahul
  2 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2023-10-06  7:30 UTC (permalink / raw)
  To: Venkata Ramana Nayana; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 10860 bytes --]

== Series Details ==

Series: tests/xe/perf_pmu: Tests for the XE pmu interface (rev3)
URL   : https://patchwork.freedesktop.org/series/119936/
State : failure

== Summary ==

CI Bug Log - changes from IGT_7518 -> IGTPW_9936
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_9936 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_9936, please notify your bug team (lgci.bug.filing@intel.com) to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/index.html

Participating hosts (39 -> 39)
------------------------------

  Additional (1): bat-dg2-9 
  Missing    (1): fi-snb-2520m 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_9936:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_exec_suspend@basic-s3@smem:
    - fi-skl-guc:         [PASS][1] -> [ABORT][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7518/fi-skl-guc/igt@gem_exec_suspend@basic-s3@smem.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/fi-skl-guc/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@kms_pipe_crc_basic@suspend-read-crc@pipe-c-hdmi-a-3:
    - bat-dg2-11:         [PASS][3] -> [INCOMPLETE][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7518/bat-dg2-11/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-c-hdmi-a-3.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-11/igt@kms_pipe_crc_basic@suspend-read-crc@pipe-c-hdmi-a-3.html

  
Known issues
------------

  Here are the changes found in IGTPW_9936 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_lmem_swapping@random-engines:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][5] ([fdo#109271]) +18 other tests skip
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/fi-bsw-n3050/igt@gem_lmem_swapping@random-engines.html

  * igt@gem_mmap@basic:
    - bat-dg2-9:          NOTRUN -> [SKIP][6] ([i915#4083])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@gem_mmap@basic.html

  * igt@gem_mmap_gtt@basic:
    - bat-dg2-9:          NOTRUN -> [SKIP][7] ([i915#4077]) +2 other tests skip
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@gem_mmap_gtt@basic.html

  * igt@gem_render_tiled_blits@basic:
    - bat-dg2-9:          NOTRUN -> [SKIP][8] ([i915#4079]) +1 other test skip
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@gem_render_tiled_blits@basic.html

  * igt@i915_pm_rps@basic-api:
    - bat-dg2-9:          NOTRUN -> [SKIP][9] ([i915#6621])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@i915_pm_rps@basic-api.html

  * igt@i915_selftest@live@requests:
    - bat-mtlp-8:         [PASS][10] -> [ABORT][11] ([i915#9414])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7518/bat-mtlp-8/igt@i915_selftest@live@requests.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-mtlp-8/igt@i915_selftest@live@requests.html

  * igt@kms_addfb_basic@addfb25-y-tiled-small-legacy:
    - bat-dg2-9:          NOTRUN -> [SKIP][12] ([i915#5190])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_addfb_basic@addfb25-y-tiled-small-legacy.html

  * igt@kms_addfb_basic@basic-y-tiled-legacy:
    - bat-dg2-9:          NOTRUN -> [SKIP][13] ([i915#4215] / [i915#5190])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_addfb_basic@basic-y-tiled-legacy.html

  * igt@kms_addfb_basic@framebuffer-vs-set-tiling:
    - bat-dg2-9:          NOTRUN -> [SKIP][14] ([i915#4212]) +6 other tests skip
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_addfb_basic@framebuffer-vs-set-tiling.html

  * igt@kms_addfb_basic@tile-pitch-mismatch:
    - bat-dg2-9:          NOTRUN -> [SKIP][15] ([i915#4212] / [i915#5608])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_addfb_basic@tile-pitch-mismatch.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - bat-dg2-9:          NOTRUN -> [SKIP][16] ([i915#4103] / [i915#4213] / [i915#5608]) +1 other test skip
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_force_connector_basic@force-load-detect:
    - bat-dg2-9:          NOTRUN -> [SKIP][17] ([fdo#109285])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_force_connector_basic@prune-stale-modes:
    - bat-dg2-9:          NOTRUN -> [SKIP][18] ([i915#5274])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_force_connector_basic@prune-stale-modes.html

  * igt@kms_hdmi_inject@inject-audio:
    - fi-bsw-n3050:       NOTRUN -> [FAIL][19] ([IGT#3])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/fi-bsw-n3050/igt@kms_hdmi_inject@inject-audio.html

  * igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence:
    - bat-adlp-9:         NOTRUN -> [SKIP][20] ([i915#3546]) +2 other tests skip
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-adlp-9/igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence.html
    - bat-dg2-11:         NOTRUN -> [SKIP][21] ([i915#1845]) +3 other tests skip
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-11/igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence.html

  * igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-c-dp-5:
    - bat-adlp-11:        [PASS][22] -> [ABORT][23] ([i915#8668] / [i915#9451])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7518/bat-adlp-11/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-c-dp-5.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-adlp-11/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-c-dp-5.html

  * igt@kms_psr@sprite_plane_onoff:
    - bat-dg2-9:          NOTRUN -> [SKIP][24] ([i915#1072]) +3 other tests skip
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_psr@sprite_plane_onoff.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - bat-dg2-9:          NOTRUN -> [SKIP][25] ([i915#3555])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@kms_setmode@basic-clone-single-crtc.html

  * igt@prime_vgem@basic-fence-flip:
    - bat-dg2-9:          NOTRUN -> [SKIP][26] ([i915#3708])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@prime_vgem@basic-fence-flip.html

  * igt@prime_vgem@basic-fence-mmap:
    - bat-dg2-9:          NOTRUN -> [SKIP][27] ([i915#3708] / [i915#4077]) +1 other test skip
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@prime_vgem@basic-fence-mmap.html

  * igt@prime_vgem@basic-write:
    - bat-dg2-9:          NOTRUN -> [SKIP][28] ([i915#3291] / [i915#3708]) +2 other tests skip
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-dg2-9/igt@prime_vgem@basic-write.html

  
#### Possible fixes ####

  * igt@debugfs_test@read_all_entries:
    - bat-adlp-11:        [DMESG-WARN][29] ([i915#6868]) -> [PASS][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7518/bat-adlp-11/igt@debugfs_test@read_all_entries.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-adlp-11/igt@debugfs_test@read_all_entries.html

  * igt@i915_pm_rpm@module-reload:
    - bat-atsm-1:         [SKIP][31] -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7518/bat-atsm-1/igt@i915_pm_rpm@module-reload.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-atsm-1/igt@i915_pm_rpm@module-reload.html

  * igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-dp-5:
    - bat-adlp-11:        [ABORT][33] ([i915#8668]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_7518/bat-adlp-11/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-dp-5.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/bat-adlp-11/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-dp-5.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [IGT#3]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/3
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1845]: https://gitlab.freedesktop.org/drm/intel/issues/1845
  [i915#3291]: https://gitlab.freedesktop.org/drm/intel/issues/3291
  [i915#3546]: https://gitlab.freedesktop.org/drm/intel/issues/3546
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
  [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
  [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
  [i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
  [i915#5274]: https://gitlab.freedesktop.org/drm/intel/issues/5274
  [i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
  [i915#5608]: https://gitlab.freedesktop.org/drm/intel/issues/5608
  [i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
  [i915#6868]: https://gitlab.freedesktop.org/drm/intel/issues/6868
  [i915#8668]: https://gitlab.freedesktop.org/drm/intel/issues/8668
  [i915#9414]: https://gitlab.freedesktop.org/drm/intel/issues/9414
  [i915#9451]: https://gitlab.freedesktop.org/drm/intel/issues/9451


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_7518 -> IGTPW_9936

  CI-20190529: 20190529
  CI_DRM_13720: 299f698cf70fcb526dbd00faeb85b32ecce97334 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_9936: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/index.html
  IGT_7518: 2d4a57e28db0c2ccbf8b2e763074c9aa74a1ae52 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git


Testlist changes
----------------

+igt@xe_perf_pmu@any-engine-group-busy
+igt@xe_perf_pmu@compute-busy
+igt@xe_perf_pmu@copy-busy
+igt@xe_perf_pmu@render-busy
+igt@xe_perf_pmu@vcs-busy
+igt@xe_perf_pmu@vecs-busy

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/index.html

[-- Attachment #2: Type: text/html, Size: 12597 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [igt-dev] ✓ CI.xeBAT: success for tests/xe/perf_pmu: Tests for the XE pmu interface (rev3)
  2023-10-06  5:15 [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface priyanka.dandamudi
  2023-10-06  7:30 ` [igt-dev] ✗ Fi.CI.BAT: failure for tests/xe/perf_pmu: Tests for the XE pmu interface (rev3) Patchwork
@ 2023-10-06  7:31 ` Patchwork
  2023-10-06  9:31 ` [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface Kumar, Janga Rahul
  2 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2023-10-06  7:31 UTC (permalink / raw)
  To: Venkata Ramana Nayana; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 4025 bytes --]

== Series Details ==

Series: tests/xe/perf_pmu: Tests for the XE pmu interface (rev3)
URL   : https://patchwork.freedesktop.org/series/119936/
State : success

== Summary ==

CI Bug Log - changes from XEIGT_7518_BAT -> XEIGTPW_9936_BAT
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Participating hosts (4 -> 4)
------------------------------

  No changes in participating hosts

Known issues
------------

  Here are the changes found in XEIGTPW_9936_BAT that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_pipe_crc_basic@hang-read-crc:
    - bat-dg2-oem2:       [PASS][1] -> [TIMEOUT][2] ([Intel XE#430]) +1 other test timeout
   [1]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7518/bat-dg2-oem2/igt@kms_pipe_crc_basic@hang-read-crc.html
   [2]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9936/bat-dg2-oem2/igt@kms_pipe_crc_basic@hang-read-crc.html

  * igt@kms_pipe_crc_basic@nonblocking-crc:
    - bat-dg2-oem2:       [PASS][3] -> [INCOMPLETE][4] ([Intel XE#545]) +1 other test incomplete
   [3]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7518/bat-dg2-oem2/igt@kms_pipe_crc_basic@nonblocking-crc.html
   [4]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9936/bat-dg2-oem2/igt@kms_pipe_crc_basic@nonblocking-crc.html

  
#### Possible fixes ####

  * igt@kms_cursor_legacy@basic-flip-after-cursor-legacy:
    - bat-dg2-oem2:       [FAIL][5] ([Intel XE#773]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7518/bat-dg2-oem2/igt@kms_cursor_legacy@basic-flip-after-cursor-legacy.html
   [6]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9936/bat-dg2-oem2/igt@kms_cursor_legacy@basic-flip-after-cursor-legacy.html

  * {igt@xe_create@create-execqueues-noleak}:
    - bat-adlp-7:         [FAIL][7] ([Intel XE#524]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7518/bat-adlp-7/igt@xe_create@create-execqueues-noleak.html
   [8]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9936/bat-adlp-7/igt@xe_create@create-execqueues-noleak.html

  
#### Warnings ####

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12:
    - bat-dg2-oem2:       [FAIL][9] ([Intel XE#400]) -> [TIMEOUT][10] ([Intel XE#430] / [Intel XE#530])
   [9]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7518/bat-dg2-oem2/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12.html
   [10]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9936/bat-dg2-oem2/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12@pipe-b-dp-3:
    - bat-dg2-oem2:       [FAIL][11] ([Intel XE#400]) -> [TIMEOUT][12] ([Intel XE#530])
   [11]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7518/bat-dg2-oem2/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12@pipe-b-dp-3.html
   [12]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9936/bat-dg2-oem2/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-nv12@pipe-b-dp-3.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [Intel XE#400]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/400
  [Intel XE#430]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/430
  [Intel XE#524]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/524
  [Intel XE#530]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/530
  [Intel XE#545]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/545
  [Intel XE#773]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/773


Build changes
-------------

  * IGT: IGT_7518 -> IGTPW_9936

  IGTPW_9936: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9936/index.html
  IGT_7518: 2d4a57e28db0c2ccbf8b2e763074c9aa74a1ae52 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  xe-417-b3daf7f07d6accbe43feafcadeb0b0498063761e: b3daf7f07d6accbe43feafcadeb0b0498063761e

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9936/index.html

[-- Attachment #2: Type: text/html, Size: 4946 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
  2023-10-06  5:15 [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface priyanka.dandamudi
  2023-10-06  7:30 ` [igt-dev] ✗ Fi.CI.BAT: failure for tests/xe/perf_pmu: Tests for the XE pmu interface (rev3) Patchwork
  2023-10-06  7:31 ` [igt-dev] ✓ CI.xeBAT: success " Patchwork
@ 2023-10-06  9:31 ` Kumar, Janga Rahul
  2023-10-07  1:15   ` Dixit, Ashutosh
  2 siblings, 1 reply; 8+ messages in thread
From: Kumar, Janga Rahul @ 2023-10-06  9:31 UTC (permalink / raw)
  To: Dandamudi, Priyanka, igt-dev@lists.freedesktop.org



> -----Original Message-----
> From: Dandamudi, Priyanka <priyanka.dandamudi@intel.com>
> Sent: Friday, October 6, 2023 10:45 AM
> To: Kumar, Janga Rahul <janga.rahul.kumar@intel.com>; igt-
> dev@lists.freedesktop.org; Dandamudi, Priyanka
> <priyanka.dandamudi@intel.com>
> Subject: [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
> 
> From: Venkata Ramana Nayana <venkata.ramana.nayana@intel.com>
> 
> There are set of engine group busyness counters provided by HW which are
> exposed via PMU events. Adding a basic unit tests to read those counters.
> 
> v2: Added idle condition checks while reading the counters. (Rahul)
> 
> v3: Moved test from tests/xe/ location to tests/intel.
> Modified code to work for xe_exec_queue_create xe_spin_init changes.
> 
> Cc: Janga Rahul Kumar <janga.rahul.kumar@intel.com>
> Signed-off-by: Venkata Ramana Nayana
> <venkata.ramana.nayana@intel.com>
> Signed-off-by: Priyanka Dandamudi <priyanka.dandamudi@intel.com>

Reviewed-by: Janga Rahul Kumar<janga.rahul.kumar@intel.com>
 

> ---
>  include/drm-uapi/xe_drm.h |  22 +++
>  lib/igt_perf.c            |  36 +++++
>  lib/igt_perf.h            |   5 +
>  tests/intel/xe_perf_pmu.c | 331
> ++++++++++++++++++++++++++++++++++++++
>  tests/meson.build         |   1 +
>  5 files changed, 395 insertions(+)
>  create mode 100644 tests/intel/xe_perf_pmu.c
> 
> diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h index
> 804c02270..425b7d2b8 100644
> --- a/include/drm-uapi/xe_drm.h
> +++ b/include/drm-uapi/xe_drm.h
> @@ -783,6 +783,28 @@ struct drm_xe_exec_queue_create {
>  	__u64 reserved[2];
>  };
> 
> +/**
> + * DOC: perf_events exposed by xe through
> +/sys/bus/event_sources/drivers/xe
> + *
> + */
> +
> +
> +/* PMU event config IDs */
> +
> +/*
> + * Top 4 bits of every counter are GT id.
> + */
> +#define __XE_PMU_GT_SHIFT (60)
> +
> +#define ___XE_PMU_OTHER(gt, x) \
> +	(((__u64)(x)) | ((__u64)(gt) << __XE_PMU_GT_SHIFT))
> +
> +#define XE_PMU_INTERRUPTS(gt)
> 	___XE_PMU_OTHER(gt, 0)
> +#define XE_PMU_RENDER_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 1)
> +#define XE_PMU_COPY_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 2)
> +#define XE_PMU_MEDIA_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 3)
> +#define XE_PMU_ANY_ENGINE_GROUP_BUSY(gt)
> 	___XE_PMU_OTHER(gt, 4)
> +
>  struct drm_xe_exec_queue_get_property {
>  	/** @extensions: Pointer to the first extension struct, if any */
>  	__u64 extensions;
> diff --git a/lib/igt_perf.c b/lib/igt_perf.c index ffe078adc..3866c6d77 100644
> --- a/lib/igt_perf.c
> +++ b/lib/igt_perf.c
> @@ -69,6 +69,36 @@ const char *i915_perf_device(int i915, char *buf, int
> buflen)
>  	return buf;
>  }
> 
> +const char *xe_perf_device(int xe, char *buf, int buflen) {
> +	char *s;
> +	char pref[] = "xe_";
> +	int len = strlen(pref);
> +
> +
> +	if (!buf || buflen < len)
> +		return "xe";
> +
> +	memcpy(buf, pref, len);
> +
> +	if (!bus_address(xe, buf + len, buflen - len))
> +		buf[len - 1] = '\0';
> +
> +	/* Convert all colons in the address to '_', thanks perf! */
> +	for (s = buf; *s; s++)
> +		if (*s == ':')
> +			*s = '_';
> +
> +	return buf;
> +}
> +
> +uint64_t xe_perf_type_id(int xe)
> +{
> +	char buf[80];
> +
> +	return igt_perf_type_id(xe_perf_device(xe, buf, sizeof(buf))); }
> +
>  uint64_t i915_perf_type_id(int i915)
>  {
>  	char buf[80];
> @@ -147,6 +177,12 @@ int perf_igfx_open_group(uint64_t config, int group)
>  			  PERF_FORMAT_TOTAL_TIME_ENABLED |
> PERF_FORMAT_GROUP);  }
> 
> +int perf_xe_open(int xe, uint64_t config) {
> +	return _perf_open(xe_perf_type_id(xe), config, -1,
> +			PERF_FORMAT_TOTAL_TIME_ENABLED);
> +}
> +
>  int perf_i915_open(int i915, uint64_t config)  {
>  	return _perf_open(i915_perf_type_id(i915), config, -1, diff --git
> a/lib/igt_perf.h b/lib/igt_perf.h index 4d86e31ae..3d9ba2917 100644
> --- a/lib/igt_perf.h
> +++ b/lib/igt_perf.h
> @@ -61,10 +61,15 @@ int igt_perf_open_group(uint64_t type, uint64_t
> config, int group);  const char *i915_perf_device(int i915, char *buf, int
> buflen);  uint64_t i915_perf_type_id(int i915);
> 
> +const char *xe_perf_device(int xe, char *buf, int buflen); uint64_t
> +xe_perf_type_id(int);
> +
>  int perf_igfx_open(uint64_t config);
>  int perf_igfx_open_group(uint64_t config, int group);
> 
>  int perf_i915_open(int i915, uint64_t config);  int perf_i915_open_group(int
> i915, uint64_t config, int group);
> 
> +int perf_xe_open(int xe, uint64_t config);
> +
>  #endif /* I915_PERF_H */
> diff --git a/tests/intel/xe_perf_pmu.c b/tests/intel/xe_perf_pmu.c new file
> mode 100644 index 000000000..dc825f7f8
> --- /dev/null
> +++ b/tests/intel/xe_perf_pmu.c
> @@ -0,0 +1,331 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +/**
> + * TEST: Basic tests for verify pmu perf interface
> + * Category: Hardware building block
> + * Sub-category: pmu interface
> + * Functionality: pmu
> + * Test category: functionality test
> + */
> +
> +#include <fcntl.h>
> +#include <string.h>
> +
> +#include "igt.h"
> +#include "lib/igt_syncobj.h"
> +#include "lib/intel_reg.h"
> +#include "lib/igt_perf.h"
> +#include "xe_drm.h"
> +#include "xe/xe_ioctl.h"
> +#include "xe/xe_query.h"
> +#include "xe/xe_spin.h"
> +
> +#define MAX_INSTANCE 9
> +
> +static uint64_t pmu_read(int fd)
> +{
> +	uint64_t  data[2];
> +
> +	igt_assert_eq(read(fd, data, sizeof(data)), sizeof(data));
> +
> +	return data[0];
> +}
> +
> +static int open_pmu(int fd, uint64_t config) {
> +	int perf_fd;
> +
> +	perf_fd = perf_xe_open(fd, config);
> +	igt_skip_on(perf_fd < 0 && errno == ENODEV);
> +	igt_assert(perf_fd >= 0);
> +
> +	return perf_fd;
> +}
> +
> +static uint64_t engine_group_get_config(int gt, int class) {
> +	uint64_t config;
> +
> +	switch (class) {
> +	case DRM_XE_ENGINE_CLASS_COPY:
> +		config = XE_PMU_COPY_GROUP_BUSY(gt);
> +		break;
> +	case DRM_XE_ENGINE_CLASS_RENDER:
> +	case DRM_XE_ENGINE_CLASS_COMPUTE:
> +		config = XE_PMU_RENDER_GROUP_BUSY(gt);
> +		break;
> +	case DRM_XE_ENGINE_CLASS_VIDEO_DECODE:
> +	case DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE:
> +		config = XE_PMU_MEDIA_GROUP_BUSY(gt);
> +		break;
> +	}
> +
> +	return config;
> +}
> +
> +/**
> + * Test: Basic test for measure the active time when engine of any
> +class active
> + *
> + * SUBTEST: any-engine-group-busy
> + * Description:
> + *      Run a test to measure the global activity time by submitting
> + *      the WL to all existing engines.
> + * Run type: FULL
> + *
> + */
> +static void test_any_engine_busyness(int fd, struct
> +drm_xe_engine_class_instance *eci) {
> +	uint32_t vm;
> +	uint64_t addr = 0x1a0000;
> +	struct drm_xe_sync sync[2] = {
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> +	};
> +	struct drm_xe_exec exec = {
> +		.num_batch_buffer = 1,
> +		.num_syncs = 2,
> +		.syncs = to_user_pointer(sync),
> +	};
> +	uint32_t exec_queue;
> +	uint32_t syncobj;
> +	size_t bo_size;
> +	uint32_t bo = 0;
> +	struct xe_spin *spin;
> +	struct xe_spin_opts spin_opts = { .addr = addr, .preempt = false };
> +	uint32_t pmu_fd;
> +	uint64_t count, idle;
> +
> +	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
> +	bo_size = sizeof(*spin);
> +	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
> +			xe_get_default_alignment(fd));
> +
> +	bo = xe_bo_create(fd, eci->gt_id, vm, bo_size);
> +	spin = xe_bo_map(fd, bo, bo_size);
> +
> +	exec_queue = xe_exec_queue_create(fd, vm, eci, 0);
> +	syncobj = syncobj_create(fd, 0);
> +
> +	sync[0].handle = syncobj_create(fd, 0);
> +	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
> +
> +	pmu_fd = open_pmu(fd, XE_PMU_ANY_ENGINE_GROUP_BUSY(eci-
> >gt_id));
> +	idle = pmu_read(pmu_fd);
> +	igt_assert(!idle);
> +
> +	xe_spin_init(spin, &spin_opts);
> +
> +	sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
> +	sync[1].flags |= DRM_XE_SYNC_SIGNAL;
> +	sync[1].handle = syncobj;
> +
> +	exec.exec_queue_id = exec_queue;
> +	exec.address = addr;
> +	xe_exec(fd, &exec);
> +
> +	xe_spin_wait_started(spin);
> +	usleep(50000);
> +
> +	igt_assert(!syncobj_wait(fd, &syncobj, 1, 1, 0, NULL));
> +	xe_spin_end(spin);
> +
> +	igt_assert(syncobj_wait(fd, &syncobj, 1, INT64_MAX, 0, NULL));
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
> +	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +	syncobj_destroy(fd, sync[0].handle);
> +	syncobj_destroy(fd, syncobj);
> +
> +	count = pmu_read(pmu_fd);
> +	igt_assert_lt_u64(idle, count);
> +	igt_debug("Incrementing counter all-busy-group %ld ns\n", count);
> +
> +	xe_exec_queue_destroy(fd, exec_queue);
> +	munmap(spin, bo_size);
> +	gem_close(fd, bo);
> +	xe_vm_destroy(fd, vm);
> +	close(pmu_fd);
> +}
> +
> +/**
> + * Test: Basic test for measure the active time across engine class
> + *
> + * SUBTEST: render-busy
> + * Description:
> + *	Run a test to measure the active engine class time by submitting the
> + *	WL to all instances of a class
> + * Run type: FULL
> + *
> + * SUBTEST: compute-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + *
> + * SUBTEST: copy-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + *
> + * SUBTEST: vcs-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + *
> + * SUBTEST: vecs-busy
> + * Description: Run copy-group-busy test
> + * Run type: FULL
> + *
> + */
> +
> +static void test_engine_group_busyness(int fd, int gt, int class, const
> +char *name) {
> +	uint32_t vm;
> +	uint64_t addr = 0x1a0000;
> +	struct drm_xe_sync sync[2] = {
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> +		{ .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL,
> },
> +	};
> +	struct drm_xe_exec exec = {
> +		.num_batch_buffer = 1,
> +		.num_syncs = 2,
> +		.syncs = to_user_pointer(sync),
> +	};
> +	uint32_t exec_queues[MAX_INSTANCE];
> +	uint32_t syncobjs[MAX_INSTANCE];
> +	int    pmu_fd;
> +	size_t bo_size;
> +	uint32_t bo = 0, i = 0;
> +	struct {
> +		struct xe_spin spin;
> +	} *data;
> +	struct xe_spin_opts spin_opts = { .addr = addr, .preempt = false };
> +	struct drm_xe_engine_class_instance *hwe;
> +	struct drm_xe_engine_class_instance eci[MAX_INSTANCE];
> +	int num_placements = 0;
> +	uint64_t config, count, idle;
> +
> +	config = engine_group_get_config(gt, class);
> +
> +	xe_for_each_hw_engine(fd, hwe) {
> +		if (hwe->engine_class != class || hwe->gt_id != gt)
> +			continue;
> +
> +		eci[num_placements++] = *hwe;
> +	}
> +
> +	igt_skip_on_f(!num_placements, "Engine class:%d gt:%d not enabled
> on this platform\n",
> +		      class, gt);
> +
> +	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
> +	bo_size = sizeof(*data) * num_placements;
> +	bo_size = ALIGN(bo_size + xe_cs_prefetch_size(fd),
> +xe_get_default_alignment(fd));
> +
> +	bo = xe_bo_create(fd, gt, vm, bo_size);
> +	data = xe_bo_map(fd, bo, bo_size);
> +
> +	for (i = 0; i < num_placements; i++) {
> +		struct drm_xe_exec_queue_create create = {
> +			.vm_id = vm,
> +			.width = 1,
> +			.num_placements = num_placements,
> +			.instances = to_user_pointer(eci),
> +		};
> +
> +		igt_assert_eq(igt_ioctl(fd,
> DRM_IOCTL_XE_EXEC_QUEUE_CREATE,
> +					&create), 0);
> +		exec_queues[i] = create.exec_queue_id;
> +		syncobjs[i] = syncobj_create(fd, 0);
> +	};
> +
> +	sync[0].handle = syncobj_create(fd, 0);
> +	xe_vm_bind_async(fd, vm, 0, bo, 0, addr, bo_size, sync, 1);
> +
> +	pmu_fd = open_pmu(fd, config);
> +	idle = pmu_read(pmu_fd);
> +	igt_assert(!idle);
> +
> +	for (i = 0; i < num_placements; i++) {
> +		spin_opts.addr = addr + (char *)&data[i].spin - (char *)data;
> +		xe_spin_init(&data[i].spin, &spin_opts);
> +		sync[0].flags &= ~DRM_XE_SYNC_SIGNAL;
> +		sync[1].flags |= DRM_XE_SYNC_SIGNAL;
> +		sync[1].handle = syncobjs[i];
> +
> +		exec.exec_queue_id = exec_queues[i];
> +		exec.address = spin_opts.addr;
> +		xe_exec(fd, &exec);
> +		xe_spin_wait_started(&data[i].spin);
> +	}
> +
> +	for (i = 0; i < num_placements; i++) {
> +		xe_spin_end(&data[i].spin);
> +		igt_assert(syncobj_wait(fd, &syncobjs[i], 1, INT64_MAX, 0,
> +					NULL));
> +	}
> +
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +	sync[0].flags |= DRM_XE_SYNC_SIGNAL;
> +	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, sync, 1);
> +	igt_assert(syncobj_wait(fd, &sync[0].handle, 1, INT64_MAX, 0, NULL));
> +
> +
> +	syncobj_destroy(fd, sync[0].handle);
> +	for (i = 0; i < num_placements; i++) {
> +		syncobj_destroy(fd, syncobjs[i]);
> +		xe_exec_queue_destroy(fd, exec_queues[i]);
> +	}
> +
> +	count = pmu_read(pmu_fd);
> +	igt_assert_lt_u64(idle, count);
> +	igt_debug("Incrementing counter %s-gt-%d  %ld ns\n", name, gt,
> count);
> +
> +	munmap(data, bo_size);
> +	gem_close(fd, bo);
> +	xe_vm_destroy(fd, vm);
> +	close(pmu_fd);
> +}
> +
> +igt_main
> +{
> +	struct drm_xe_engine_class_instance *hwe;
> +	const struct section {
> +		const char *name;
> +		int class;
> +	} sections[] = {
> +		{ "render-busy", DRM_XE_ENGINE_CLASS_RENDER },
> +		{ "compute-busy", DRM_XE_ENGINE_CLASS_COMPUTE },
> +		{ "copy-busy", DRM_XE_ENGINE_CLASS_COPY },
> +		{ "vcs-busy", DRM_XE_ENGINE_CLASS_VIDEO_DECODE },
> +		{ "vecs-busy", DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE },
> +		{ NULL },
> +	};
> +	int gt;
> +	int class;
> +	int fd;
> +
> +	igt_fixture {
> +		fd = drm_open_driver(DRIVER_XE);
> +		xe_device_get(fd);
> +	}
> +
> +	for (const struct section *s = sections; s->name; s++) {
> +		igt_subtest_f("%s", s->name)
> +			xe_for_each_gt(fd, gt)
> +				xe_for_each_hw_engine_class(class)
> +					if (class == s->class)
> +
> 	test_engine_group_busyness(fd, gt, class, s->name);
> +	}
> +
> +	igt_subtest("any-engine-group-busy")
> +		xe_for_each_hw_engine(fd, hwe)
> +			test_any_engine_busyness(fd, hwe);
> +
> +	igt_fixture {
> +		xe_device_put(fd);
> +		close(fd);
> +	}
> +}
> diff --git a/tests/meson.build b/tests/meson.build index
> 974cb433b..51773e9fa 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -299,6 +299,7 @@ intel_xe_progs = [
>  	'xe_pm',
>  	'xe_pm_residency',
>  	'xe_prime_self_import',
> +	'xe_perf_pmu',
>  	'xe_query',
>  	'xe_sysfs_tile',
>  	'xe_uevent',
> --
> 2.25.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
  2023-10-06  9:31 ` [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface Kumar, Janga Rahul
@ 2023-10-07  1:15   ` Dixit, Ashutosh
  0 siblings, 0 replies; 8+ messages in thread
From: Dixit, Ashutosh @ 2023-10-07  1:15 UTC (permalink / raw)
  To: Kumar, Janga Rahul; +Cc: igt-dev@lists.freedesktop.org, venkata.ramana.nayana

On Fri, 06 Oct 2023 02:31:19 -0700, Kumar, Janga Rahul wrote:
>

Hi Priyanka,

> > From: Dandamudi, Priyanka <priyanka.dandamudi@intel.com>
> > Sent: Friday, October 6, 2023 10:45 AM
> > To: Kumar, Janga Rahul <janga.rahul.kumar@intel.com>; igt-
> > dev@lists.freedesktop.org; Dandamudi, Priyanka
> > <priyanka.dandamudi@intel.com>
> > Subject: [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface
> >
> > From: Venkata Ramana Nayana <venkata.ramana.nayana@intel.com>
> >
> > There are set of engine group busyness counters provided by HW which are
> > exposed via PMU events. Adding a basic unit tests to read those counters.
> >
> > v2: Added idle condition checks while reading the counters. (Rahul)
> >
> > v3: Moved test from tests/xe/ location to tests/intel.
> > Modified code to work for xe_exec_queue_create xe_spin_init changes.
> >
> > Cc: Janga Rahul Kumar <janga.rahul.kumar@intel.com>
> > Signed-off-by: Venkata Ramana Nayana
> > <venkata.ramana.nayana@intel.com>
> > Signed-off-by: Priyanka Dandamudi <priyanka.dandamudi@intel.com>
>
> Reviewed-by: Janga Rahul Kumar<janga.rahul.kumar@intel.com>

OK good that the original patch is reverted (though it should not have been
merged in the first place) so at least it fixed part the
drm_xe_exec_queue_get_property.

However this patch is still incorrect because you should do a 'make
headers_install' from the latest drm-xe-next kernel branch and then send
/that/ patch.

Ashutosh

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-10-07  1:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-06  5:15 [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface priyanka.dandamudi
2023-10-06  7:30 ` [igt-dev] ✗ Fi.CI.BAT: failure for tests/xe/perf_pmu: Tests for the XE pmu interface (rev3) Patchwork
2023-10-06  7:31 ` [igt-dev] ✓ CI.xeBAT: success " Patchwork
2023-10-06  9:31 ` [igt-dev] [PATCH] tests/xe/perf_pmu: Tests for the XE pmu interface Kumar, Janga Rahul
2023-10-07  1:15   ` Dixit, Ashutosh
  -- strict thread matches above, loose matches on Subject: below --
2023-06-27 16:31 Venkata Ramana Nayana
2023-06-28 12:05 ` Kumar, Janga Rahul
2023-07-04  9:59   ` Nayana, Venkata Ramana

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox