[PATCH i-g-t v2 18/66] tests/xe_eudebug: Add vm open/pread/pwrite basic tests

Piatkowski, Dominik Karol dominik.karol.piatkowski at intel.com
Thu Aug 1 12:20:50 UTC 2024


Comment below.

Thanks,
Dominik Karol

> -----Original Message-----
> From: Manszewski, Christoph <christoph.manszewski at intel.com>
> Sent: Tuesday, July 30, 2024 1:45 PM
> To: igt-dev at lists.freedesktop.org
> Cc: Kempczynski, Zbigniew <zbigniew.kempczynski at intel.com>; Kamil
> Konieczny <kamil.konieczny at linux.intel.com>; Grzegorzek, Dominik
> <dominik.grzegorzek at intel.com>; Patelczyk, Maciej
> <maciej.patelczyk at intel.com>; Piatkowski, Dominik Karol
> <dominik.karol.piatkowski at intel.com>; Sikora, Pawel
> <pawel.sikora at intel.com>; Hajda, Andrzej <andrzej.hajda at intel.com>;
> Kolanupaka Naveena <kolanupaka.naveena at intel.com>; Kuoppala, Mika
> <mika.kuoppala at intel.com>; Mun, Gwan-gyeong <gwan-
> gyeong.mun at intel.com>
> Subject: [PATCH i-g-t v2 18/66] tests/xe_eudebug: Add vm
> open/pread/pwrite basic tests
> 
> From: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> 
> Add basic tests for opening, writing and reading into client's vm.
> 
> Signed-off-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Cc: Dominik Grzegorzek <dominik.grzegorzek at intel.com>
> ---
>  tests/intel/xe_eudebug.c | 276
> +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 276 insertions(+)
> 
> diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c index
> 9497e73e9..5080fdf5b 100644
> --- a/tests/intel/xe_eudebug.c
> +++ b/tests/intel/xe_eudebug.c
> @@ -16,9 +16,139 @@
>  #include <sys/ioctl.h>
> 
>  #include "igt.h"
> +#include "intel_pat.h"
> +#include "lib/igt_syncobj.h"
>  #include "xe/xe_eudebug.h"
> +#include "xe/xe_ioctl.h"
>  #include "xe/xe_query.h"
> 
> +#define BO_ADDR 0x1a0000
> +#define BO_ITEMS 4096
> +#define MIN_BO_SIZE (BO_ITEMS * sizeof(uint64_t))
> +
> +struct bind_list {
> +	int fd;
> +	uint32_t vm;
> +	uint32_t *bo;
> +	struct drm_xe_vm_bind_op *bind_ops;
> +	unsigned int n;
> +};
> +
> +static void bo_prime(int fd, uint32_t bo, const uint64_t addr, const
> +uint64_t size) {
> +	uint64_t *d;
> +	uint64_t i;
> +
> +	d = xe_bo_map(fd, bo, size);
> +	igt_assert(d);
> +
> +	for (i = 0; i < size/sizeof(*d); i++)
> +		d[i] = addr + i;
> +
> +	munmap(d, size);
> +}
> +
> +static void bo_check(int fd, uint32_t bo, const uint64_t addr, const
> +uint64_t size) {
> +	uint64_t *d;
> +	uint64_t i;
> +
> +	d = xe_bo_map(fd, bo, size);
> +	igt_assert(d);
> +
> +	for (i = 0; i < size/sizeof(*d); i++)
> +		igt_assert_eq(d[i], addr + i + 1);
> +
> +	munmap(d, size);
> +}
> +
> +static uint32_t *vm_create_objects(int fd, uint32_t bo_placement, uint32_t
> vm, unsigned int size,
> +				   unsigned int n)
> +{
> +	uint32_t *bo;
> +	unsigned int i;
> +
> +	bo = calloc(n, sizeof(*bo));
> +	igt_assert(bo);
> +
> +	for (i = 0; i < n; i++) {
> +		bo[i] = xe_bo_create(fd, vm, size, bo_placement, 0);
> +		igt_assert(bo[i]);
> +	}
> +
> +	return bo;
> +}
> +
> +static struct bind_list *create_bind_list(int fd, uint32_t bo_placement,
> +					  uint32_t vm, unsigned int n)
> +{
> +	const unsigned int bo_size = max_t(bo_size,
> xe_get_default_alignment(fd), MIN_BO_SIZE);
> +	struct bind_list *bl;
> +	unsigned int i;
> +
> +	bl = malloc(sizeof(*bl));
> +	bl->fd = fd;
> +	bl->vm = vm;
> +	bl->bo = vm_create_objects(fd, bo_placement, vm, bo_size, n);
> +	bl->n = n;
> +	bl->bind_ops = calloc(n, sizeof(*bl->bind_ops));
> +	igt_assert(bl->bind_ops);
> +
> +	for (i = 0; i < n; i++) {
> +		struct drm_xe_vm_bind_op *o = &bl->bind_ops[i];
> +
> +		o->range = bo_size;
> +		o->addr = BO_ADDR + 2 * i * bo_size;
> +		o->flags = 0;
> +		o->pat_index = intel_get_pat_idx_wb(fd);
> +		o->prefetch_mem_region_instance = 0;
> +		o->reserved[0] = 0;
> +		o->reserved[1] = 0;
> +	}
> +
> +	for (i = 0; i < bl->n; i++) {
> +		struct drm_xe_vm_bind_op *o = &bl->bind_ops[i];
> +
> +		igt_debug("bo %d: addr 0x%llx, range 0x%llx\n", i, o->addr, o-
> >range);
> +		bo_prime(fd, bl->bo[i], o->addr, o->range);
> +	}
> +
> +	return bl;
> +}
> +
> +static void do_bind_list(struct xe_eudebug_client *c,
> +			 struct bind_list *bl, struct drm_xe_sync *sync) {
> +	int i;
> +	uint64_t ref_seqno = 0, op_ref_seqno = 0;
> +
> +	xe_vm_bind_array(bl->fd, bl->vm, 0, bl->bind_ops, bl->n, sync, sync ?
> 1 : 0);
> +	xe_eudebug_client_vm_bind_event(c,
> DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
> +					bl->fd, bl->vm, 0, bl->n, &ref_seqno);
> +	for (i = 0; i < bl->n; i++)
> +		xe_eudebug_client_vm_bind_op_event(c,
> DRM_XE_EUDEBUG_EVENT_CREATE,
> +						   ref_seqno,
> +						   &op_ref_seqno,
> +						   bl->bind_ops[i].addr,
> +						   bl->bind_ops[i].range,
> +						   0);
> +
> +	if (sync)
> +		igt_assert(syncobj_wait(bl->fd, &sync->handle, 1,
> INT64_MAX, 0,
> +NULL)); }
> +
> +static void check_bind_list(struct bind_list *bl) {
> +	unsigned int i;
> +
> +	for (i = 0; i < bl->n; i++) {
> +		igt_debug("%d: checking 0x%llx (%lld)\n",
> +			  i, bl->bind_ops[i].addr, bl->bind_ops[i].addr);
> +		bo_check(bl->fd, bl->bo[i], bl->bind_ops[i].addr,
> +			 bl->bind_ops[i].range);
> +	}
> +}
> +
>  #define CREATE_VMS	(1 << 0)
>  #define CREATE_EXEC_QUEUES	(1 << 1)
>  static void run_basic_client(struct xe_eudebug_client *c) @@ -613,6
> +743,149 @@ static void test_empty_discovery(int fd, unsigned int flags, int
> clients)
>  	}
>  }
> 
> +typedef void (*client_run_t)(struct xe_eudebug_client *);
> +
> +static void test_client_with_trigger(int fd, unsigned int flags, int count,
> +				     client_run_t client_fn, int type,
> +				     xe_eudebug_trigger_fn trigger_fn,
> +				     struct drm_xe_engine_class_instance *hwe,
> +				     bool match_opposite, uint32_t
> event_filter) {
> +	struct xe_eudebug_session **s;
> +	int i;
> +
> +	s = calloc(count, sizeof(*s));
> +
> +	igt_assert(s);
> +
> +	for (i = 0; i < count; i++)
> +		s[i] = xe_eudebug_session_create(fd, client_fn, flags, hwe);
> +
> +	if (trigger_fn)
> +		for (i = 0; i < count; i++)
> +			xe_eudebug_debugger_add_trigger(s[i]->d, type,
> trigger_fn);
> +
> +	for (i = 0; i < count; i++)
> +		xe_eudebug_session_run(s[i]);
> +
> +	for (i = 0; i < count; i++)
> +		xe_eudebug_session_check(s[i], match_opposite,
> event_filter);
> +
> +	for (i = 0; i < count; i++)
> +		xe_eudebug_session_destroy(s[i]);
> +}
> +
> +static void vm_access_client(struct xe_eudebug_client *c) {
> +	struct drm_xe_sync sync = {
> +		.flags = DRM_XE_SYNC_TYPE_SYNCOBJ |
> DRM_XE_SYNC_FLAG_SIGNAL, };
> +	struct drm_xe_engine_class_instance *hwe = c->ptr;
> +	struct bind_list *bl;
> +	uint32_t vm;
> +	int fd, i;
> +
> +	igt_debug("Using %s\n", xe_engine_class_string(hwe->engine_class));
> +
> +	fd = xe_eudebug_client_open_driver(c);
> +	xe_device_get(fd);
> +
> +	vm = xe_eudebug_client_vm_create(c, fd, 0, 0);
> +
> +	bl = create_bind_list(fd, vram_if_possible(fd, hwe->gt_id), vm, 4);
> +	sync.handle = syncobj_create(bl->fd, 0);
> +	do_bind_list(c, bl, &sync);
> +	syncobj_destroy(bl->fd, sync.handle);
> +
> +	for (i = 0; i < bl->n; i++)
> +		xe_eudebug_client_wait_stage(c, bl->bind_ops[i].addr);
> +
> +	check_bind_list(bl);
> +
> +	xe_eudebug_client_vm_destroy(c, fd, vm);
> +
> +	xe_device_put(fd);
> +	xe_eudebug_client_close_driver(c, fd); }
> +
> +static void debugger_test_vma(struct xe_eudebug_debugger *d,
> +			      uint64_t client_handle,
> +			      uint64_t vm_handle,
> +			      uint64_t va_start,
> +			      uint64_t va_length)
> +{
> +	struct drm_xe_eudebug_vm_open vo = { 0, };
> +	uint64_t *v;
> +	uint64_t items = va_length / sizeof(uint64_t);
> +	int fd;
> +	int r, i;
> +
> +	v = malloc(va_length);
> +	igt_assert(v);
> +
> +	vo.client_handle = client_handle;
> +	vo.vm_handle = vm_handle;
> +
> +	fd = igt_ioctl(d->fd, DRM_XE_EUDEBUG_IOCTL_VM_OPEN, &vo);
> +	igt_assert_lte(0, fd);
> +
> +	r = pread(fd, v, va_length, va_start);
> +	igt_assert_eq(r, va_length);
> +
> +	for (i = 0; i < items; i++)
> +		igt_assert_eq(v[i], va_start + i);
> +
> +	for (i = 0; i < items; i++)
> +		v[i] = va_start + i + 1;
> +
> +	r = pwrite(fd, v, va_length, va_start);
> +	igt_assert_eq(r, va_length);
> +
> +	fsync(fd);
> +
> +	close(fd);
> +	free(v);
> +}
> +
> +static void vm_trigger(struct xe_eudebug_debugger *d,
> +		       struct drm_xe_eudebug_event *e) {
> +	struct drm_xe_eudebug_event_vm_bind_op *eo = (void *)e;
> +
> +	if (e->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
> +		struct drm_xe_eudebug_event_vm_bind *eb;
> +
> +		igt_debug("vm bind op event received with ref %lld, addr
> 0x%llx, range 0x%llx\n",
> +			  eo->vm_bind_ref_seqno,
> +			  eo->addr,
> +			  eo->range);
> +
> +		eb = (struct drm_xe_eudebug_event_vm_bind *)
> +			xe_eudebug_event_log_find_seqno(d->log, eo-
> >vm_bind_ref_seqno);
> +		igt_assert(eb);
> +
> +		debugger_test_vma(d, eb->client_handle, eb->vm_handle,
> +				  eo->addr, eo->range);
> +		xe_eudebug_debugger_signal_stage(d, eo->addr);
> +	}
> +}
> +
> +/**
> + * SUBTEST: basic-vm-access
> + * Description:
> + *      Exercise XE_EUDEBG_VM_OPEN with pread and pwrite into the vm fd

Typo: XE_EUDEBUG_VM_OPEN

> + */
> +static void test_vm_access(int fd, unsigned int flags, int num_clients)
> +{
> +	struct drm_xe_engine_class_instance *hwe;
> +
> +	xe_for_each_engine(fd, hwe)
> +		test_client_with_trigger(fd, flags, num_clients,
> +					 vm_access_client,
> +
> DRM_XE_EUDEBUG_EVENT_VM_BIND_OP,
> +					 vm_trigger, hwe,
> +					 false,
> XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP);
> +}
> +
>  igt_main
>  {
>  	int fd;
> @@ -633,6 +906,9 @@ igt_main
>  	igt_subtest("basic-client")
>  		test_basic_sessions(fd, 0, 1);
> 
> +	igt_subtest("basic-vm-access")
> +		test_vm_access(fd, 0, 1);
> +
>  	igt_subtest("multiple-sessions")
>  		test_basic_sessions(fd, CREATE_VMS |
> CREATE_EXEC_QUEUES, 4);
> 
> --
> 2.34.1



More information about the igt-dev mailing list