Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Welty, Brian" <brian.welty@intel.com>
To: "Chang, Bruce" <yu.bruce.chang@intel.com>,
	<igt-dev@lists.freedesktop.org>
Cc: Oak Zeng <oak.zeng@intel.com>
Subject: Re: [igt-dev] [PATCH i-g-t] tests/xe add invalid va access tests
Date: Thu, 31 Aug 2023 17:25:18 -0700	[thread overview]
Message-ID: <beaece7c-7111-5efd-43b7-36bca87ac95a@intel.com> (raw)
In-Reply-To: <20230831234654.18207-1-yu.bruce.chang@intel.com>



On 8/31/2023 4:46 PM, Chang, Bruce wrote:
> add the following invalid va access test cases:
> 
> 	gpu fault	scratch page	command timeout
> 1) 	no		no		yes
> 2) 	no		yes		no
> 3) 	yes		no		yes
> 4) 	yes		yes		no
> 
> TODO: with futher improvement of xe_wait_ufence, the test
> can check more specific error code from it.
> 

Typo with futher above.

Test looks good to me!
I note 2 issues below....
With those addressed:
   Reviewed-by: Brian Welty <brian.welty@intel.com>

But I don't know IGT process for adding new tests.
As this is brand new test, I hope there is gatekeeper making sure new
tests are truly needed (versus adding into some existing test)?  So
seems maintainer feedback or second reviewer who knows IGT better than 
me is best.

-Brian


> v2: async vm/bind, and re-bind valid address
> v3: added xe_wait_ufence check
> 
> Signed-off-by: Bruce Chang <yu.bruce.chang@intel.com>
> Cc: Oak Zeng <oak.zeng@intel.com>
> Cc: Brian Welty <brian.welty@intel.com>
> Cc: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> ---
>   lib/xe/xe_ioctl.c             |  15 +++-
>   lib/xe/xe_ioctl.h             |   3 +
>   tests/meson.build             |   1 +
>   tests/xe/xe_exec_invalid_va.c | 164 ++++++++++++++++++++++++++++++++++
>   4 files changed, 180 insertions(+), 3 deletions(-)
>   create mode 100644 tests/xe/xe_exec_invalid_va.c
> 
> diff --git a/lib/xe/xe_ioctl.c b/lib/xe/xe_ioctl.c
> index 730dcfd16..022f0cf04 100644
> --- a/lib/xe/xe_ioctl.c
> +++ b/lib/xe/xe_ioctl.c
> @@ -415,9 +415,9 @@ void xe_exec_wait(int fd, uint32_t exec_queue, uint64_t addr)
>   	syncobj_destroy(fd, sync.handle);
>   }
>   
> -int64_t xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
> +int64_t _xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
>   		       struct drm_xe_engine_class_instance *eci,
> -		       int64_t timeout)
> +		       int64_t timeout, bool timeout_assert)
>   {
>   	struct drm_xe_wait_user_fence wait = {
>   		.addr = to_user_pointer(addr),
> @@ -430,11 +430,20 @@ int64_t xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
>   		.instances = eci ? to_user_pointer(eci) : 0,
>   	};
>   
> -	igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_WAIT_USER_FENCE, &wait), 0);
> +	if (igt_ioctl(fd, DRM_IOCTL_XE_WAIT_USER_FENCE, &wait))
> +		igt_assert (!timeout_assert && errno == ETIME);

This doesn't look right to me...  I might be confused.

I think you want:
     igt_assert(!timeout_assert || errno == ETIME);

or:
    if (igt_ioctl(fd, DRM_IOCTL_XE_WAIT_USER_FENCE, &wait) && 
timeout_assert)
         igt_assert(errno == ETIME);


>   
>   	return wait.timeout;
>   }
>   
> +
> +int64_t xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
> +		       struct drm_xe_engine_class_instance *eci,
> +		       int64_t timeout)
> +{
> +	return _xe_wait_ufence(fd, addr, value, eci, timeout, true);
> +}
> +
>   /**
>    * xe_wait_ufence_abstime:
>    * @fd: xe device fd
> diff --git a/lib/xe/xe_ioctl.h b/lib/xe/xe_ioctl.h
> index 6c281b3bf..4bf7410a4 100644
> --- a/lib/xe/xe_ioctl.h
> +++ b/lib/xe/xe_ioctl.h
> @@ -82,6 +82,9 @@ void xe_exec(int fd, struct drm_xe_exec *exec);
>   void xe_exec_sync(int fd, uint32_t exec_queue, uint64_t addr,
>   		  struct drm_xe_sync *sync, uint32_t num_syncs);
>   void xe_exec_wait(int fd, uint32_t exec_queue, uint64_t addr);
> +int64_t _xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
> +		       struct drm_xe_engine_class_instance *eci,
> +		       int64_t timeout, bool timeout_assert);
>   int64_t xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
>   		       struct drm_xe_engine_class_instance *eci,
>   		       int64_t timeout);
> diff --git a/tests/meson.build b/tests/meson.build
> index 4d325bed1..8861b6c5b 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -276,6 +276,7 @@ xe_progs = [
>   	'xe_exec_reset',
>   	'xe_exec_store',
>   	'xe_exec_threads',
> +	'xe_exec_invalid_va',

I believe team wants these sorted alphabetically.

>   	'xe_exercise_blt',
>   	'xe_gpgpu_fill',
>   	'xe_guc_pc',
> diff --git a/tests/xe/xe_exec_invalid_va.c b/tests/xe/xe_exec_invalid_va.c
> new file mode 100644
> index 000000000..468b90c8a
> --- /dev/null
> +++ b/tests/xe/xe_exec_invalid_va.c
> @@ -0,0 +1,164 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +/**
> + * TEST: invalid va tests
> + * Category: Hardware building block
> + * Sub-category: execbuf
> + * Functionality: fault mode
> + * Test category: functionality test
> + * GPU requirements: GPU needs support for DRM_XE_VM_CREATE_FAULT_MODE
> + */
> +
> +#include <fcntl.h>
> +
> +#include "igt.h"
> +#include "lib/igt_syncobj.h"
> +#include "lib/intel_reg.h"
> +#include "xe_drm.h"
> +
> +#include "xe/xe_ioctl.h"
> +#include "xe/xe_query.h"
> +#include <string.h>
> +
> +static void insert_store(uint32_t *bb, uint64_t va, uint64_t data)
> +{
> +	*bb++ = MI_STORE_DWORD_IMM_GEN4;
> +	*bb++ = lower_32_bits(va);
> +	*bb++ = upper_32_bits(va);
> +	*bb++ = data;
> +	*bb++ = MI_BATCH_BUFFER_END;
> +}
> +
> +/**
> + * SUBTEST: invalid-va
> + * Description: Check driver handling of invalid va access
> + * Run type: FULL
> + *
> + * SUBTEST: invalid-va-scratch
> + * Description: Check driver handling of invalid va access with scratch page
> + * Run type: FULL
> + *
> + * SUBTEST: invalid-va-fault
> + * Description: Check driver handling of invalid va access with fault enabled
> + * Run type: FULL
> + *
> + * SUBTEST: invalid-va-fault-scratch
> + * Description: Check driver handling of invalid va access with fault + scratch page
> + * Run type: FULL
> + *
> + * arg[1]: for vm create flags
> + */
> +static void test_exec(int fd, uint32_t flags)
> +{
> +	const uint64_t inv_addr = 0x20000000;
> +	const uint64_t addr = 0x1a0000;
> +#define USER_FENCE_VALUE	0xdeadbeefdeadbeefull
> +#define ONE_SEC			MS_TO_NS(1000)
> +#define	STORE_DATA		0xDEADBEAF
> +	struct _data {
> +		uint32_t batch[16];
> +		uint64_t vm_sync;
> +		uint64_t sync;
> +		uint64_t data;
> +	} *data;
> +	struct drm_xe_sync sync = {
> +		.flags = DRM_XE_SYNC_USER_FENCE | DRM_XE_SYNC_SIGNAL,
> +		.timeline_value = USER_FENCE_VALUE,
> +	};
> +	struct drm_xe_exec exec = {
> +		.num_batch_buffer = 1,
> +		.address = addr,
> +		.num_syncs = 1,
> +		.syncs = to_user_pointer(&sync),
> +	};
> +	uint32_t vm;
> +	uint32_t bo;
> +	size_t bo_size;
> +	struct drm_xe_engine_class_instance *eci;
> +
> +	eci = xe_hw_engine(fd, 0);
> +	vm = xe_vm_create(fd, flags | DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0);
> +	bo_size = ALIGN(sizeof(*data), xe_get_default_alignment(fd));
> +	bo = xe_bo_create_flags(fd, vm, bo_size,
> +				all_memory_regions(fd) |
> +				visible_vram_if_possible(fd, 0));
> +	data = xe_bo_map(fd, bo, bo_size);
> +	memset(data, 0, bo_size);
> +
> +	insert_store(data->batch, inv_addr + offsetof(struct _data, data), STORE_DATA);
> +	exec.exec_queue_id = xe_exec_queue_create(fd, vm, eci, 0);
> +	sync.addr = to_user_pointer(&data->vm_sync);
> +	xe_vm_bind_async_flags(fd, vm, 0, bo, 0,
> +				addr, bo_size, &sync, 1,
> +				XE_VM_BIND_FLAG_IMMEDIATE);
> +	xe_wait_ufence(fd, &data->vm_sync, USER_FENCE_VALUE, NULL, ONE_SEC);
> +	data->vm_sync = 0;
> +	sync.addr = addr + offsetof(struct _data, sync);
> +	xe_exec(fd, &exec);
> +	_xe_wait_ufence(fd, &data->sync, USER_FENCE_VALUE, NULL, ONE_SEC, false);
> +	if (!(flags & DRM_XE_VM_CREATE_SCRATCH_PAGE))
> +		assert(errno == ETIME);
> +	else
> +		assert(errno == 0);
> +	data->sync = 0;
> +
> +	if ((flags & DRM_XE_VM_CREATE_FAULT_MODE) &&
> +	    (flags & DRM_XE_VM_CREATE_SCRATCH_PAGE)) {
> +		/* bind inv_addr after scratch page was created */
> +		sync.addr = to_user_pointer(&data->vm_sync);
> +		xe_vm_bind_async_flags(fd, vm, 0, bo, 0,
> +				inv_addr, bo_size, &sync, 1,
> +				XE_VM_BIND_FLAG_IMMEDIATE);
> +		xe_wait_ufence(fd, &data->vm_sync, USER_FENCE_VALUE, NULL, ONE_SEC);
> +		data->vm_sync = 0;
> +		data->data = 0;
> +		sync.addr = addr + offsetof(struct _data, sync);
> +		xe_exec(fd, &exec);
> +		xe_wait_ufence(fd, &data->sync, USER_FENCE_VALUE, NULL, ONE_SEC);
> +		igt_assert_eq(data->data, STORE_DATA);
> +	}
> +
> +	sync.addr = to_user_pointer(&data->vm_sync);
> +	xe_vm_unbind_async(fd, vm, 0, 0, addr, bo_size, &sync, 1);
> +	xe_wait_ufence(fd, &data->vm_sync, USER_FENCE_VALUE, NULL, ONE_SEC);
> +	data->vm_sync = 0;
> +	xe_vm_unbind_async(fd, vm, 0, 0, inv_addr, bo_size, &sync, 1);
> +	xe_wait_ufence(fd, &data->vm_sync, USER_FENCE_VALUE, NULL, ONE_SEC);
> +	xe_exec_queue_destroy(fd, exec.exec_queue_id);
> +	munmap(data, bo_size);
> +	gem_close(fd, bo);
> +	xe_vm_destroy(fd, vm);
> +}
> +
> +igt_main
> +{
> +	const struct section {
> +		const char *name;
> +		unsigned int flags;
> +	} sections[] = {
> +		{ "invalid-va", 0 },
> +		{ "invalid-va-scratch", DRM_XE_VM_CREATE_SCRATCH_PAGE },
> +		{ "invalid-va-fault", DRM_XE_VM_CREATE_FAULT_MODE },
> +		{ "invalid-va-fault-scratch", DRM_XE_VM_CREATE_FAULT_MODE |
> +					      DRM_XE_VM_CREATE_SCRATCH_PAGE },
> +		{ NULL },
> +	};
> +	int fd;
> +
> +	igt_fixture {
> +		fd = drm_open_driver(DRIVER_XE);
> +		igt_require(xe_supports_faults(fd));
> +	}
> +
> +	for (const struct section *s = sections; s->name; s++) {
> +		igt_subtest_f("%s", s->name)
> +			test_exec(fd, s->flags);
> +	}
> +
> +	igt_fixture
> +		drm_close_driver(fd);
> +}
> +

  reply	other threads:[~2023-09-01  0:26 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-31 23:46 [igt-dev] [PATCH i-g-t] tests/xe add invalid va access tests Chang, Bruce
2023-09-01  0:25 ` Welty, Brian [this message]
2023-09-01  0:46 ` [igt-dev] ✓ CI.xeBAT: success for tests/xe add invalid va access tests (rev3) Patchwork
2023-09-01  0:51 ` [igt-dev] ✗ GitLab.Pipeline: warning " Patchwork
2023-09-01  0:59 ` [igt-dev] ✗ Fi.CI.BAT: failure " Patchwork
2023-09-01 12:16 ` [igt-dev] [PATCH i-g-t] tests/xe add invalid va access tests Kamil Konieczny
2023-09-01 23:56   ` Chang, Yu bruce
  -- strict thread matches above, loose matches on Subject: below --
2023-08-29 23:05 Chang, Bruce
2023-08-30 22:56 ` Welty, Brian
2023-08-31  0:26   ` Chang, Yu bruce
2023-08-31  1:11     ` Welty, Brian
2023-09-01  0:09       ` Chang, Yu bruce
2023-08-28 18:53 Chang, Bruce

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=beaece7c-7111-5efd-43b7-36bca87ac95a@intel.com \
    --to=brian.welty@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=oak.zeng@intel.com \
    --cc=yu.bruce.chang@intel.com \
    /path/to/YOUR_REPLY

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

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