Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage
@ 2023-05-24 14:29 Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers Dominik Grzegorzek
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

This series introduces test coverage for eudebug event
interface recently proposed as an RFC.
(https://patchwork.freedesktop.org/series/116442/) 

This series adds xe_eudebug tests together with 
a library that encapsulates common paths in current 
and future eu debugger scenarios. It provides an abstraction
over debugger and debuggee processes, asynchronous event reader,
and event log buffers for post-mortem analysis.

Place xe_eudebug tests inside xe/staging/ directory
and behind xe_staging build option as the kernel part 
won't be merged anytime soon.

Dominik Grzegorzek (8):
  xe: sync uapi headers
  meson: Introduce xe_staging build option
  xe/staging/xe_eudebug: test eudebug connection
  lib/staging/xe_eudebug: introduce eu debug testing framework
  xe/staging/xe_eudebug: test open close events
  xe/staging/xe_eudebug: exercise read_event ioctl
  xe/staging/xe_eudebug: add vm events sanity check
  xe/staging/xe_eudebug: Race discovery against eudebug attach.
  xe/staging/xe_eudebug: Add TEST/SUBTEST documentation

 include/drm-uapi/xe_drm_tmp.h |   76 +++
 lib/meson.build               |    3 +-
 lib/xe/staging/xe_eudebug.c   | 1047 +++++++++++++++++++++++++++++++++
 lib/xe/staging/xe_eudebug.h   |   89 +++
 meson.build                   |    1 +
 meson_options.txt             |    5 +
 tests/meson.build             |   17 +
 tests/xe/staging/xe_eudebug.c |  639 ++++++++++++++++++++
 8 files changed, 1876 insertions(+), 1 deletion(-)
 create mode 100644 include/drm-uapi/xe_drm_tmp.h
 create mode 100644 lib/xe/staging/xe_eudebug.c
 create mode 100644 lib/xe/staging/xe_eudebug.h
 create mode 100644 tests/xe/staging/xe_eudebug.c

-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-26 10:37   ` Zbigniew Kempczyński
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 2/9] meson: Introduce xe_staging build option Dominik Grzegorzek
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
---
 include/drm-uapi/xe_drm_tmp.h | 76 +++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 include/drm-uapi/xe_drm_tmp.h

diff --git a/include/drm-uapi/xe_drm_tmp.h b/include/drm-uapi/xe_drm_tmp.h
new file mode 100644
index 000000000..9829cd724
--- /dev/null
+++ b/include/drm-uapi/xe_drm_tmp.h
@@ -0,0 +1,76 @@
+#ifndef _UAPI_XE_DRM_TMP_H_
+#define _UAPI_XE_DRM_TMP_H_
+
+#include "xe_drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define DRM_XE_EUDEBUG_CONNECT			0x5f
+
+#define DRM_IOCTL_XE_EUDEBUG_CONNECT		DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EUDEBUG_CONNECT, struct drm_xe_eudebug_connect_param)
+
+/**
+ * Do a eudebug event read for a debugger connection.
+ *
+ * This ioctl is available in debug version 1.
+ */
+#define DRM_XE_EUDEBUG_IOCTL_READ_EVENT _IO('j', 0x0)
+
+/* XXX: Document events to match their internal counterparts when moved to xe_drm.h */
+struct drm_xe_eudebug_event {
+	struct xe_user_extension ext;
+
+	__u32 type;
+#define DRM_XE_EUDEBUG_EVENT_NONE     0
+#define DRM_XE_EUDEBUG_EVENT_READ     1
+#define DRM_XE_EUDEBUG_EVENT_OPEN     2
+#define DRM_XE_EUDEBUG_EVENT_VM	      3
+#define DRM_XE_EUDEBUG_EVENT_MAX_EVENT DRM_XE_EUDEBUG_EVENT_VM
+
+	__u32 flags;
+#define DRM_XE_EUDEBUG_EVENT_CREATE	(1 << 0)
+#define DRM_XE_EUDEBUG_EVENT_DESTROY	(1 << 1)
+#define DRM_XE_EUDEBUG_EVENT_STATE_CHANGE (1 << 2)
+
+	__u64 seqno;
+	__u64 size;
+} __attribute__((packed));
+
+struct drm_xe_eudebug_event_client {
+	struct drm_xe_eudebug_event base; /* .flags = CREATE/DESTROY */
+
+	__u64 client_handle; /* This is unique per debug connection */
+} __attribute__((packed));
+
+struct drm_xe_eudebug_event_vm {
+	struct drm_xe_eudebug_event base;
+
+	__u64 client_handle;
+	__u64 vm_handle;
+} __attribute__((packed));
+
+/*
+ * Debugger ABI (ioctl and events) Version History:
+ * 0 - No debugger available
+ * 1 - Initial version
+ */
+#define DRM_XE_EUDEBUG_VERSION 1
+
+struct drm_xe_eudebug_connect_param {
+	struct xe_user_extension ext;
+
+	__u64 pid; /* input: Target process ID */
+	__u32 flags;
+
+	__u32 version; /* output: current ABI (ioctl / events) version */
+	__u64 events;  /* input: event types to subscribe to */
+	__u64 extensions; /* MBZ */
+};
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _UAPI_XE_DRM_TMP_H_ */
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 2/9] meson: Introduce xe_staging build option
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-26 10:51   ` Zbigniew Kempczyński
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 3/9] xe/staging/xe_eudebug: test eudebug connection Dominik Grzegorzek
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

There are some major features, which in a current state cannot be merged
upstream. A good example here in an EU debugger, which does not
meet the requirement of having an opensourced client. While those
features are in the development we need a way of providing them
validation. So introduce xe_staging build option under which
we can keep tests of features that are under haevy development and not
yet accepted upstream or not yet completed.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
---
 meson.build       |  1 +
 meson_options.txt |  5 +++++
 tests/meson.build | 16 ++++++++++++++++
 3 files changed, 22 insertions(+)

diff --git a/meson.build b/meson.build
index 1c872cc9c..ae2206d6e 100644
--- a/meson.build
+++ b/meson.build
@@ -86,6 +86,7 @@ build_chamelium = get_option('chamelium')
 build_docs = get_option('docs')
 build_tests = not get_option('tests').disabled()
 build_xe = not get_option('xe_driver').disabled()
+build_xe_staging = not get_option('xe_staging').disabled()
 with_libdrm = get_option('libdrm_drivers')
 
 build_info = ['Build type: ' + get_option('buildtype')]
diff --git a/meson_options.txt b/meson_options.txt
index 7b5a818cb..46ee91fe6 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -46,6 +46,11 @@ option('xe_driver',
        type : 'feature',
        description : 'Build tests for Xe driver (experimental)')
 
+option('xe_staging',
+       type : 'feature',
+       value : 'disabled',
+       description : 'Build tests for Xe features that cannot be upstreamed yet (experimental)')
+
 option('libdrm_drivers',
        type : 'array',
        value : ['auto'],
diff --git a/tests/meson.build b/tests/meson.build
index 38f080f7c..8c7055ed9 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -269,6 +269,9 @@ xe_progs = [
 	'xe_waitfence',
 ]
 
+xe_staging_progs = [
+]
+
 msm_progs = [
 	'msm_mapping',
 	'msm_recovery',
@@ -330,6 +333,19 @@ if build_xe
 	build_info += 'Xe **experimental** tests enabled.'
 endif
 
+if build_xe_staging
+        foreach prog : xe_staging_progs
+		test_executables += executable(prog,
+		           join_paths('xe/staging', prog + '.c'),
+			   dependencies : test_deps,
+			   install_dir : libexecdir,
+			   install_rpath : libexecdir_rpathdir,
+			   install : true)
+		test_list += prog
+	endforeach
+	build_info += 'Work in progress tests enabled.'
+endif
+
 foreach prog : msm_progs
 	test_executables += executable(prog, join_paths('msm', prog + '.c'),
 				       dependencies : test_deps,
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 3/9] xe/staging/xe_eudebug: test eudebug connection
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 2/9] meson: Introduce xe_staging build option Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 4/9] lib/staging/xe_eudebug: introduce eu debug testing framework Dominik Grzegorzek
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

Add basic tests checking xe eudebug connection capability.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 tests/meson.build             |   1 +
 tests/xe/staging/xe_eudebug.c | 133 ++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+)
 create mode 100644 tests/xe/staging/xe_eudebug.c

diff --git a/tests/meson.build b/tests/meson.build
index 8c7055ed9..afe3e86a2 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -270,6 +270,7 @@ xe_progs = [
 ]
 
 xe_staging_progs = [
+	'xe_eudebug',
 ]
 
 msm_progs = [
diff --git a/tests/xe/staging/xe_eudebug.c b/tests/xe/staging/xe_eudebug.c
new file mode 100644
index 000000000..7202da689
--- /dev/null
+++ b/tests/xe/staging/xe_eudebug.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <xe_drm_tmp.h>
+#include "igt.h"
+
+static int __debug_connect(int fd, int *debugfd, struct drm_xe_eudebug_connect_param *param)
+{
+	int ret = 0;
+
+	*debugfd = igt_ioctl(fd, DRM_IOCTL_XE_EUDEBUG_CONNECT, param);
+
+	if (*debugfd < 0) {
+		ret = -errno;
+		igt_assume(ret != 0);
+	}
+
+	errno = 0;
+	return ret;
+}
+
+static void test_connect(int fd)
+{
+	struct drm_xe_eudebug_connect_param param = {};
+	int debugfd, ret;
+	pid_t *pid;
+
+	pid = mmap(NULL, sizeof(pid_t), PROT_WRITE,
+		   MAP_SHARED | MAP_ANON, -1, 0);
+
+	/* get fresh unrelated pid */
+	igt_fork(child, 1)
+		*pid = getpid();
+
+	igt_waitchildren();
+	param.pid = *pid;
+	munmap(pid, sizeof(pid_t));
+
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert(debugfd == -1);
+	igt_assert_eq(ret, param.pid ? -ENOENT : -EINVAL);
+
+	param.pid = 0;
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert(debugfd == -1);
+	igt_assert_eq(ret, -EINVAL);
+
+	igt_fork(child, 1) {
+		int newfd = drm_open_driver(DRIVER_XE);
+
+		igt_drop_root();
+
+		param.pid = 1;
+		ret = __debug_connect(newfd, &debugfd, &param);
+		igt_assert(debugfd == -1);
+		igt_assert_eq(ret, -EACCES);
+	}
+	igt_waitchildren();
+
+	param.pid = getpid();
+	param.version = -1;
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert(debugfd == -1);
+	igt_assert_eq(ret, -EINVAL);
+
+	param.version = 0;
+	param.flags = ~0;
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert(debugfd == -1);
+	igt_assert_eq(ret, -EINVAL);
+
+	param.flags = 0;
+	param.events = ~0;
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert(debugfd == -1);
+	igt_assert_eq(ret, -EINVAL);
+
+	param.events = 0;
+	param.extensions = ~0;
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert(debugfd == -1);
+	igt_assert_eq(ret, -EINVAL);
+
+	param.extensions = 0;
+	ret = __debug_connect(fd, &debugfd, &param);
+	igt_assert_neq(debugfd, -1);
+	igt_assert_eq(ret, 0);
+
+	close(debugfd);
+}
+
+static void test_close(int fd)
+{
+	struct drm_xe_eudebug_connect_param param = { 0,  };
+	int debug_fd1, debug_fd2;
+	int fd2;
+
+	param.pid = getpid();
+
+	igt_assert_eq(__debug_connect(fd, &debug_fd1, &param), 0);
+	igt_assert(debug_fd1 >= 0);
+	igt_assert_eq(__debug_connect(fd, &debug_fd2, &param), -EBUSY);
+	igt_assert_eq(debug_fd2, -1);
+
+	close(debug_fd1);
+	fd2 = drm_open_driver(DRIVER_XE);
+
+	igt_assert_eq(__debug_connect(fd2, &debug_fd2, &param), 0);
+	igt_assert(debug_fd2 >= 0);
+	close(fd2);
+	close(debug_fd2);
+	close(debug_fd1);
+}
+
+igt_main
+{
+	int fd;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_XE);
+	}
+
+	igt_subtest("basic-connect")
+		test_connect(fd);
+
+	igt_subtest("basic-close")
+		test_close(fd);
+
+	igt_fixture
+		close(fd);
+}
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 4/9] lib/staging/xe_eudebug: introduce eu debug testing framework
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (2 preceding siblings ...)
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 3/9] xe/staging/xe_eudebug: test eudebug connection Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 5/9] xe/staging/xe_eudebug: test open close events Dominik Grzegorzek
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev; +Cc: Mika Kuoppala

Introduce library which simplifies testing of eu debug capability.
The library provides event log helpers together with asynchronous
abstraction for client proccess and the debugger itself.

xe_eudebug_client creates its own proccess with user's work function,
and gives machanisms to synchronize beginning of execution and event
logging.

xe_eudebug_debugger allows to attach to the given proccess, provides
asynchronous thread for event reading and introduces triggers - a
callback mechanism triggered every time subscribed event was read.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuaoppala@linux.intel.com>
---
 lib/meson.build             |    3 +-
 lib/xe/staging/xe_eudebug.c | 1047 +++++++++++++++++++++++++++++++++++
 lib/xe/staging/xe_eudebug.h |   89 +++
 3 files changed, 1138 insertions(+), 1 deletion(-)
 create mode 100644 lib/xe/staging/xe_eudebug.c
 create mode 100644 lib/xe/staging/xe_eudebug.h

diff --git a/lib/meson.build b/lib/meson.build
index 85f100f75..7d79919fc 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -104,7 +104,8 @@ lib_sources = [
 	'xe/xe_compute_square_kernels.c',
 	'xe/xe_ioctl.c',
 	'xe/xe_query.c',
-	'xe/xe_spin.c'
+	'xe/xe_spin.c',
+	'xe/staging/xe_eudebug.c'
 ]
 
 lib_deps = [
diff --git a/lib/xe/staging/xe_eudebug.c b/lib/xe/staging/xe_eudebug.c
new file mode 100644
index 000000000..45df071fd
--- /dev/null
+++ b/lib/xe/staging/xe_eudebug.c
@@ -0,0 +1,1047 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/select.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include "xe_eudebug.h"
+#include "xe/xe_ioctl.h"
+#include "igt.h"
+
+struct event_trigger {
+	xe_eudebug_trigger_fn fn;
+	int type;
+	struct igt_list_head link;
+};
+
+#define CLIENT_PID  1
+#define CLIENT_RUN  2
+#define CLIENT_FINI 3
+#define CLIENT_STOP 4
+
+#define DEBUGGER_WORKER_INACTIVE  0
+#define DEBUGGER_WORKER_ACTIVE  1
+#define DEBUGGER_WORKER_QUITTING 2
+
+static const char *type_to_str(unsigned int type)
+{
+	switch (type) {
+	case DRM_XE_EUDEBUG_EVENT_NONE:
+		return "none";
+	case DRM_XE_EUDEBUG_EVENT_READ:
+		return "read";
+	case DRM_XE_EUDEBUG_EVENT_OPEN:
+		return "client";
+	case DRM_XE_EUDEBUG_EVENT_VM:
+		return "vm";
+	}
+
+	return "unknown";
+}
+
+static const char *event_type_to_str(struct drm_xe_eudebug_event *e, char *buf)
+{
+	sprintf(buf, "%s(%d)", type_to_str(e->type), e->type);
+
+	return buf;
+}
+
+static const char *flags_to_str(unsigned int flags)
+{
+	if (flags & DRM_XE_EUDEBUG_EVENT_CREATE)
+		return "create";
+
+	if (flags & DRM_XE_EUDEBUG_EVENT_DESTROY)
+		return "destroy";
+
+	if (flags & DRM_XE_EUDEBUG_EVENT_STATE_CHANGE)
+		return "state-change";
+
+	return "flags unknown";
+}
+
+static const char *event_members_to_str(struct drm_xe_eudebug_event *e, char *b)
+{
+	switch (e->type) {
+	case DRM_XE_EUDEBUG_EVENT_OPEN: {
+		struct drm_xe_eudebug_event_client *ec = (struct drm_xe_eudebug_event_client *)e;
+
+		sprintf(b, "handle=%llu", ec->client_handle);
+		break;
+	}
+	case DRM_XE_EUDEBUG_EVENT_VM: {
+		struct drm_xe_eudebug_event_vm *evm = (struct drm_xe_eudebug_event_vm *)e;
+
+		sprintf(b, "client_handle=%llu, handle=%llu",
+			evm->client_handle, evm->vm_handle);
+		break;
+	}
+	default:
+		strcpy(b, "<...>");
+	}
+
+	return b;
+}
+
+static const char *event_to_str(struct drm_xe_eudebug_event *e, char *buf)
+{
+	char a[256];
+	char b[256];
+
+	sprintf(buf, "(%llu) %15s:%s: %s",
+		e->seqno,
+		event_type_to_str(e, a),
+		flags_to_str(e->flags),
+		event_members_to_str(e, b));
+
+	return buf;
+}
+
+static void catch_child_failure(void)
+{
+	pid_t pid;
+	int status;
+
+	pid = waitpid(-1, &status, WNOHANG);
+
+	if (pid == 0 || pid == -1)
+		return;
+
+	if (!WIFEXITED(status))
+		return;
+
+	igt_assert_f(WEXITSTATUS(status) == 0, "Client failed!\n");
+}
+
+static int safe_pipe_read(int pipe[2], void *buf, int nbytes)
+{
+	int ret;
+	struct pollfd fd = {
+		.fd = pipe[0],
+		.events = POLLIN,
+		.revents = 0
+	};
+
+	/* When child fails we may get stuck forever. Check whether
+	 * the child process ended with an error.
+	 */
+	do {
+		ret = poll(&fd, 1, 1000);
+
+		if (!ret)
+			catch_child_failure();
+	} while (!ret);
+
+	return read(pipe[0], buf, nbytes);
+}
+
+static uint64_t pipe_wait_u64(int pipe[2])
+{
+	uint64_t in;
+	uint64_t ret;
+
+	ret = safe_pipe_read(pipe, &in, sizeof(in));
+	igt_assert(ret == sizeof(in));
+
+	return in;
+}
+
+#define pipe_wait pipe_wait_u64
+
+static void pipe_wait_token(int pipe[2], uint64_t token)
+{
+	uint64_t in;
+
+	in = pipe_wait_u64(pipe);
+	igt_assert_eq(token, in);
+}
+
+static void pipe_signal(int pipe[2], uint64_t token)
+{
+	igt_assert(write(pipe[1], &token, sizeof(token)) == sizeof(token));
+}
+
+static void pipe_close(int pipe[2])
+{
+	if (pipe[0] != -1)
+		close(pipe[0]);
+
+	if (pipe[1] != -1)
+		close(pipe[1]);
+}
+
+static int __xe_eudebug_connect(int fd, pid_t pid, uint32_t flags, uint64_t events)
+{
+	struct drm_xe_eudebug_connect_param param = {
+		.pid = pid,
+		.flags = flags,
+		.events = events
+	};
+	int debugfd;
+
+	debugfd = igt_ioctl(fd, DRM_IOCTL_XE_EUDEBUG_CONNECT, &param);
+
+	if (debugfd < 0)
+		return -errno;
+
+	return debugfd;
+}
+
+static int xe_eudebug_connect(int fd, pid_t pid, uint32_t flags)
+{
+	int ret;
+	uint64_t events = 0; /* events filtering not supported yet! */
+
+	ret = __xe_eudebug_connect(fd, pid, flags, events);
+
+	return ret;
+}
+
+static void event_log_write_to_fd(struct xe_eudebug_event_log *l, int fd)
+{
+	igt_assert_eq(write(fd, &l->head, sizeof(l->head)),
+		      sizeof(l->head));
+
+	igt_assert_eq(write(fd, l->log, l->head), l->head);
+}
+
+static void event_log_read_from_fd(struct xe_eudebug_event_log *l, int fd)
+{
+	igt_assert_eq(read(fd, &l->head, sizeof(l->head)),
+		      sizeof(l->head));
+
+	igt_assert_lt(l->head, l->max_size);
+
+	igt_assert_eq(read(fd, l->log, l->head), l->head);
+}
+
+typedef int (*cmp_fn_t)(struct drm_xe_eudebug_event *,	void *data);
+
+static struct drm_xe_eudebug_event *
+event_cmp(struct xe_eudebug_event_log *l,
+	  struct drm_xe_eudebug_event *current,
+	  cmp_fn_t match,
+	  void *data)
+{
+	struct drm_xe_eudebug_event *e = current;
+
+	xe_eudebug_for_each_event(e, l) {
+		if (match(e, data))
+			return e;
+	}
+
+	return NULL;
+}
+
+static int match_type_and_flags(struct drm_xe_eudebug_event *a, void *data)
+{
+	struct drm_xe_eudebug_event *b = data;
+
+	if (a->type == b->type &&
+	    a->flags == b->flags)
+		return 1;
+
+	return 0;
+}
+
+static int match_client_handle(struct drm_xe_eudebug_event *e, void *data)
+{
+	uint64_t h = *(uint64_t *)data;
+
+	switch (e->type) {
+	case DRM_XE_EUDEBUG_EVENT_OPEN: {
+		struct drm_xe_eudebug_event_client *client = (struct drm_xe_eudebug_event_client *)e;
+
+		if (client->client_handle == h)
+			return 1;
+		break;
+	}
+	case DRM_XE_EUDEBUG_EVENT_VM: {
+		struct drm_xe_eudebug_event_vm *vm = (struct drm_xe_eudebug_event_vm *)e;
+
+		if (vm->client_handle == h)
+			return 1;
+		break;
+	}
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int match_opposite_resource(struct drm_xe_eudebug_event *e, void *data)
+{
+
+	struct drm_xe_eudebug_event *d = (void *)data;
+	int ret;
+
+	d->flags ^= DRM_XE_EUDEBUG_EVENT_CREATE | DRM_XE_EUDEBUG_EVENT_DESTROY;
+	ret = match_type_and_flags(e, data);
+	d->flags ^= DRM_XE_EUDEBUG_EVENT_CREATE | DRM_XE_EUDEBUG_EVENT_DESTROY;
+
+	if (!ret)
+		return 0;
+
+	switch (e->type) {
+	case DRM_XE_EUDEBUG_EVENT_OPEN: {
+		struct drm_xe_eudebug_event_client *client = (struct drm_xe_eudebug_event_client *)e;
+		struct drm_xe_eudebug_event_client *filter = (struct drm_xe_eudebug_event_client *)data;
+
+		if (client->client_handle == filter->client_handle)
+			return 1;
+		break;
+	}
+	case DRM_XE_EUDEBUG_EVENT_VM: {
+		struct drm_xe_eudebug_event_vm *vm = (struct drm_xe_eudebug_event_vm *)e;
+		struct drm_xe_eudebug_event_vm *filter = (struct drm_xe_eudebug_event_vm *)data;
+
+		if (vm->vm_handle == filter->vm_handle)
+			return 1;
+		break;
+	}
+	default:
+		break;
+	}
+	return 0;
+}
+
+static struct drm_xe_eudebug_event *
+event_type_match(struct xe_eudebug_event_log *l,
+		 struct drm_xe_eudebug_event *filter,
+		 struct drm_xe_eudebug_event *current)
+{
+	return event_cmp(l, current, match_type_and_flags, filter);
+}
+
+static struct drm_xe_eudebug_event *
+client_match(struct xe_eudebug_event_log *l,
+	     uint64_t client_handle,
+	     struct drm_xe_eudebug_event *current)
+{
+	return event_cmp(l, current, match_client_handle, &client_handle);
+}
+
+static struct drm_xe_eudebug_event *
+opposite_event_match(struct xe_eudebug_event_log *l,
+		    struct drm_xe_eudebug_event *filter,
+		    struct drm_xe_eudebug_event *current)
+{
+	return event_cmp(l, current, match_opposite_resource, filter);
+}
+
+static void compare_client(struct xe_eudebug_event_log *c, struct drm_xe_eudebug_event *_ce,
+			   struct xe_eudebug_event_log *d, struct drm_xe_eudebug_event *_de)
+{
+	struct drm_xe_eudebug_event_client *ce = (void *)_ce;
+	struct drm_xe_eudebug_event_client *de = (void *)_de;
+	struct drm_xe_eudebug_event *hc, *hd;
+
+	igt_assert(ce);
+	igt_assert(de);
+
+	igt_debug("client: %llu -> %llu\n", ce->client_handle, de->client_handle);
+
+	hc = NULL;
+	hd = NULL;
+
+	do {
+		hc = client_match(c, ce->client_handle, hc);
+		if (!hc)
+			break;
+
+		hd = client_match(d, de->client_handle, hd);
+		if (!hd) {
+			igt_warn("no matching event type %u found for client %llu\n",
+				 hc->type, ce->client_handle);
+			igt_assert(hd);
+		}
+
+		igt_debug("comparing %s %llu vs %s %llu\n",
+			 c->name, hc->seqno, d->name, hd->seqno);
+
+		igt_assert_eq(hc->type, hd->type);
+		igt_assert_eq(hc->flags, hd->flags);
+	} while (hc);
+}
+
+/*
+ * Yeah very slow but someone with lots of events
+ * will conjure a better datastruct
+ */
+static struct drm_xe_eudebug_event *
+xe_eudebug_event_log_find_seqno(struct xe_eudebug_event_log *l, uint64_t seqno)
+{
+	struct drm_xe_eudebug_event *e = NULL, *found = NULL;
+
+	xe_eudebug_for_each_event(e, l) {
+		if (e->seqno == seqno) {
+			igt_assert(!found);
+			found = e;
+		}
+	}
+
+	return found;
+}
+
+static void event_log_sort(struct xe_eudebug_event_log *l)
+{
+	struct xe_eudebug_event_log *tmp;
+	struct drm_xe_eudebug_event *e = NULL;
+	uint64_t first_seqno = 0;
+	uint64_t last_seqno = 0;
+	uint64_t events = 0, added = 0;
+	uint64_t i;
+
+	xe_eudebug_for_each_event(e, l) {
+		if (e->seqno > last_seqno)
+			last_seqno = e->seqno;
+
+		if (e->seqno < first_seqno)
+			first_seqno = e->seqno;
+
+		events++;
+	}
+
+	tmp = xe_eudebug_event_log_create("tmp", l->max_size);
+
+	for (i = 0; i <= last_seqno; i++) {
+		e = xe_eudebug_event_log_find_seqno(l, i);
+		if (e) {
+			xe_eudebug_event_log_write(tmp, e);
+			added++;
+		}
+	}
+
+	igt_assert_eq(events, added);
+	igt_assert_eq(tmp->head, l->head);
+
+	memcpy(l->log, tmp->log, tmp->head);
+
+	xe_eudebug_event_log_destroy(tmp);
+}
+
+/**
+ * xe_eudebug_event_log_create:
+ * @name: event log identifier
+ * @max_size: maximum size of created log
+ *
+ * Function creates an Eu Debugger event log with size equal to @max_size.
+ *
+ * Returns: pointer to just created log
+ */
+#define MAX_EVENT_LOG_SIZE (32 * 1024 * 1024)
+struct xe_eudebug_event_log *xe_eudebug_event_log_create(const char *name, unsigned int max_size)
+{
+	struct xe_eudebug_event_log *l;
+
+	l = calloc(1, sizeof(*l));
+	igt_assert(l);
+	l->log = calloc(1, max_size);
+	igt_assert(l->log);
+	l->max_size = max_size;
+	strncpy(l->name, name, sizeof(l->name) - 1);
+
+	return l;
+}
+
+/**
+ * xe_eudebug_event_log_destroy:
+ * @l: event log pointer
+ *
+ * Frees given event log @l.
+ */
+void xe_eudebug_event_log_destroy(struct xe_eudebug_event_log *l)
+{
+	free(l->log);
+	free(l);
+}
+
+/**
+ * xe_eudebug_event_log_write:
+ * @l: event log pointer
+ * @e: event to be written to event log
+ *
+ * Writes event @e to the event log.
+ */
+void xe_eudebug_event_log_write(struct xe_eudebug_event_log *l, struct drm_xe_eudebug_event *e)
+{
+	igt_assert_lt(l->head + e->size, l->max_size);
+	memcpy(l->log + l->head, e, e->size);
+	l->head += e->size;
+
+#ifdef DEBUG_LOG
+	igt_info("%s: wrote %u bytes to eventlog, free %u bytes\n",
+		 l->name, size, l->max_size - l->head);
+#endif
+}
+
+/**
+ * xe_eudebug_event_log_print:
+ * @l: event log pointer
+ * @debug: when true function uses igt_debug instead of igt_info.
+ *
+ * Prints given event log.
+ */
+void
+xe_eudebug_event_log_print(struct xe_eudebug_event_log *l, bool debug)
+{
+	struct drm_xe_eudebug_event *e = NULL;
+	int level = debug ? IGT_LOG_DEBUG : IGT_LOG_INFO;
+	char str[4096];
+
+	igt_log(IGT_LOG_DOMAIN, level,
+		"event log '%s' (%u bytes):\n", l->name, l->head);
+
+	xe_eudebug_for_each_event(e, l) {
+		event_to_str(e, str);
+		igt_log(IGT_LOG_DOMAIN, level, "%s\n", str);
+	}
+}
+
+/**
+ * xe_eudebug_event_log_compare:
+ * @a: event log pointer
+ * @b: event log pointer
+ *
+ * Compares and asserts event logs @a, @b if the event
+ * sequence matches.
+ */
+void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *a, struct xe_eudebug_event_log *b)
+{
+	struct drm_xe_eudebug_event *ae = NULL;
+	struct drm_xe_eudebug_event *be = NULL;
+
+	xe_eudebug_for_each_event(ae, a) {
+		if (ae->type == DRM_XE_EUDEBUG_EVENT_OPEN &&
+		    ae->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
+			be = event_type_match(b, ae, be);
+
+			compare_client(a, ae, b, be);
+			compare_client(b, be, a, ae);
+		}
+	}
+}
+
+/**
+ * xe_eudebug_event_log_match_opposite:
+ * @l: event log pointer
+ *
+ * Matches and asserts content of all opposite events (create vs destroy).
+ */
+void
+xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log *l)
+{
+	struct drm_xe_eudebug_event *ce = NULL;
+	struct drm_xe_eudebug_event *de = NULL;
+
+	xe_eudebug_for_each_event(ce, l) {
+		if (ce->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
+			uint8_t offset = sizeof(struct drm_xe_eudebug_event);
+			int opposite_matching;
+
+			de = opposite_event_match(l, ce, ce);
+
+			igt_assert_eq(ce->size, de->size);
+			opposite_matching = memcmp((uint8_t *)de + offset,
+						   (uint8_t *)ce + offset,
+						   de->size - offset) == 0;
+
+			igt_assert_f(opposite_matching,
+				     "%s: create|destroy event not "
+				     "maching (%llu) vs (%llu)\n",
+				     l->name, de->seqno, ce->seqno);
+		}
+	}
+}
+
+static void debugger_run_triggers(struct xe_eudebug_debugger *d,
+				  struct drm_xe_eudebug_event *e)
+{
+	struct event_trigger *t;
+
+	igt_list_for_each_entry(t, &d->triggers, link) {
+		if (e->type == t->type)
+			t->fn(d, e);
+	}
+}
+
+#define MAX_EVENT_SIZE (32 * 1024)
+static int
+xe_eudebug_read_event(int fd, struct drm_xe_eudebug_event *event)
+{
+	int ret;
+
+	event->type = DRM_XE_EUDEBUG_EVENT_READ;
+	event->flags = 0;
+	event->size = MAX_EVENT_SIZE;
+
+	ret = igt_ioctl(fd, DRM_XE_EUDEBUG_IOCTL_READ_EVENT, event);
+	if (ret < 0)
+		return -errno;
+
+	return ret;
+}
+
+static void *debugger_worker_loop(void *data)
+{
+	uint8_t buf[MAX_EVENT_SIZE];
+	struct drm_xe_eudebug_event *e = (void *)buf;
+	struct xe_eudebug_debugger *d = data;
+	struct pollfd p = {
+		.fd = d->fd,
+		.events = POLLIN,
+		.revents = 0,
+	};
+	int timeout_ms = 100, ret;
+
+	igt_assert(d->master_fd >= 0);
+
+	 do {
+		ret = poll(&p, 1, timeout_ms);
+
+		if (ret == -1) {
+			igt_info("poll failed with errno %d\n", errno);
+			break;
+		}
+
+		if (ret == 1 && (p.revents & POLLIN)) {
+			int err = xe_eudebug_read_event(d->fd, e);
+
+			if (!err) {
+				++d->event_count;
+
+				xe_eudebug_event_log_write(d->log, e);
+				debugger_run_triggers(d, e);
+			} else {
+				igt_info("xe_eudebug_read_event returned %d\n", ret);
+			}
+		}
+	} while ((ret && READ_ONCE(d->worker_state) == DEBUGGER_WORKER_QUITTING) ||
+		 READ_ONCE(d->worker_state) == DEBUGGER_WORKER_ACTIVE);
+
+	d->worker_state = DEBUGGER_WORKER_INACTIVE;
+	return NULL;
+}
+
+/**
+ * xe_eudebug_debugger_create:
+ * @master_fd: xe client used to open the debugger connection
+ * @flags: flags stored in a debugger structure, can be used at will
+ * of the caller, i.e. to be used inside triggers.
+ *
+ * Returns: newly created xe_eudebug_debugger structure with its
+ * event log initialized. Note that to open the connection
+ * you need call @xe_eudebug_debugger_attach.
+ */
+struct xe_eudebug_debugger *
+xe_eudebug_debugger_create(int master_fd, uint64_t flags)
+{
+	struct xe_eudebug_debugger *d;
+
+	d = calloc(1, sizeof(*d));
+	d->flags = flags;
+	igt_assert(d);
+	IGT_INIT_LIST_HEAD(&d->triggers);
+	d->log = xe_eudebug_event_log_create("debugger", MAX_EVENT_LOG_SIZE);
+	d->fd = -1;
+	d->master_fd = master_fd;
+
+	return d;
+}
+
+static void debugger_destroy_triggers(struct xe_eudebug_debugger *d)
+{
+	struct event_trigger *t, *tmp;
+
+	igt_list_for_each_entry_safe(t, tmp, &d->triggers, link)
+		free(t);
+}
+
+/**
+ * xe_eudebug_debugger_destroy:
+ * @d: pointer to the debugger
+ *
+ * Frees xe_eudebug_debugger structure pointed by @d. If the debugger
+ * connection was still opened it terminates it.
+ */
+void xe_eudebug_debugger_destroy(struct xe_eudebug_debugger *d)
+{
+	if (d->worker_state)
+		xe_eudebug_debugger_stop_worker(d, 1);
+
+	if (d->target_pid)
+		xe_eudebug_debugger_dettach(d);
+
+	xe_eudebug_event_log_destroy(d->log);
+	debugger_destroy_triggers(d);
+	free(d);
+}
+
+/**
+ * xe_eudebug_debugger_attach:
+ * @d: pointer to the debugger
+ * @target: pid of the process to attach debugger
+ *
+ * Opens the xe eu debugger connection to the @target proccess.
+ *
+ * Returns: 0 if the debugger was successfully attached, -errno otherwise.
+ */
+int xe_eudebug_debugger_attach(struct xe_eudebug_debugger *d, pid_t target)
+{
+	int ret;
+
+	igt_assert_eq(d->fd, -1);
+	ret = xe_eudebug_connect(d->master_fd, target, 0);
+
+	if (ret < 0)
+		return ret;
+
+	d->fd = ret;
+	d->target_pid = target;
+
+	igt_debug("debugger connected to %lu\n", d->target_pid);
+
+	return 0;
+}
+
+/**
+ * xe_eudebug_debugger_dettach:
+ * @d: pointer to the debugger
+ *
+ * Closes previously opened xe eu debugger connection. Asserts if
+ * the debugger has active session.
+ */
+void xe_eudebug_debugger_dettach(struct xe_eudebug_debugger *d)
+{
+	igt_assert(d->target_pid);
+	close(d->fd);
+	d->target_pid = 0;
+	d->fd = -1;
+}
+
+/**
+ * xe_eudebug_debugger_add_trigger:
+ * @d: pointer to the debugger
+ * @type: the type of the event which activates the trigger
+ * @fn: function to be called when event of @type was read by the debugger.
+ *
+ * Adds function @fn to the list of triggers activated when event of @type
+ * has been read by worker.
+ * Note: Triggers are activated by the worker.
+ */
+void xe_eudebug_debugger_add_trigger(struct xe_eudebug_debugger *d,
+				     int type, xe_eudebug_trigger_fn fn)
+{
+	struct event_trigger *t;
+
+	t = calloc(1, sizeof(*t));
+	IGT_INIT_LIST_HEAD(&t->link);
+	t->type = type;
+	t->fn = fn;
+
+	igt_list_add_tail(&t->link, &d->triggers);
+	igt_debug("added trigger %p\n", t);
+}
+
+/**
+ * xe_eudebug_debugger_start_worker:
+ * @d: pointer to the debugger
+ *
+ * Starts the debugger worker. Worker is resposible for reading all
+ * incoming events from the debugger, put then into debugger log and
+ * execute appropriate event triggers. Note that using the debuggers
+ * event log while worker is running is not safe.
+ */
+void xe_eudebug_debugger_start_worker(struct xe_eudebug_debugger *d)
+{
+	int ret;
+
+	d->worker_state = true;
+	ret = pthread_create(&d->worker_thread, NULL, &debugger_worker_loop, d);
+
+	igt_assert_f(ret == 0, "Debugger worker thread creation failed!");
+}
+
+/**
+ * xe_eudebug_debugger_stop_worker:
+ * @d: pointer to the debugger
+ *
+ * Stops the debugger worker. Event log is sorted by seqno after closure.
+ */
+void xe_eudebug_debugger_stop_worker(struct xe_eudebug_debugger *d,
+				     int timeout_s)
+{
+	struct timespec t = {};
+	int ret;
+
+	igt_assert(d->worker_state);
+
+	d->worker_state = DEBUGGER_WORKER_QUITTING; /* First time be polite. */
+	igt_assert_eq(clock_gettime(CLOCK_REALTIME, &t), 0);
+	t.tv_sec += timeout_s;
+
+	ret = pthread_timedjoin_np(d->worker_thread, NULL, &t);
+
+	if (ret == ETIMEDOUT) {
+		d->worker_state = DEBUGGER_WORKER_INACTIVE;
+		ret = pthread_join(d->worker_thread, NULL);
+	}
+
+	igt_assert_f(ret == 0 || ret != ESRCH,
+		     "pthread join failed with error %d!\n", ret);
+
+	event_log_sort(d->log);
+}
+
+/**
+ * xe_eudebug_client_create:
+ * @work: function that opens xe device and executes arbitrary workload
+ * @flags: flags stored in a client structure, can be used at will
+ * of the caller, i.e. to provide the @work function an additional switch.
+ *
+ * Forks and creates the debugger process. @work won't be called until
+ * xe_eudebug_client_start is called.
+ *
+ * Returns: newly created xe_eudebug_debugger structure with its
+ * event log initialized.
+ */
+struct xe_eudebug_client *xe_eudebug_client_create(xe_eudebug_client_work_fn work, uint64_t flags)
+{
+	struct xe_eudebug_client *c;
+
+	c = calloc(1, sizeof(*c));
+	c->flags = flags;
+	igt_assert(c);
+	igt_assert(!pipe(c->p_in));
+	igt_assert(!pipe(c->p_out));
+	c->seqno = 1;
+	c->log = xe_eudebug_event_log_create("client", MAX_EVENT_LOG_SIZE);
+	c->done = 0;
+
+	igt_fork(child, 1) {
+		igt_assert_eq(c->pid, 0);
+
+		close(c->p_out[0]);
+		c->p_out[0] = -1;
+		close(c->p_in[1]);
+		c->p_in[1] = -1;
+
+		pipe_signal(c->p_out, CLIENT_PID);
+		pipe_signal(c->p_out, getpid());
+
+		pipe_wait_token(c->p_in, CLIENT_RUN);
+		work(c);
+		pipe_signal(c->p_out, CLIENT_FINI);
+
+		igt_assert_eq(c->pid, 0);
+		event_log_write_to_fd(c->log, c->p_out[1]);
+		pipe_signal(c->p_out, c->seqno);
+		pipe_wait_token(c->p_in, CLIENT_STOP);
+	}
+
+	close(c->p_out[1]);
+	c->p_out[1] = -1;
+	close(c->p_in[0]);
+	c->p_in[0] = -1;
+
+	pipe_wait_token(c->p_out, CLIENT_PID);
+	c->pid = pipe_wait(c->p_out);
+
+	igt_info("client running with pid %d\n", c->pid);
+
+	return c;
+}
+
+/**
+ * xe_eudebug_client_stop:
+ * @c: pointer to xe_eudbug_client structure
+ *
+ * Waits for the end of client's work and exits the proccess.
+ */
+void xe_eudebug_client_stop(struct xe_eudebug_client *c)
+{
+	if (c->pid) {
+		int waitstatus;
+
+		xe_eudebug_client_wait_done(c);
+
+		pipe_signal(c->p_in, CLIENT_STOP);
+		igt_assert_eq(waitpid(c->pid, &waitstatus, 0),
+			      c->pid);
+		c->pid = 0;
+	}
+}
+
+/**
+ * xe_eudebug_client_destroy:
+ * @c: pointer to xe_eudbug_client structure to be freed
+ *
+ * Frees the @c client structure. Note that it calls xe_eudebug_client_stop if
+ * client proccess has not terminated yet.
+ */
+void xe_eudebug_client_destroy(struct xe_eudebug_client *c)
+{
+	xe_eudebug_client_stop(c);
+	pipe_close(c->p_in);
+	pipe_close(c->p_out);
+	xe_eudebug_event_log_destroy(c->log);
+	free(c);
+}
+
+/**
+ * xe_eudebug_client_get_seqno:
+ * @c: pointer to xe_eudbug_client structure
+ *
+ * Increments and returns current seqno value of the given client @c
+ *
+ * Returns: incremented seqno
+ */
+uint64_t xe_eudebug_client_get_seqno(struct xe_eudebug_client *c)
+{
+	return c->seqno++;
+}
+
+/**
+ * xe_eudebug_client_start:
+ * @c: pointer to xe_eudebug_client structure
+ *
+ * Starts execution of client's work function within the client's proccess.
+ */
+void xe_eudebug_client_start(struct xe_eudebug_client *c)
+{
+	pipe_signal(c->p_in, CLIENT_RUN);
+}
+
+/**
+ * xe_eudebug_client_wait_done:
+ * @c: pointer to xe_eudebug_client structure
+ *
+ * Waits for the client work end updates the event log.
+ * Doesn't terminate the client's proccess yet.
+ */
+void xe_eudebug_client_wait_done(struct xe_eudebug_client *c)
+{
+	if (!c->done) {
+		c->done = 1;
+		pipe_wait_token(c->p_out, CLIENT_FINI);
+		event_log_read_from_fd(c->log, c->p_out[0]);
+		c->seqno = pipe_wait(c->p_out);
+	}
+}
+
+#define to_base(x) ((struct drm_xe_eudebug_event *)&x)
+
+static void base_event(struct xe_eudebug_client *c,
+		       struct drm_xe_eudebug_event *e,
+		       uint32_t type,
+		       uint32_t flags,
+		       uint64_t size)
+{
+	e->type = type;
+	e->flags = flags;
+	e->seqno = xe_eudebug_client_get_seqno(c);
+	e->size = size;
+}
+
+static void client_event(struct xe_eudebug_client *c, uint32_t flags, int client_fd)
+{
+	struct drm_xe_eudebug_event_client ec;
+
+	base_event(c, to_base(ec), DRM_XE_EUDEBUG_EVENT_OPEN, flags, sizeof(ec));
+
+	ec.client_handle = client_fd;
+
+	xe_eudebug_event_log_write(c->log, (void *)&ec);
+}
+
+static void vm_event(struct xe_eudebug_client *c, uint32_t flags, int client_fd, uint32_t vm_id)
+{
+	struct drm_xe_eudebug_event_vm evm;
+
+	base_event(c, to_base(evm), DRM_XE_EUDEBUG_EVENT_VM, flags, sizeof(evm));
+
+	evm.client_handle = client_fd;
+	evm.vm_handle = vm_id;
+
+	xe_eudebug_event_log_write(c->log, (void *)&evm);
+}
+
+/* Eu debugger wrappers around resource creating xe ioctls. */
+
+/**
+ * xe_eudebug_client_open_driver:
+ * @c: pointer to xe_eudebug_client structure
+ *
+ * Calls drm_open_client(DRIVER_XE) and logs the corresponding
+ * event in client's event log.
+ *
+ * Returns: valid DRM file descriptor
+ */
+int xe_eudebug_client_open_driver(struct xe_eudebug_client *c)
+{
+	int fd;
+
+	fd = drm_open_driver(DRIVER_XE);
+	client_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, fd);
+
+	return fd;
+}
+
+/**
+ * xe_eudebug_client_close_driver:
+ * @c: pointer to xe_eudebug_client structure
+ * @fd: xe client
+ *
+ * Calls close driver and logs the corresponding event in
+ * client's event log.
+ */
+void xe_eudebug_client_close_driver(struct xe_eudebug_client *c, int fd)
+{
+	client_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, fd);
+	close(fd);
+}
+
+/**
+ * xe_eudebug_client_vm_create:
+ * @c: pointer to xe_eudebug_client structure
+ * @fd: xe client
+ * @flags: vm bind flags
+ * @ext: pointer to the first user extension
+ *
+ * Calls xe_vm_create() and logs the corresponding event in
+ * client's event log.
+ *
+ * Returns: valid vm handle
+ */
+uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c, int fd,
+				     uint32_t flags, uint64_t ext)
+{
+	uint32_t vm;
+
+	vm = xe_vm_create(fd, flags, ext);
+	vm_event(c, DRM_XE_EUDEBUG_EVENT_CREATE, fd, vm);
+
+	return vm;
+}
+
+/**
+ * xe_eudebug_client_vm_destroy:
+ * @c: pointer to xe_eudebug_client structure
+ * fd: xe client
+ * vm: vm handle
+ *
+ * Calls xe_vm_destroy() and logs the corresponding event in
+ * client's event log.
+ */
+void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, int fd, uint32_t vm)
+{
+	xe_vm_destroy(fd, vm);
+	vm_event(c, DRM_XE_EUDEBUG_EVENT_DESTROY, fd, vm);
+}
diff --git a/lib/xe/staging/xe_eudebug.h b/lib/xe/staging/xe_eudebug.h
new file mode 100644
index 000000000..5170878dc
--- /dev/null
+++ b/lib/xe/staging/xe_eudebug.h
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+#include <stdint.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include <xe_drm.h>
+#include <xe_drm_tmp.h>
+#include "igt_list.h"
+
+struct xe_eudebug_event_log {
+	uint8_t *log;
+	unsigned int head;
+	unsigned int max_size;
+	char name[80];
+};
+
+struct xe_eudebug_debugger {
+	int fd;
+	uint64_t flags;
+
+	struct xe_eudebug_event_log *log;
+
+	uint64_t event_count;
+
+	uint64_t target_pid;
+
+	struct igt_list_head triggers;
+
+	int master_fd;
+
+	pthread_t worker_thread;
+	int worker_state;
+};
+
+struct xe_eudebug_client {
+	int pid;
+	uint64_t seqno;
+	uint64_t flags;
+	struct xe_eudebug_event_log *log;
+
+	int done;
+	int p_in[2];
+	int p_out[2];
+};
+
+typedef void (*xe_eudebug_client_work_fn)(struct xe_eudebug_client *);
+typedef void (*xe_eudebug_trigger_fn)(struct xe_eudebug_debugger *,
+				      struct drm_xe_eudebug_event *);
+
+#define xe_eudebug_for_each_event(_e, _log) \
+	for ((_e) = (_e) ? (void *)(uint8_t *)(_e) + (_e)->size : \
+		    (void *)(_log)->log; \
+	    (uint8_t *)(_e) < (_log)->log + (_log)->head; \
+	    (_e) = (void *)(uint8_t *)(_e) + (_e)->size)
+
+struct xe_eudebug_event_log *
+xe_eudebug_event_log_create(const char *name, unsigned int max_size);
+void xe_eudebug_event_log_destroy(struct xe_eudebug_event_log *l);
+void xe_eudebug_event_log_print(struct xe_eudebug_event_log *l, bool debug);
+void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *c, struct xe_eudebug_event_log *d);
+void xe_eudebug_event_log_write(struct xe_eudebug_event_log *l, struct drm_xe_eudebug_event *e);
+void xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log *l);
+
+struct xe_eudebug_debugger *
+xe_eudebug_debugger_create(int xe, uint64_t flags);
+void xe_eudebug_debugger_destroy(struct xe_eudebug_debugger *d);
+int xe_eudebug_debugger_attach(struct xe_eudebug_debugger *d, pid_t pid);
+void xe_eudebug_debugger_start_worker(struct xe_eudebug_debugger *d);
+void xe_eudebug_debugger_stop_worker(struct xe_eudebug_debugger *d, int timeout_s);
+void xe_eudebug_debugger_dettach(struct xe_eudebug_debugger *d);
+void xe_eudebug_debugger_add_trigger(struct xe_eudebug_debugger *d, int type,
+				     xe_eudebug_trigger_fn fn);
+
+struct xe_eudebug_client *
+xe_eudebug_client_create(xe_eudebug_client_work_fn work, uint64_t flags);
+void xe_eudebug_client_destroy(struct xe_eudebug_client *c);
+void xe_eudebug_client_start(struct xe_eudebug_client *c);
+void xe_eudebug_client_stop(struct xe_eudebug_client *c);
+void xe_eudebug_client_wait_done(struct xe_eudebug_client *c);
+uint64_t xe_eudebug_client_get_seqno(struct xe_eudebug_client *c);
+
+int xe_eudebug_client_open_driver(struct xe_eudebug_client *c);
+void xe_eudebug_client_close_driver(struct xe_eudebug_client *c, int fd);
+uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c, int fd,
+				     uint32_t flags, uint64_t ext);
+void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, int fd, uint32_t vm);
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 5/9] xe/staging/xe_eudebug: test open close events
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (3 preceding siblings ...)
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 4/9] lib/staging/xe_eudebug: introduce eu debug testing framework Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 6/9] xe/staging/xe_eudebug: exercise read_event ioctl Dominik Grzegorzek
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

Introduce basic tests which validate client create/destroy events
sent on xe drm client open/close.

Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
---
 tests/xe/staging/xe_eudebug.c | 89 +++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/tests/xe/staging/xe_eudebug.c b/tests/xe/staging/xe_eudebug.c
index 7202da689..6b97a4851 100644
--- a/tests/xe/staging/xe_eudebug.c
+++ b/tests/xe/staging/xe_eudebug.c
@@ -4,7 +4,68 @@
  */
 
 #include <xe_drm_tmp.h>
+
 #include "igt.h"
+#include "xe/staging/xe_eudebug.h"
+
+static void run_basic_client(struct xe_eudebug_client *c)
+{
+	int fd;
+
+	fd = xe_eudebug_client_open_driver(c);
+	xe_eudebug_client_close_driver(c, fd);
+}
+
+struct session {
+	unsigned int flags;
+	struct xe_eudebug_debugger *d;
+	struct xe_eudebug_client *c;
+};
+
+static struct session *session_create(int fd, xe_eudebug_client_work_fn work, unsigned int flags)
+{
+	struct session *s;
+
+	s = calloc(1, sizeof(*s));
+	igt_assert(s);
+
+	s->c = xe_eudebug_client_create(work, flags);
+	s->d = xe_eudebug_debugger_create(fd, flags);
+
+	return s;
+}
+
+static void session_run(struct session *s)
+{
+	struct xe_eudebug_debugger *debugger = s->d;
+	struct xe_eudebug_client *client = s->c;
+
+	igt_assert_eq(xe_eudebug_debugger_attach(debugger, client->pid), 0);
+
+	xe_eudebug_debugger_start_worker(debugger);
+
+	xe_eudebug_client_start(client);
+	xe_eudebug_client_wait_done(client);
+
+	xe_eudebug_debugger_stop_worker(debugger, 1);
+
+	xe_eudebug_event_log_print(debugger->log, true);
+	xe_eudebug_event_log_print(client->log, true);
+}
+
+static void session_check(struct session *s, bool match_opposite)
+{
+	xe_eudebug_event_log_compare(s->c->log, s->d->log);
+
+	if (match_opposite)
+		xe_eudebug_event_log_match_opposite(s->d->log);
+}
+
+static void session_destroy(struct session *s)
+{
+	xe_eudebug_debugger_destroy(s->d);
+	xe_eudebug_client_destroy(s->c);
+}
 
 static int __debug_connect(int fd, int *debugfd, struct drm_xe_eudebug_connect_param *param)
 {
@@ -114,6 +175,28 @@ static void test_close(int fd)
 	close(debug_fd1);
 }
 
+static void test_basic_sessions(int fd, unsigned int flags, int count)
+{
+	struct session **s;
+	int i;
+
+	s = calloc(count, sizeof(*s));
+
+	igt_assert(s);
+
+	for (i = 0; i < count; i++)
+		s[i] = session_create(fd, run_basic_client, flags);
+
+	for (i = 0; i < count; i++)
+		session_run(s[i]);
+
+	for (i = 0; i < count; i++)
+		session_check(s[i], true);
+
+	for (i = 0; i < count; i++)
+		session_destroy(s[i]);
+}
+
 igt_main
 {
 	int fd;
@@ -128,6 +211,12 @@ igt_main
 	igt_subtest("basic-close")
 		test_close(fd);
 
+	igt_subtest("basic-client")
+		test_basic_sessions(fd, 0, 1);
+
+	igt_subtest("multiple-sessions")
+		test_basic_sessions(fd, 0, 4);
+
 	igt_fixture
 		close(fd);
 }
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 6/9] xe/staging/xe_eudebug: exercise read_event ioctl
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (4 preceding siblings ...)
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 5/9] xe/staging/xe_eudebug: test open close events Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 7/9] xe/staging/xe_eudebug: add vm events sanity check Dominik Grzegorzek
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

Introduce synchronous test, which validates eu debugger read_event
ioctl.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
---
 tests/xe/staging/xe_eudebug.c | 81 +++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/tests/xe/staging/xe_eudebug.c b/tests/xe/staging/xe_eudebug.c
index 6b97a4851..771089179 100644
--- a/tests/xe/staging/xe_eudebug.c
+++ b/tests/xe/staging/xe_eudebug.c
@@ -2,6 +2,7 @@
 /*
  * Copyright © 2023 Intel Corporation
  */
+#include <poll.h>
 
 #include <xe_drm_tmp.h>
 
@@ -67,6 +68,34 @@ static void session_destroy(struct session *s)
 	xe_eudebug_client_destroy(s->c);
 }
 
+static int __read_event(int debugfd, struct drm_xe_eudebug_event *event)
+{
+	int ret;
+
+	ret = igt_ioctl(debugfd, DRM_XE_EUDEBUG_IOCTL_READ_EVENT, event);
+	if (ret < 0)
+		return -errno;
+
+	return ret;
+}
+
+static int poll_event(int fd, int timeout_ms)
+{
+	int ret;
+
+	struct pollfd p = {
+		.fd = fd,
+		.events = POLLIN,
+		.revents = 0,
+	};
+
+	ret = poll(&p, 1, timeout_ms);
+	if (ret == -1)
+		return -errno;
+
+	return ret == 1 && (p.revents & POLLIN);
+}
+
 static int __debug_connect(int fd, int *debugfd, struct drm_xe_eudebug_connect_param *param)
 {
 	int ret = 0;
@@ -175,6 +204,55 @@ static void test_close(int fd)
 	close(debug_fd1);
 }
 
+#define MAX_EVENT_SIZE (32 * 1024)
+static void test_read_event(int fd)
+{
+	struct drm_xe_eudebug_event event = {};
+	struct xe_eudebug_debugger *d;
+	struct xe_eudebug_client *c;
+
+	c = xe_eudebug_client_create(run_basic_client, 0);
+	d = xe_eudebug_debugger_create(fd, 0);
+
+	igt_assert_eq(xe_eudebug_debugger_attach(d, c->pid), 0);
+	igt_assert_eq(poll_event(d->fd, 500), 0);
+
+	event.size = 1;
+	event.type = DRM_XE_EUDEBUG_EVENT_NONE;
+	igt_assert_eq(__read_event(d->fd, &event), -EINVAL);
+
+	event.size = MAX_EVENT_SIZE;
+	event.type = DRM_XE_EUDEBUG_EVENT_NONE;
+	igt_assert_eq(__read_event(d->fd, &event), -EINVAL);
+
+	xe_eudebug_client_start(c);
+
+	igt_assert_eq(poll_event(d->fd, 500), 1);
+	event.type = DRM_XE_EUDEBUG_EVENT_READ;
+	igt_assert_eq(__read_event(d->fd, &event), 0);
+
+	igt_assert_eq(poll_event(d->fd, 500), 1);
+	event.size = MAX_EVENT_SIZE;
+	event.flags = 0;
+	event.type = DRM_XE_EUDEBUG_EVENT_READ;
+	igt_assert_eq(__read_event(d->fd, &event), 0);
+
+	igt_assert_eq(poll_event(d->fd, 500), 0);
+	event.size = MAX_EVENT_SIZE;
+	event.flags = 0;
+	event.type = DRM_XE_EUDEBUG_EVENT_READ;
+	igt_assert_eq(__read_event(d->fd, &event), -ENOENT);
+
+	xe_eudebug_client_wait_done(c);
+	xe_eudebug_client_stop(c);
+
+	igt_assert_eq(poll_event(d->fd, 500), 0);
+	igt_assert_eq(__read_event(d->fd, &event), -ENOENT);
+
+	xe_eudebug_debugger_destroy(d);
+	xe_eudebug_client_destroy(c);
+}
+
 static void test_basic_sessions(int fd, unsigned int flags, int count)
 {
 	struct session **s;
@@ -211,6 +289,9 @@ igt_main
 	igt_subtest("basic-close")
 		test_close(fd);
 
+	igt_subtest("basic-read-event")
+		test_read_event(fd);
+
 	igt_subtest("basic-client")
 		test_basic_sessions(fd, 0, 1);
 
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 7/9] xe/staging/xe_eudebug: add vm events sanity check
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (5 preceding siblings ...)
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 6/9] xe/staging/xe_eudebug: exercise read_event ioctl Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 8/9] xe/staging/xe_eudebug: Race discovery against eudebug attach Dominik Grzegorzek
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

Add basic test validating eudebug vm events.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
---
 tests/xe/staging/xe_eudebug.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/tests/xe/staging/xe_eudebug.c b/tests/xe/staging/xe_eudebug.c
index 771089179..0f81dcd7e 100644
--- a/tests/xe/staging/xe_eudebug.c
+++ b/tests/xe/staging/xe_eudebug.c
@@ -7,13 +7,26 @@
 #include <xe_drm_tmp.h>
 
 #include "igt.h"
+#include "xe/xe_ioctl.h"
 #include "xe/staging/xe_eudebug.h"
 
+#define CREATE_VMS	(1 << 0)
 static void run_basic_client(struct xe_eudebug_client *c)
 {
-	int fd;
+	int fd, i;
 
 	fd = xe_eudebug_client_open_driver(c);
+
+	if (c->flags & CREATE_VMS) {
+		uint32_t vms[igt_fls(DRM_XE_VM_CREATE_ASYNC_BIND_OPS)];
+
+		for (i = 0; (1 << i) <= DRM_XE_VM_CREATE_ASYNC_BIND_OPS; i++)
+			vms[i] = xe_eudebug_client_vm_create(c, fd, 1 << i, 0);
+
+		for (i--; i >= 0; i--)
+			xe_eudebug_client_vm_destroy(c, fd, vms[i]);
+	}
+
 	xe_eudebug_client_close_driver(c, fd);
 }
 
@@ -296,7 +309,10 @@ igt_main
 		test_basic_sessions(fd, 0, 1);
 
 	igt_subtest("multiple-sessions")
-		test_basic_sessions(fd, 0, 4);
+		test_basic_sessions(fd, CREATE_VMS, 4);
+
+	igt_subtest("basic-vms")
+		test_basic_sessions(fd, CREATE_VMS, 1);
 
 	igt_fixture
 		close(fd);
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 8/9] xe/staging/xe_eudebug: Race discovery against eudebug attach.
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (6 preceding siblings ...)
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 7/9] xe/staging/xe_eudebug: add vm events sanity check Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 9/9] xe/staging/xe_eudebug: Add TEST/SUBTEST documentation Dominik Grzegorzek
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

Validate eu debug resource discovery in a pretty cruel way.
Add subtests:

1) discovery-race - spawns N client proccesses, which create
   N+N*N resources each, then it creates M debugger
   threads competing for an access to the client proccess. After
   successful attach, with probability of 0.5 read and assert
   discovered resources, immediately detach otherwise.

2) discovery-empty[|-clients] - same as 1#, but destroy
   resources in flight (explicetly or by closing the client).
   Expect the last discovery not sending any events.

Currently N = 16, M = 4.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
---
 tests/xe/staging/xe_eudebug.c | 271 ++++++++++++++++++++++++++++++++++
 1 file changed, 271 insertions(+)

diff --git a/tests/xe/staging/xe_eudebug.c b/tests/xe/staging/xe_eudebug.c
index 0f81dcd7e..29d4d8926 100644
--- a/tests/xe/staging/xe_eudebug.c
+++ b/tests/xe/staging/xe_eudebug.c
@@ -288,6 +288,268 @@ static void test_basic_sessions(int fd, unsigned int flags, int count)
 		session_destroy(s[i]);
 }
 
+#define RESOURCE_COUNT 16
+#define PRIMARY_THREAD			(1 << 0)
+#define DISCOVERY_CLOSE_CLIENT		(1 << 1)
+#define DISCOVERY_DESTROY_RESOURCES	(1 << 2)
+static void run_discovery_client(struct xe_eudebug_client *c)
+{
+	int fd[RESOURCE_COUNT], i;
+	bool skip_sleep = c->flags & (DISCOVERY_DESTROY_RESOURCES | DISCOVERY_CLOSE_CLIENT);
+
+	srand(getpid());
+
+	for (i = 0; i < RESOURCE_COUNT; i++) {
+		fd[i] = xe_eudebug_client_open_driver(c);
+
+		/*
+		 * Give the debugger a break in event stream after every
+		 * other client, that allows to read discovery and dettach in quiet.
+		 */
+		if (random() % 2 == 0 && !skip_sleep)
+			sleep(1);
+
+		for (int j = 0; j < RESOURCE_COUNT; j++) {
+			uint32_t vm = xe_eudebug_client_vm_create(c, fd[i], 0, 0);
+
+			if (c->flags & DISCOVERY_DESTROY_RESOURCES)
+				xe_eudebug_client_vm_destroy(c, fd[i], vm);
+		}
+
+		if (c->flags & DISCOVERY_CLOSE_CLIENT)
+			xe_eudebug_client_close_driver(c, fd[i]);
+	}
+}
+
+static void *discovery_race_thread(void *data)
+{
+	struct {
+		uint64_t client_handle;
+		int vm_count;
+	} clients[RESOURCE_COUNT];
+	struct session *s = data;
+	struct drm_xe_eudebug_event *e = NULL;
+	int expected = RESOURCE_COUNT * (1 + RESOURCE_COUNT);
+	const int tries = 100;
+	bool done = false;
+	int ret = 0;
+
+	for (int try = 0; try < tries && !done; try++) {
+
+		ret = xe_eudebug_debugger_attach(s->d, s->c->pid);
+
+		if (ret == -EBUSY) {
+			usleep(100000);
+			continue;
+		}
+
+		igt_assert_eq(ret, 0);
+
+		if (random() % 2) {
+			int i = -1;
+			xe_eudebug_debugger_start_worker(s->d);
+			sleep(1);
+			xe_eudebug_debugger_stop_worker(s->d, 1);
+			igt_debug("Resources discovered: %lu\n", s->d->event_count);
+
+			xe_eudebug_for_each_event(e, s->d->log) {
+				if (e->type == DRM_XE_EUDEBUG_EVENT_OPEN) {
+					struct drm_xe_eudebug_event_client *eo = (void *)e;
+
+					if (i >= 0) {
+						igt_assert_eq(clients[i].vm_count,
+							      RESOURCE_COUNT);
+					}
+
+					igt_assert(++i < RESOURCE_COUNT);
+					clients[i].client_handle = eo->client_handle;
+					clients[i].vm_count = 0;
+				}
+
+				if (e->type == DRM_XE_EUDEBUG_EVENT_VM)
+					clients[i].vm_count++;
+			};
+
+			for (int j = 0; j < i; j++)
+				for (int k = 0; k < i; k++) {
+					if (k == j)
+						continue;
+
+					igt_assert_neq(clients[j].client_handle,
+						       clients[k].client_handle);
+				}
+
+			if (s->d->event_count >= expected)
+				done = true;
+		}
+
+		xe_eudebug_debugger_dettach(s->d);
+		s->d->log->head = 0;
+		s->d->event_count = 0;
+	}
+
+	/* Primary thread must read everything */
+	if (s->flags & PRIMARY_THREAD) {
+		while ((ret = xe_eudebug_debugger_attach(s->d, s->c->pid)) == -EBUSY)
+			usleep(100000);
+
+		igt_assert_eq(ret, 0);
+
+		xe_eudebug_debugger_start_worker(s->d);
+		xe_eudebug_client_wait_done(s->c);
+
+		if (READ_ONCE(s->d->event_count) != expected)
+			sleep(5);
+
+		xe_eudebug_debugger_stop_worker(s->d, 1);
+		xe_eudebug_debugger_dettach(s->d);
+	}
+
+	return NULL;
+}
+
+static bool event_equals(struct drm_xe_eudebug_event *a,
+			 struct drm_xe_eudebug_event *b)
+{
+	uint64_t seqno_a = a->seqno;
+	int ret = 0;
+
+	if (a->size != b->size)
+		return 0;
+
+	a->seqno = b->seqno;
+	ret = memcmp(a, b, a->size);
+	a->seqno = seqno_a;
+
+	return ret == 0;
+}
+
+static void test_race_discovery(int fd, unsigned int flags, int clients)
+{
+	const int debuggers_per_client = 4;
+	int count = clients * debuggers_per_client;
+	struct drm_xe_eudebug_event *ef = NULL, *e = NULL;
+	struct session *sessions, *s;
+	struct xe_eudebug_client *c;
+	pthread_t *threads;
+	bool found;
+	int i, j;
+
+	sessions = calloc(count, sizeof(*sessions));
+	threads = calloc(count, sizeof(*threads));
+
+	for (i = 0; i < clients; i++) {
+		c = xe_eudebug_client_create(run_discovery_client, flags);
+		for (j = 0; j < debuggers_per_client; j++) {
+			s = &sessions[i * debuggers_per_client + j];
+			s->c = c;
+			s->d = xe_eudebug_debugger_create(fd, flags);
+			s->flags = flags | (!j ? PRIMARY_THREAD : 0);
+		}
+	}
+
+	for (i = 0; i < count; i++) {
+		if (sessions[i].flags & PRIMARY_THREAD)
+			xe_eudebug_client_start(sessions[i].c);
+
+		pthread_create(&threads[i], NULL, discovery_race_thread, &sessions[i]);
+	}
+
+	for (i = 0; i < count; i++)
+		pthread_join(threads[i], NULL);
+
+	for (i = count - 1; i > 0; i--) {
+		if (sessions[i].flags & PRIMARY_THREAD) {
+			igt_assert_eq(sessions[i].c->seqno-1, sessions[i].d->event_count);
+
+			xe_eudebug_for_each_event(ef, sessions[0].d->log) {
+				found = false;
+				e = NULL;
+				xe_eudebug_for_each_event(e, sessions[i].d->log) {
+					if (event_equals(ef, e)) {
+						igt_assert_f(!found, "Event duplicated"
+								     " in session %d\n", i);
+						found = true;
+					}
+				}
+
+				if (!found)
+					xe_eudebug_event_log_print(sessions[i].d->log, false);
+				igt_assert_f(found, "Missing event in session %d\n", i);
+			}
+			xe_eudebug_client_destroy(sessions[i].c);
+		}
+		xe_eudebug_debugger_destroy(sessions[i].d);
+	}
+}
+
+static void *attach_dettach_thread(void *data)
+{
+	struct session *s = data;
+	const int tries = 100;
+	int ret = 0;
+
+	for (int try = 0; try < tries; try++) {
+
+		ret = xe_eudebug_debugger_attach(s->d, s->c->pid);
+
+		if (ret == -EBUSY) {
+			usleep(100000);
+			continue;
+		}
+
+		igt_assert_eq(ret, 0);
+
+		if (random() % 2 == 0) {
+			xe_eudebug_debugger_start_worker(s->d);
+			xe_eudebug_debugger_stop_worker(s->d, 1);
+		}
+
+		xe_eudebug_debugger_dettach(s->d);
+		s->d->log->head = 0;
+		s->d->event_count = 0;
+	}
+
+	return NULL;
+}
+
+static void test_empty_discovery(int fd, unsigned int flags, int clients)
+{
+	struct session **s;
+	pthread_t *threads;
+	int i, expected = flags & DISCOVERY_CLOSE_CLIENT ? 0 : RESOURCE_COUNT;
+
+	igt_assert(flags & (DISCOVERY_DESTROY_RESOURCES | DISCOVERY_CLOSE_CLIENT));
+
+	s = calloc(clients, sizeof(struct session *));
+	threads = calloc(clients, sizeof(*threads));
+
+	for (i = 0; i < clients; i++)
+		s[i] = session_create(fd, run_discovery_client, flags);
+
+	for (i = 0; i < clients; i++) {
+		xe_eudebug_client_start(s[i]->c);
+
+		pthread_create(&threads[i], NULL, attach_dettach_thread, s[i]);
+	}
+
+	for (i = 0; i < clients; i++)
+		pthread_join(threads[i], NULL);
+
+	for (i = 0; i < clients; i++) {
+		xe_eudebug_client_wait_done(s[i]->c);
+		igt_assert_eq(xe_eudebug_debugger_attach(s[i]->d, s[i]->c->pid), 0);
+
+		xe_eudebug_debugger_start_worker(s[i]->d);
+		xe_eudebug_debugger_stop_worker(s[i]->d, 5);
+		xe_eudebug_debugger_dettach(s[i]->d);
+
+		igt_assert_eq(s[i]->d->event_count, expected);
+
+		session_destroy(s[i]);
+	}
+}
+
 igt_main
 {
 	int fd;
@@ -314,6 +576,15 @@ igt_main
 	igt_subtest("basic-vms")
 		test_basic_sessions(fd, CREATE_VMS, 1);
 
+	igt_subtest("discovery-race")
+		test_race_discovery(fd, 0, 16);
+
+	igt_subtest("discovery-empty")
+		test_empty_discovery(fd, DISCOVERY_CLOSE_CLIENT, 16);
+
+	igt_subtest("discovery-empty-clients")
+		test_empty_discovery(fd, DISCOVERY_DESTROY_RESOURCES, 16);
+
 	igt_fixture
 		close(fd);
 }
-- 
2.34.1

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

* [igt-dev] [PATCH i-g-t 9/9] xe/staging/xe_eudebug: Add TEST/SUBTEST documentation
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (7 preceding siblings ...)
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 8/9] xe/staging/xe_eudebug: Race discovery against eudebug attach Dominik Grzegorzek
@ 2023-05-24 14:29 ` Dominik Grzegorzek
  2023-05-24 16:01 ` [igt-dev] ✓ Fi.CI.BAT: success for Add initial eudebug coverage (rev3) Patchwork
  2023-05-25  4:13 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  10 siblings, 0 replies; 16+ messages in thread
From: Dominik Grzegorzek @ 2023-05-24 14:29 UTC (permalink / raw)
  To: igt-dev

Document xe_eudebug test, to reflect its internal logic.

Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
---
 tests/xe/staging/xe_eudebug.c | 49 +++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/tests/xe/staging/xe_eudebug.c b/tests/xe/staging/xe_eudebug.c
index 29d4d8926..1491fa0aa 100644
--- a/tests/xe/staging/xe_eudebug.c
+++ b/tests/xe/staging/xe_eudebug.c
@@ -2,6 +2,15 @@
 /*
  * Copyright © 2023 Intel Corporation
  */
+
+/**
+ * TEST: Test EU Debugger functionality
+ * Category: Software building block
+ * Sub-category: eu debugger
+ * Test category: functionality test
+ * Run type: BAT
+ */
+
 #include <poll.h>
 
 #include <xe_drm_tmp.h>
@@ -124,6 +133,12 @@ static int __debug_connect(int fd, int *debugfd, struct drm_xe_eudebug_connect_p
 	return ret;
 }
 
+/**
+ * SUBTEST: basic-connect
+ * Description:
+ * 	Exercise XE_EUDEBG_CONNECT ioctl with passing
+ *	valid and invalid params.
+ */
 static void test_connect(int fd)
 {
 	struct drm_xe_eudebug_connect_param param = {};
@@ -194,6 +209,11 @@ static void test_connect(int fd)
 	close(debugfd);
 }
 
+/**
+ * SUBTEST: basic-close
+ * Description:
+ * 	Test whether eudebug can be reattached after closure.
+ */
 static void test_close(int fd)
 {
 	struct drm_xe_eudebug_connect_param param = { 0,  };
@@ -217,6 +237,11 @@ static void test_close(int fd)
 	close(debug_fd1);
 }
 
+/**
+ * SUBTEST: basic-read-event
+ * Description:
+ * 	Synchronously exercise eu debugger event polling and reading.
+ */
 #define MAX_EVENT_SIZE (32 * 1024)
 static void test_read_event(int fd)
 {
@@ -266,6 +291,20 @@ static void test_read_event(int fd)
 	xe_eudebug_client_destroy(c);
 }
 
+/**
+ * SUBTEST: basic-client
+ * Description:
+ * 	Attach the debugger to proccess which opens and closes xe drm client.
+ *
+ * SUBTEST: multiple-sessions
+ * Description:
+ * 	Simultaneusly attach many debuggers to many proccesses.
+ * 	Each proccess opens and closes xe drm client.
+ *
+ * SUBTEST: basic-vms
+ * Description:
+ * 	Attach the debugger to procces which creates and destroys a few vms.
+ */
 static void test_basic_sessions(int fd, unsigned int flags, int count)
 {
 	struct session **s;
@@ -321,6 +360,16 @@ static void run_discovery_client(struct xe_eudebug_client *c)
 	}
 }
 
+/**
+ * SUBTEST: discovery-%s
+ * Description: Race discovery against %arg[1] and the debugger dettach.
+ *
+ * arg[1]:
+ *
+ * @race:		resources creation
+ * @empty:		resources destruction
+ * @empty-clients:	client closure
+ */
 static void *discovery_race_thread(void *data)
 {
 	struct {
-- 
2.34.1

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

* [igt-dev] ✓ Fi.CI.BAT: success for Add initial eudebug coverage (rev3)
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (8 preceding siblings ...)
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 9/9] xe/staging/xe_eudebug: Add TEST/SUBTEST documentation Dominik Grzegorzek
@ 2023-05-24 16:01 ` Patchwork
  2023-05-25  4:13 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  10 siblings, 0 replies; 16+ messages in thread
From: Patchwork @ 2023-05-24 16:01 UTC (permalink / raw)
  To: Grzegorzek, Dominik; +Cc: igt-dev

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

== Series Details ==

Series: Add initial eudebug coverage (rev3)
URL   : https://patchwork.freedesktop.org/series/117823/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13185 -> IGTPW_9030
====================================================

Summary
-------

  **WARNING**

  Minor unknown changes coming with IGTPW_9030 need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_9030, please notify your bug team 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_9030/index.html

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

  Additional (1): fi-skl-guc 
  Missing    (2): fi-kbl-soraka fi-snb-2520m 

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

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

### IGT changes ###

#### Warnings ####

  * igt@kms_psr@primary_mmap_gtt:
    - bat-rplp-1:         [SKIP][1] ([i915#1072]) -> [ABORT][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/bat-rplp-1/igt@kms_psr@primary_mmap_gtt.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/bat-rplp-1/igt@kms_psr@primary_mmap_gtt.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@i915_selftest@live@requests:
    - {bat-mtlp-6}:       [PASS][3] -> [ABORT][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/bat-mtlp-6/igt@i915_selftest@live@requests.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/bat-mtlp-6/igt@i915_selftest@live@requests.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_lmem_swapping@basic:
    - fi-skl-guc:         NOTRUN -> [SKIP][5] ([fdo#109271] / [i915#4613]) +3 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/fi-skl-guc/igt@gem_lmem_swapping@basic.html

  * igt@i915_selftest@live@gt_heartbeat:
    - fi-kbl-7567u:       [PASS][6] -> [DMESG-FAIL][7] ([i915#5334] / [i915#7872])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/fi-kbl-7567u/igt@i915_selftest@live@gt_heartbeat.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/fi-kbl-7567u/igt@i915_selftest@live@gt_heartbeat.html

  * igt@i915_selftest@live@mman:
    - bat-rpls-2:         [PASS][8] -> [TIMEOUT][9] ([i915#6794] / [i915#7392])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/bat-rpls-2/igt@i915_selftest@live@mman.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/bat-rpls-2/igt@i915_selftest@live@mman.html

  * igt@i915_suspend@basic-s2idle-without-i915:
    - bat-rpls-2:         NOTRUN -> [ABORT][10] ([i915#6687])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/bat-rpls-2/igt@i915_suspend@basic-s2idle-without-i915.html

  * igt@kms_chamelium_hpd@common-hpd-after-suspend:
    - fi-skl-guc:         NOTRUN -> [SKIP][11] ([fdo#109271]) +10 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/fi-skl-guc/igt@kms_chamelium_hpd@common-hpd-after-suspend.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-skl-guc:         NOTRUN -> [SKIP][12] ([IGT#6] / [fdo#109271]) +6 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/fi-skl-guc/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence@pipe-c-dp-1:
    - bat-dg2-8:          [PASS][13] -> [FAIL][14] ([i915#7932]) +1 similar issue
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/bat-dg2-8/igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence@pipe-c-dp-1.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/bat-dg2-8/igt@kms_pipe_crc_basic@nonblocking-crc-frame-sequence@pipe-c-dp-1.html

  * igt@kms_pipe_crc_basic@read-crc:
    - bat-adlp-9:         NOTRUN -> [SKIP][15] ([i915#3546]) +1 similar issue
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/bat-adlp-9/igt@kms_pipe_crc_basic@read-crc.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-skl-guc:         NOTRUN -> [SKIP][16] ([IGT#6] / [fdo#109271] / [i915#4579])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/fi-skl-guc/igt@kms_setmode@basic-clone-single-crtc.html

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

  [IGT#6]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/6
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#3546]: https://gitlab.freedesktop.org/drm/intel/issues/3546
  [i915#4579]: https://gitlab.freedesktop.org/drm/intel/issues/4579
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#6687]: https://gitlab.freedesktop.org/drm/intel/issues/6687
  [i915#6794]: https://gitlab.freedesktop.org/drm/intel/issues/6794
  [i915#7392]: https://gitlab.freedesktop.org/drm/intel/issues/7392
  [i915#7872]: https://gitlab.freedesktop.org/drm/intel/issues/7872
  [i915#7932]: https://gitlab.freedesktop.org/drm/intel/issues/7932
  [i915#8497]: https://gitlab.freedesktop.org/drm/intel/issues/8497


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

  * CI: CI-20190529 -> None
  * IGT: IGT_7302 -> IGTPW_9030

  CI-20190529: 20190529
  CI_DRM_13185: e9b0234536d53adca81a81bc1f58611a0f5209d1 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_9030: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/index.html
  IGT_7302: de4b71f2c13f6fdcae15a4c3fac7fbe5f5737685 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git

== Logs ==

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

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

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

* [igt-dev] ✓ Fi.CI.IGT: success for Add initial eudebug coverage (rev3)
  2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
                   ` (9 preceding siblings ...)
  2023-05-24 16:01 ` [igt-dev] ✓ Fi.CI.BAT: success for Add initial eudebug coverage (rev3) Patchwork
@ 2023-05-25  4:13 ` Patchwork
  10 siblings, 0 replies; 16+ messages in thread
From: Patchwork @ 2023-05-25  4:13 UTC (permalink / raw)
  To: Grzegorzek, Dominik; +Cc: igt-dev

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

== Series Details ==

Series: Add initial eudebug coverage (rev3)
URL   : https://patchwork.freedesktop.org/series/117823/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_13185_full -> IGTPW_9030_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

Participating hosts (7 -> 8)
------------------------------

  Additional (1): shard-rkl0 

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_barrier_race@remote-request@rcs0:
    - shard-glk:          [PASS][1] -> [ABORT][2] ([i915#7461] / [i915#8211])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-glk6/igt@gem_barrier_race@remote-request@rcs0.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-glk6/igt@gem_barrier_race@remote-request@rcs0.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-glk:          [PASS][3] -> [FAIL][4] ([i915#2842])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-glk4/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-glk9/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_render_copy@x-tiled-to-vebox-yf-tiled:
    - shard-apl:          NOTRUN -> [SKIP][5] ([fdo#109271]) +8 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-apl7/igt@gem_render_copy@x-tiled-to-vebox-yf-tiled.html

  * igt@i915_selftest@live@gt_heartbeat:
    - shard-apl:          [PASS][6] -> [DMESG-FAIL][7] ([i915#5334])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-apl6/igt@i915_selftest@live@gt_heartbeat.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-apl3/igt@i915_selftest@live@gt_heartbeat.html

  * igt@kms_flip@2x-nonexisting-fb-interruptible:
    - shard-apl:          NOTRUN -> [SKIP][8] ([IGT#6] / [fdo#109271]) +6 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-apl1/igt@kms_flip@2x-nonexisting-fb-interruptible.html

  * igt@kms_flip@2x-plain-flip-fb-recreate:
    - shard-snb:          NOTRUN -> [SKIP][9] ([fdo#109271]) +20 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-snb2/igt@kms_flip@2x-plain-flip-fb-recreate.html

  * igt@kms_plane_scaling@plane-downscale-with-rotation-factor-0-75@pipe-b-hdmi-a-1:
    - shard-snb:          NOTRUN -> [SKIP][10] ([fdo#109271] / [i915#4579]) +13 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-snb1/igt@kms_plane_scaling@plane-downscale-with-rotation-factor-0-75@pipe-b-hdmi-a-1.html

  * igt@kms_scaling_modes@scaling-mode-center:
    - shard-apl:          NOTRUN -> [SKIP][11] ([fdo#109271] / [i915#4579])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-apl6/igt@kms_scaling_modes@scaling-mode-center.html

  
#### Possible fixes ####

  * igt@gem_ppgtt@blt-vs-render-ctxn:
    - shard-snb:          [FAIL][12] ([i915#4998] / [i915#8295]) -> [PASS][13]
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-snb6/igt@gem_ppgtt@blt-vs-render-ctxn.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-snb1/igt@gem_ppgtt@blt-vs-render-ctxn.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-apl:          [ABORT][14] ([i915#5566]) -> [PASS][15]
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-apl6/igt@gen9_exec_parse@allowed-all.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-apl6/igt@gen9_exec_parse@allowed-all.html

  * igt@i915_pm_rc6_residency@rc6-idle@vecs0:
    - {shard-dg1}:        [FAIL][16] ([i915#3591]) -> [PASS][17]
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-dg1-16/igt@i915_pm_rc6_residency@rc6-idle@vecs0.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-dg1-16/igt@i915_pm_rc6_residency@rc6-idle@vecs0.html

  * igt@i915_pm_rpm@modeset-lpsp:
    - {shard-rkl}:        [SKIP][18] ([i915#1397]) -> [PASS][19]
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-rkl-4/igt@i915_pm_rpm@modeset-lpsp.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-rkl-7/igt@i915_pm_rpm@modeset-lpsp.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-apl:          [FAIL][20] ([IGT#6] / [i915#2346]) -> [PASS][21]
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-apl3/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-apl3/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-glk:          [FAIL][22] ([IGT#6] / [i915#2346]) -> [PASS][23]
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-glk3/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-glk7/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-apl:          [FAIL][24] ([IGT#6] / [i915#4767]) -> [PASS][25]
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-apl6/igt@kms_fbcon_fbt@fbc-suspend.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-apl4/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_flip@plain-flip-ts-check@b-hdmi-a1:
    - shard-glk:          [FAIL][26] ([i915#2122]) -> [PASS][27]
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-glk5/igt@kms_flip@plain-flip-ts-check@b-hdmi-a1.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-glk1/igt@kms_flip@plain-flip-ts-check@b-hdmi-a1.html

  * igt@kms_vblank@pipe-c-ts-continuation-suspend:
    - {shard-tglu}:       [ABORT][28] ([i915#5122] / [i915#8213]) -> [PASS][29]
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-tglu-7/igt@kms_vblank@pipe-c-ts-continuation-suspend.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-tglu-2/igt@kms_vblank@pipe-c-ts-continuation-suspend.html

  * igt@perf_pmu@all-busy-idle-check-all:
    - {shard-dg1}:        [FAIL][30] ([i915#5234]) -> [PASS][31]
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13185/shard-dg1-18/igt@perf_pmu@all-busy-idle-check-all.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/shard-dg1-18/igt@perf_pmu@all-busy-idle-check-all.html

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

  [IGT#6]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/6
  [fdo#103375]: https://bugs.freedesktop.org/show_bug.cgi?id=103375
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
  [fdo#109506]: https://bugs.freedesktop.org/show_bug.cgi?id=109506
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
  [fdo#110723]: https://bugs.freedesktop.org/show_bug.cgi?id=110723
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
  [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
  [fdo#111644]: https://bugs.freedesktop.org/show_bug.cgi?id=111644
  [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1397]: https://gitlab.freedesktop.org/drm/intel/issues/1397
  [i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
  [i915#1839]: https://gitlab.freedesktop.org/drm/intel/issues/1839
  [i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2527]: https://gitlab.freedesktop.org/drm/intel/issues/2527
  [i915#2575]: https://gitlab.freedesktop.org/drm/intel/issues/2575
  [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
  [i915#2658]: https://gitlab.freedesktop.org/drm/intel/issues/2658
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#2705]: https://gitlab.freedesktop.org/drm/intel/issues/2705
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
  [i915#3023]: https://gitlab.freedesktop.org/drm/intel/issues/3023
  [i915#3116]: https://gitlab.freedesktop.org/drm/intel/issues/3116
  [i915#315]: https://gitlab.freedesktop.org/drm/intel/issues/315
  [i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
  [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3299]: https://gitlab.freedesktop.org/drm/intel/issues/3299
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3591]: https://gitlab.freedesktop.org/drm/intel/issues/3591
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
  [i915#3689]: https://gitlab.freedesktop.org/drm/intel/issues/3689
  [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
  [i915#3886]: https://gitlab.freedesktop.org/drm/intel/issues/3886
  [i915#3955]: https://gitlab.freedesktop.org/drm/intel/issues/3955
  [i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
  [i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
  [i915#426]: https://gitlab.freedesktop.org/drm/intel/issues/426
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#4579]: https://gitlab.freedesktop.org/drm/intel/issues/4579
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4767]: https://gitlab.freedesktop.org/drm/intel/issues/4767
  [i915#4998]: https://gitlab.freedesktop.org/drm/intel/issues/4998
  [i915#5122]: https://gitlab.freedesktop.org/drm/intel/issues/5122
  [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
  [i915#5234]: https://gitlab.freedesktop.org/drm/intel/issues/5234
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5325]: https://gitlab.freedesktop.org/drm/intel/issues/5325
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
  [i915#5493]: https://gitlab.freedesktop.org/drm/intel/issues/5493
  [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#6768]: https://gitlab.freedesktop.org/drm/intel/issues/6768
  [i915#7461]: https://gitlab.freedesktop.org/drm/intel/issues/7461
  [i915#7582]: https://gitlab.freedesktop.org/drm/intel/issues/7582
  [i915#7701]: https://gitlab.freedesktop.org/drm/intel/issues/7701
  [i915#7711]: https://gitlab.freedesktop.org/drm/intel/issues/7711
  [i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
  [i915#7975]: https://gitlab.freedesktop.org/drm/intel/issues/7975
  [i915#8211]: https://gitlab.freedesktop.org/drm/intel/issues/8211
  [i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
  [i915#8292]: https://gitlab.freedesktop.org/drm/intel/issues/8292
  [i915#8295]: https://gitlab.freedesktop.org/drm/intel/issues/8295
  [i915#8304]: https://gitlab.freedesktop.org/drm/intel/issues/8304
  [i915#8311]: https://gitlab.freedesktop.org/drm/intel/issues/8311
  [i915#8398]: https://gitlab.freedesktop.org/drm/intel/issues/8398
  [i915#8516]: https://gitlab.freedesktop.org/drm/intel/issues/8516


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

  * CI: CI-20190529 -> None
  * IGT: IGT_7302 -> IGTPW_9030
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_13185: e9b0234536d53adca81a81bc1f58611a0f5209d1 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_9030: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9030/index.html
  IGT_7302: de4b71f2c13f6fdcae15a4c3fac7fbe5f5737685 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

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

* Re: [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers Dominik Grzegorzek
@ 2023-05-26 10:37   ` Zbigniew Kempczyński
  2023-05-26 10:57     ` Grzegorzek, Dominik
  0 siblings, 1 reply; 16+ messages in thread
From: Zbigniew Kempczyński @ 2023-05-26 10:37 UTC (permalink / raw)
  To: Dominik Grzegorzek; +Cc: igt-dev

On Wed, May 24, 2023 at 04:29:23PM +0200, Dominik Grzegorzek wrote:
> Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
> ---
>  include/drm-uapi/xe_drm_tmp.h | 76 +++++++++++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
>  create mode 100644 include/drm-uapi/xe_drm_tmp.h
> 
> diff --git a/include/drm-uapi/xe_drm_tmp.h b/include/drm-uapi/xe_drm_tmp.h
> new file mode 100644
> index 000000000..9829cd724
> --- /dev/null
> +++ b/include/drm-uapi/xe_drm_tmp.h

Maybe xe_drm_local.h or xe_drm_staging.h? tmp looks weird imo.

--
Zbigniew


> @@ -0,0 +1,76 @@
> +#ifndef _UAPI_XE_DRM_TMP_H_
> +#define _UAPI_XE_DRM_TMP_H_
> +
> +#include "xe_drm.h"
> +
> +#if defined(__cplusplus)
> +extern "C" {
> +#endif
> +
> +#define DRM_XE_EUDEBUG_CONNECT			0x5f
> +
> +#define DRM_IOCTL_XE_EUDEBUG_CONNECT		DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EUDEBUG_CONNECT, struct drm_xe_eudebug_connect_param)
> +
> +/**
> + * Do a eudebug event read for a debugger connection.
> + *
> + * This ioctl is available in debug version 1.
> + */
> +#define DRM_XE_EUDEBUG_IOCTL_READ_EVENT _IO('j', 0x0)
> +
> +/* XXX: Document events to match their internal counterparts when moved to xe_drm.h */
> +struct drm_xe_eudebug_event {
> +	struct xe_user_extension ext;
> +
> +	__u32 type;
> +#define DRM_XE_EUDEBUG_EVENT_NONE     0
> +#define DRM_XE_EUDEBUG_EVENT_READ     1
> +#define DRM_XE_EUDEBUG_EVENT_OPEN     2
> +#define DRM_XE_EUDEBUG_EVENT_VM	      3
> +#define DRM_XE_EUDEBUG_EVENT_MAX_EVENT DRM_XE_EUDEBUG_EVENT_VM
> +
> +	__u32 flags;
> +#define DRM_XE_EUDEBUG_EVENT_CREATE	(1 << 0)
> +#define DRM_XE_EUDEBUG_EVENT_DESTROY	(1 << 1)
> +#define DRM_XE_EUDEBUG_EVENT_STATE_CHANGE (1 << 2)
> +
> +	__u64 seqno;
> +	__u64 size;
> +} __attribute__((packed));
> +
> +struct drm_xe_eudebug_event_client {
> +	struct drm_xe_eudebug_event base; /* .flags = CREATE/DESTROY */
> +
> +	__u64 client_handle; /* This is unique per debug connection */
> +} __attribute__((packed));
> +
> +struct drm_xe_eudebug_event_vm {
> +	struct drm_xe_eudebug_event base;
> +
> +	__u64 client_handle;
> +	__u64 vm_handle;
> +} __attribute__((packed));
> +
> +/*
> + * Debugger ABI (ioctl and events) Version History:
> + * 0 - No debugger available
> + * 1 - Initial version
> + */
> +#define DRM_XE_EUDEBUG_VERSION 1
> +
> +struct drm_xe_eudebug_connect_param {
> +	struct xe_user_extension ext;
> +
> +	__u64 pid; /* input: Target process ID */
> +	__u32 flags;
> +
> +	__u32 version; /* output: current ABI (ioctl / events) version */
> +	__u64 events;  /* input: event types to subscribe to */
> +	__u64 extensions; /* MBZ */
> +};
> +
> +#if defined(__cplusplus)
> +}
> +#endif
> +
> +#endif /* _UAPI_XE_DRM_TMP_H_ */
> -- 
> 2.34.1
> 

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

* Re: [igt-dev] [PATCH i-g-t 2/9] meson: Introduce xe_staging build option
  2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 2/9] meson: Introduce xe_staging build option Dominik Grzegorzek
@ 2023-05-26 10:51   ` Zbigniew Kempczyński
  2023-05-26 10:59     ` Grzegorzek, Dominik
  0 siblings, 1 reply; 16+ messages in thread
From: Zbigniew Kempczyński @ 2023-05-26 10:51 UTC (permalink / raw)
  To: Dominik Grzegorzek; +Cc: igt-dev

On Wed, May 24, 2023 at 04:29:24PM +0200, Dominik Grzegorzek wrote:
> There are some major features, which in a current state cannot be merged
> upstream. A good example here in an EU debugger, which does not
> meet the requirement of having an opensourced client. While those
> features are in the development we need a way of providing them
> validation. So introduce xe_staging build option under which
> we can keep tests of features that are under haevy development and not
> yet accepted upstream or not yet completed.
> 
> Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> ---
>  meson.build       |  1 +
>  meson_options.txt |  5 +++++
>  tests/meson.build | 16 ++++++++++++++++
>  3 files changed, 22 insertions(+)
> 
> diff --git a/meson.build b/meson.build
> index 1c872cc9c..ae2206d6e 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -86,6 +86,7 @@ build_chamelium = get_option('chamelium')
>  build_docs = get_option('docs')
>  build_tests = not get_option('tests').disabled()
>  build_xe = not get_option('xe_driver').disabled()
> +build_xe_staging = not get_option('xe_staging').disabled()
>  with_libdrm = get_option('libdrm_drivers')
>  
>  build_info = ['Build type: ' + get_option('buildtype')]
> diff --git a/meson_options.txt b/meson_options.txt
> index 7b5a818cb..46ee91fe6 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -46,6 +46,11 @@ option('xe_driver',
>         type : 'feature',
>         description : 'Build tests for Xe driver (experimental)')
>  
> +option('xe_staging',
> +       type : 'feature',
> +       value : 'disabled',
> +       description : 'Build tests for Xe features that cannot be upstreamed yet (experimental)')
> +
>  option('libdrm_drivers',
>         type : 'array',
>         value : ['auto'],
> diff --git a/tests/meson.build b/tests/meson.build
> index 38f080f7c..8c7055ed9 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -269,6 +269,9 @@ xe_progs = [
>  	'xe_waitfence',
>  ]
>  
> +xe_staging_progs = [
> +]
> +
>  msm_progs = [
>  	'msm_mapping',
>  	'msm_recovery',
> @@ -330,6 +333,19 @@ if build_xe
>  	build_info += 'Xe **experimental** tests enabled.'
>  endif

I got spurious information on 'mesoning':

Message: Xe **experimental** tests enabled.

Configuration looks:

$ meson configure | grep staging
  xe_staging                     disabled                         [enabled, disabled, auto]        Build tests for Xe features that cannot be upstreamed yet 

--
Zbigniew

>  
> +if build_xe_staging
> +        foreach prog : xe_staging_progs
> +		test_executables += executable(prog,
> +		           join_paths('xe/staging', prog + '.c'),
> +			   dependencies : test_deps,
> +			   install_dir : libexecdir,
> +			   install_rpath : libexecdir_rpathdir,
> +			   install : true)
> +		test_list += prog
> +	endforeach
> +	build_info += 'Work in progress tests enabled.'
> +endif
> +
>  foreach prog : msm_progs
>  	test_executables += executable(prog, join_paths('msm', prog + '.c'),
>  				       dependencies : test_deps,
> -- 
> 2.34.1
> 

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

* Re: [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers
  2023-05-26 10:37   ` Zbigniew Kempczyński
@ 2023-05-26 10:57     ` Grzegorzek, Dominik
  0 siblings, 0 replies; 16+ messages in thread
From: Grzegorzek, Dominik @ 2023-05-26 10:57 UTC (permalink / raw)
  To: Kempczynski, Zbigniew; +Cc: igt-dev@lists.freedesktop.org

On Fri, 2023-05-26 at 12:37 +0200, Zbigniew Kempczyński wrote:
> On Wed, May 24, 2023 at 04:29:23PM +0200, Dominik Grzegorzek wrote:
> > Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
> > ---
> >  include/drm-uapi/xe_drm_tmp.h | 76 +++++++++++++++++++++++++++++++++++
> >  1 file changed, 76 insertions(+)
> >  create mode 100644 include/drm-uapi/xe_drm_tmp.h
> > 
> > diff --git a/include/drm-uapi/xe_drm_tmp.h b/include/drm-uapi/xe_drm_tmp.h
> > new file mode 100644
> > index 000000000..9829cd724
> > --- /dev/null
> > +++ b/include/drm-uapi/xe_drm_tmp.h
> 
> Maybe xe_drm_local.h or xe_drm_staging.h? tmp looks weird imo.

I do not like the name too, just took the exact file from KMD rfc. Will talk with Mika
about renaming it to xe_drm_staging. Ta!
> 
> --
> Zbigniew
> 
> 
> > @@ -0,0 +1,76 @@
> > +#ifndef _UAPI_XE_DRM_TMP_H_
> > +#define _UAPI_XE_DRM_TMP_H_
> > +
> > +#include "xe_drm.h"
> > +
> > +#if defined(__cplusplus)
> > +extern "C" {
> > +#endif
> > +
> > +#define DRM_XE_EUDEBUG_CONNECT			0x5f
> > +
> > +#define DRM_IOCTL_XE_EUDEBUG_CONNECT		DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EUDEBUG_CONNECT, struct drm_xe_eudebug_connect_param)
> > +
> > +/**
> > + * Do a eudebug event read for a debugger connection.
> > + *
> > + * This ioctl is available in debug version 1.
> > + */
> > +#define DRM_XE_EUDEBUG_IOCTL_READ_EVENT _IO('j', 0x0)
> > +
> > +/* XXX: Document events to match their internal counterparts when moved to xe_drm.h */
> > +struct drm_xe_eudebug_event {
> > +	struct xe_user_extension ext;
> > +
> > +	__u32 type;
> > +#define DRM_XE_EUDEBUG_EVENT_NONE     0
> > +#define DRM_XE_EUDEBUG_EVENT_READ     1
> > +#define DRM_XE_EUDEBUG_EVENT_OPEN     2
> > +#define DRM_XE_EUDEBUG_EVENT_VM	      3
> > +#define DRM_XE_EUDEBUG_EVENT_MAX_EVENT DRM_XE_EUDEBUG_EVENT_VM
> > +
> > +	__u32 flags;
> > +#define DRM_XE_EUDEBUG_EVENT_CREATE	(1 << 0)
> > +#define DRM_XE_EUDEBUG_EVENT_DESTROY	(1 << 1)
> > +#define DRM_XE_EUDEBUG_EVENT_STATE_CHANGE (1 << 2)
> > +
> > +	__u64 seqno;
> > +	__u64 size;
> > +} __attribute__((packed));
> > +
> > +struct drm_xe_eudebug_event_client {
> > +	struct drm_xe_eudebug_event base; /* .flags = CREATE/DESTROY */
> > +
> > +	__u64 client_handle; /* This is unique per debug connection */
> > +} __attribute__((packed));
> > +
> > +struct drm_xe_eudebug_event_vm {
> > +	struct drm_xe_eudebug_event base;
> > +
> > +	__u64 client_handle;
> > +	__u64 vm_handle;
> > +} __attribute__((packed));
> > +
> > +/*
> > + * Debugger ABI (ioctl and events) Version History:
> > + * 0 - No debugger available
> > + * 1 - Initial version
> > + */
> > +#define DRM_XE_EUDEBUG_VERSION 1
> > +
> > +struct drm_xe_eudebug_connect_param {
> > +	struct xe_user_extension ext;
> > +
> > +	__u64 pid; /* input: Target process ID */
> > +	__u32 flags;
> > +
> > +	__u32 version; /* output: current ABI (ioctl / events) version */
> > +	__u64 events;  /* input: event types to subscribe to */
> > +	__u64 extensions; /* MBZ */
> > +};
> > +
> > +#if defined(__cplusplus)
> > +}
> > +#endif
> > +
> > +#endif /* _UAPI_XE_DRM_TMP_H_ */
> > -- 
> > 2.34.1
> > 


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

* Re: [igt-dev] [PATCH i-g-t 2/9] meson: Introduce xe_staging build option
  2023-05-26 10:51   ` Zbigniew Kempczyński
@ 2023-05-26 10:59     ` Grzegorzek, Dominik
  0 siblings, 0 replies; 16+ messages in thread
From: Grzegorzek, Dominik @ 2023-05-26 10:59 UTC (permalink / raw)
  To: Kempczynski, Zbigniew; +Cc: igt-dev@lists.freedesktop.org

On Fri, 2023-05-26 at 12:51 +0200, Zbigniew Kempczyński wrote:
> On Wed, May 24, 2023 at 04:29:24PM +0200, Dominik Grzegorzek wrote:
> > There are some major features, which in a current state cannot be merged
> > upstream. A good example here in an EU debugger, which does not
> > meet the requirement of having an opensourced client. While those
> > features are in the development we need a way of providing them
> > validation. So introduce xe_staging build option under which
> > we can keep tests of features that are under haevy development and not
> > yet accepted upstream or not yet completed.
> > 
> > Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@intel.com>
> > Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> > ---
> >  meson.build       |  1 +
> >  meson_options.txt |  5 +++++
> >  tests/meson.build | 16 ++++++++++++++++
> >  3 files changed, 22 insertions(+)
> > 
> > diff --git a/meson.build b/meson.build
> > index 1c872cc9c..ae2206d6e 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -86,6 +86,7 @@ build_chamelium = get_option('chamelium')
> >  build_docs = get_option('docs')
> >  build_tests = not get_option('tests').disabled()
> >  build_xe = not get_option('xe_driver').disabled()
> > +build_xe_staging = not get_option('xe_staging').disabled()
> >  with_libdrm = get_option('libdrm_drivers')
> >  
> >  build_info = ['Build type: ' + get_option('buildtype')]
> > diff --git a/meson_options.txt b/meson_options.txt
> > index 7b5a818cb..46ee91fe6 100644
> > --- a/meson_options.txt
> > +++ b/meson_options.txt
> > @@ -46,6 +46,11 @@ option('xe_driver',
> >         type : 'feature',
> >         description : 'Build tests for Xe driver (experimental)')
> >  
> > +option('xe_staging',
> > +       type : 'feature',
> > +       value : 'disabled',
> > +       description : 'Build tests for Xe features that cannot be upstreamed yet (experimental)')
> > +
> >  option('libdrm_drivers',
> >         type : 'array',
> >         value : ['auto'],
> > diff --git a/tests/meson.build b/tests/meson.build
> > index 38f080f7c..8c7055ed9 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -269,6 +269,9 @@ xe_progs = [
> >  	'xe_waitfence',
> >  ]
> >  
> > +xe_staging_progs = [
> > +]
> > +
> >  msm_progs = [
> >  	'msm_mapping',
> >  	'msm_recovery',
> > @@ -330,6 +333,19 @@ if build_xe
> >  	build_info += 'Xe **experimental** tests enabled.'
> >  endif
> 
> I got spurious information on 'mesoning':
> 
> Message: Xe **experimental** tests enabled.
> 
> Configuration looks:
> 
> $ meson configure | grep staging
>   xe_staging                     disabled                         [enabled, disabled, auto]        Build tests for Xe features that cannot be upstreamed yet 
> 
> --
> Zbigniew
The message you pointed, comes from xe_driver param. 
If xe_staging is enabled we add 'Work in progress tests enabled.' to that info log.
As I'm looking at it now it could be just "XE staging tests enabled.", will change that!

Regards, 
Dominik
> 
> >  
> > +if build_xe_staging
> > +        foreach prog : xe_staging_progs
> > +		test_executables += executable(prog,
> > +		           join_paths('xe/staging', prog + '.c'),
> > +			   dependencies : test_deps,
> > +			   install_dir : libexecdir,
> > +			   install_rpath : libexecdir_rpathdir,
> > +			   install : true)
> > +		test_list += prog
> > +	endforeach
> > +	build_info += 'Work in progress tests enabled.'
> > +endif
> > +
> >  foreach prog : msm_progs
> >  	test_executables += executable(prog, join_paths('msm', prog + '.c'),
> >  				       dependencies : test_deps,
> > -- 
> > 2.34.1
> > 


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

end of thread, other threads:[~2023-05-26 10:59 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-24 14:29 [igt-dev] [RFC v2 i-g-t 0/9] Add initial eudebug coverage Dominik Grzegorzek
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 1/9] xe: sync uapi headers Dominik Grzegorzek
2023-05-26 10:37   ` Zbigniew Kempczyński
2023-05-26 10:57     ` Grzegorzek, Dominik
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 2/9] meson: Introduce xe_staging build option Dominik Grzegorzek
2023-05-26 10:51   ` Zbigniew Kempczyński
2023-05-26 10:59     ` Grzegorzek, Dominik
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 3/9] xe/staging/xe_eudebug: test eudebug connection Dominik Grzegorzek
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 4/9] lib/staging/xe_eudebug: introduce eu debug testing framework Dominik Grzegorzek
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 5/9] xe/staging/xe_eudebug: test open close events Dominik Grzegorzek
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 6/9] xe/staging/xe_eudebug: exercise read_event ioctl Dominik Grzegorzek
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 7/9] xe/staging/xe_eudebug: add vm events sanity check Dominik Grzegorzek
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 8/9] xe/staging/xe_eudebug: Race discovery against eudebug attach Dominik Grzegorzek
2023-05-24 14:29 ` [igt-dev] [PATCH i-g-t 9/9] xe/staging/xe_eudebug: Add TEST/SUBTEST documentation Dominik Grzegorzek
2023-05-24 16:01 ` [igt-dev] ✓ Fi.CI.BAT: success for Add initial eudebug coverage (rev3) Patchwork
2023-05-25  4:13 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork

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