From: "Yadav, Arvind" <arvind.yadav@intel.com>
To: "Sharma, Nishit" <nishit.sharma@intel.com>,
<igt-dev@lists.freedesktop.org>
Cc: <matthew.brost@intel.com>, <himal.prasad.ghimiray@intel.com>,
<thomas.hellstrom@linux.intel.com>, <pravalika.gurram@intel.com>
Subject: Re: [PATCH i-g-t v6 6/9] tests/intel/xe_madvise: Add dontneed-before-exec subtest
Date: Tue, 7 Apr 2026 10:59:51 +0530 [thread overview]
Message-ID: <753ee211-bb5e-4883-85b7-d7e97a5f20dd@intel.com> (raw)
In-Reply-To: <a0303680-5405-46d4-8cd6-32c96f9e2720@intel.com>
On 06-04-2026 22:18, Sharma, Nishit wrote:
>
> On 3/25/2026 6:14 PM, Arvind Yadav wrote:
>> This test validates GPU execution behavior when a data BO is purged
>> before submission. The test creates a batch that writes to a data BO,
>> purges the data BO (while keeping the batch BO valid to avoid GPU
>> reset), then submits for execution. With VM_CREATE_FLAG_SCRATCH_PAGE,
>> the GPU write may succeed by landing on scratch memory instead of the
>> purged BO, demonstrating graceful handling of purged memory during
>> GPU operations.
>>
>> v4:
>> - Added proper resource cleanup before calling igt_skip(). (Nishit)
>>
>> Cc: Nishit Sharma <nishit.sharma@intel.com>
>> Cc: Matthew Brost <matthew.brost@intel.com>
>> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
>> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
>> Reviewed-by: Pravalika Gurram <pravalika.gurram@intel.com>
>> Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
>> ---
>> tests/intel/xe_madvise.c | 148 +++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 148 insertions(+)
>>
>> diff --git a/tests/intel/xe_madvise.c b/tests/intel/xe_madvise.c
>> index 9a157de1d..d126db9ed 100644
>> --- a/tests/intel/xe_madvise.c
>> +++ b/tests/intel/xe_madvise.c
>> @@ -27,7 +27,11 @@ static bool xe_has_purgeable_support(int fd)
>> /* Purgeable test constants */
>> #define PURGEABLE_ADDR 0x1a0000
>> +#define PURGEABLE_BATCH_ADDR 0x3c0000
>> #define PURGEABLE_BO_SIZE 4096
>> +#define PURGEABLE_FENCE_VAL 0xbeef
>> +#define PURGEABLE_TEST_PATTERN 0xc0ffee
>> +#define PURGEABLE_DEAD_PATTERN 0xdead
>> /**
>> * trigger_memory_pressure - Fill VRAM/RAM + 50% to force purgeable
>> reclaim
>> @@ -206,6 +210,62 @@ static void test_purged_mmap_blocked(int fd)
>> xe_vm_destroy(fd, vm);
>> }
>> +/**
>> + * purgeable_setup_batch_and_data - Setup VM with batch and data BOs
>> for GPU exec
>> + * @fd: DRM file descriptor
>> + * @vm: Output VM handle
>> + * @bind_engine: Output bind engine handle
>> + * @batch_bo: Output batch BO handle
>> + * @data_bo: Output data BO handle
>> + * @batch: Output batch buffer pointer
>> + * @data: Output data buffer pointer
>> + * @batch_addr: Batch virtual address
>> + * @data_addr: Data virtual address
>> + * @batch_size: Batch buffer size
>> + * @data_size: Data buffer size
>> + *
>> + * Helper to create VM, bind engine, batch and data BOs, and bind them.
>> + */
>> +static void purgeable_setup_batch_and_data(int fd, uint32_t *vm,
>> + uint32_t *bind_engine,
>> + uint32_t *batch_bo,
>> + uint32_t *data_bo,
>> + uint32_t **batch,
>> + uint32_t **data,
>> + uint64_t batch_addr,
>> + uint64_t data_addr,
>> + size_t batch_size,
>> + size_t data_size)
>> +{
>> + struct drm_xe_sync sync = {
>> + .type = DRM_XE_SYNC_TYPE_USER_FENCE,
>> + .flags = DRM_XE_SYNC_FLAG_SIGNAL,
>> + .timeline_value = PURGEABLE_FENCE_VAL,
>> + };
>> + uint64_t vm_sync = 0;
>> +
>> + *vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE, 0);
>> + *bind_engine = xe_bind_exec_queue_create(fd, *vm, 0);
>> +
>> + /* Create and bind batch BO */
>> + *batch_bo = xe_bo_create(fd, *vm, batch_size,
>> vram_if_possible(fd, 0),
>> + DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
>> + *batch = xe_bo_map(fd, *batch_bo, batch_size);
>> +
>> + sync.addr = to_user_pointer(&vm_sync);
>> + xe_vm_bind_async(fd, *vm, *bind_engine, *batch_bo, 0,
>> batch_addr, batch_size, &sync, 1);
>> + xe_wait_ufence(fd, &vm_sync, PURGEABLE_FENCE_VAL, 0, NSEC_PER_SEC);
>> +
>> + /* Create and bind data BO */
>> + *data_bo = xe_bo_create(fd, *vm, data_size, vram_if_possible(fd,
>> 0),
>> + DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
>> + *data = xe_bo_map(fd, *data_bo, data_size);
>> +
>> + vm_sync = 0;
>> + xe_vm_bind_async(fd, *vm, *bind_engine, *data_bo, 0, data_addr,
>> data_size, &sync, 1);
>> + xe_wait_ufence(fd, &vm_sync, PURGEABLE_FENCE_VAL, 0, NSEC_PER_SEC);
>> +}
>> +
>> /**
>> * SUBTEST: dontneed-before-mmap
>> * Description: Mark BO as DONTNEED before mmap, verify mmap()
>> fails with -EBUSY
>> @@ -302,6 +362,88 @@ static void test_dontneed_after_mmap(int fd)
>> xe_vm_destroy(fd, vm);
>> }
>> +/**
>> + * SUBTEST: dontneed-before-exec
>> + * Description: Mark BO as DONTNEED before GPU exec, verify GPU
>> behavior with SCRATCH_PAGE
>> + * Test category: functionality test
>> + */
>> +static void test_dontneed_before_exec(int fd, struct
>> drm_xe_engine_class_instance *hwe)
>> +{
>> + uint32_t vm, exec_queue, bo, batch_bo, bind_engine;
>> + uint64_t data_addr = PURGEABLE_ADDR;
>> + uint64_t batch_addr = PURGEABLE_BATCH_ADDR;
>> + size_t data_size = PURGEABLE_BO_SIZE;
>> + size_t batch_size = PURGEABLE_BO_SIZE;
>> + struct drm_xe_sync sync[1] = {
>> + { .type = DRM_XE_SYNC_TYPE_USER_FENCE,
>> + .flags = DRM_XE_SYNC_FLAG_SIGNAL,
>> + .timeline_value = PURGEABLE_FENCE_VAL },
>> + };
>> + struct drm_xe_exec exec = {
>> + .num_batch_buffer = 1,
>> + .num_syncs = 1,
>> + .syncs = to_user_pointer(sync),
>> + };
>> + uint32_t *data, *batch;
>> + uint64_t vm_sync = 0;
>> + int b, ret;
>> +
>> + purgeable_setup_batch_and_data(fd, &vm, &bind_engine, &batch_bo,
>> + &bo, &batch, &data, batch_addr,
>> + data_addr, batch_size, data_size);
>> +
>> + /* Prepare batch */
>> + b = 0;
>> + batch[b++] = MI_STORE_DWORD_IMM_GEN4;
>> + batch[b++] = data_addr;
>> + batch[b++] = data_addr >> 32;
>> + batch[b++] = PURGEABLE_DEAD_PATTERN;
>> + batch[b++] = MI_BATCH_BUFFER_END;
>> +
>> + /* Phase 1: Purge data BO, batch BO still valid */
>> + if (!purgeable_mark_and_verify_purged(fd, vm, data_addr,
>> data_size)) {
> Same comment as in patch-4/9.
Fixed — purgeable_mark_and_verify_purged() now handles retained == 0
from DONTNEED as already-purged success
>> + munmap(data, data_size);
>> + munmap(batch, batch_size);
>> + gem_close(fd, bo);
>> + gem_close(fd, batch_bo);
>> + xe_exec_queue_destroy(fd, bind_engine);
>> + xe_vm_destroy(fd, vm);
>> + igt_skip("Unable to induce purge on this platform/config");
>> + }
>> +
>> + exec_queue = xe_exec_queue_create(fd, vm, hwe, 0);
>> + exec.exec_queue_id = exec_queue;
>> + exec.address = batch_addr;
>> +
>> + vm_sync = 0;
>> + sync[0].addr = to_user_pointer(&vm_sync);
>> +
>> + /*
>> + * VM has SCRATCH_PAGE — exec may succeed with the GPU write
>> + * landing on scratch instead of the purged data BO.
>> + */
>> + ret = __xe_exec(fd, &exec);
> You can use xe_exec(fd, &exec) which is internally calling __xe_exec()
> and after use xe_wait_fence()
We can't use xe_exec() here, the data BO has been purged, so exec may
legitimately fail. xe_exec() asserts success internally, which would
cause a false test failure. We need __xe_exec() to handle both outcomes:
success (GPU write lands on scratch page) or failure (exec rejected for
purged BO).
Thanks,
Arvind
>> + if (ret == 0) {
>> + int64_t timeout = NSEC_PER_SEC;
>> +
>> + __xe_wait_ufence(fd, &vm_sync, PURGEABLE_FENCE_VAL,
>> + exec_queue, &timeout);
>> + }
>> +
>> + /*
>> + * Don't purge the batch BO — GPU would fetch zeroed scratch
>> + * instructions and trigger an engine reset.
>> + */
>> +
>> + munmap(data, data_size);
>> + munmap(batch, batch_size);
>> + gem_close(fd, bo);
>> + gem_close(fd, batch_bo);
>> + xe_exec_queue_destroy(fd, bind_engine);
>> + xe_exec_queue_destroy(fd, exec_queue);
>> + xe_vm_destroy(fd, vm);
>> +}
>> +
>> int igt_main()
>> {
>> struct drm_xe_engine_class_instance *hwe;
>> @@ -332,6 +474,12 @@ int igt_main()
>> break;
>> }
>> + igt_subtest("dontneed-before-exec")
>> + xe_for_each_engine(fd, hwe) {
>> + test_dontneed_before_exec(fd, hwe);
>> + break;
>> + }
>> +
>> igt_fixture() {
>> xe_device_put(fd);
>> drm_close_driver(fd);
next prev parent reply other threads:[~2026-04-07 5:30 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-25 12:44 [PATCH i-g-t v6 0/9] tests/xe: Add purgeable memory madvise tests for system allocator Arvind Yadav
2026-03-25 12:44 ` [PATCH i-g-t v6 1/9] drm-uapi/xe_drm: Add UAPI support for purgeable buffer objects Arvind Yadav
2026-04-06 5:23 ` Sharma, Nishit
2026-04-06 6:00 ` Yadav, Arvind
2026-03-25 12:44 ` [PATCH i-g-t v6 2/9] lib/xe: Add purgeable memory ioctl support Arvind Yadav
2026-04-06 6:59 ` Sharma, Nishit
2026-04-07 3:18 ` Yadav, Arvind
2026-03-25 12:44 ` [PATCH i-g-t v6 3/9] tests/intel/xe_madvise: Add dontneed-before-mmap subtest Arvind Yadav
2026-04-06 9:53 ` Sharma, Nishit
2026-04-06 10:30 ` Sharma, Nishit
2026-04-07 4:21 ` Yadav, Arvind
2026-03-25 12:44 ` [PATCH i-g-t v6 4/9] tests/intel/xe_madvise: Add purged-mmap-blocked subtest Arvind Yadav
2026-04-06 12:34 ` Sharma, Nishit
2026-04-07 5:09 ` Yadav, Arvind
2026-03-25 12:44 ` [PATCH i-g-t v6 5/9] tests/intel/xe_madvise: Add dontneed-after-mmap subtest Arvind Yadav
2026-04-06 13:33 ` Sharma, Nishit
2026-04-07 5:15 ` Yadav, Arvind
2026-03-25 12:44 ` [PATCH i-g-t v6 6/9] tests/intel/xe_madvise: Add dontneed-before-exec subtest Arvind Yadav
2026-04-06 16:48 ` Sharma, Nishit
2026-04-07 5:29 ` Yadav, Arvind [this message]
2026-03-25 12:44 ` [PATCH i-g-t v6 7/9] tests/intel/xe_madvise: Add dontneed-after-exec subtest Arvind Yadav
2026-04-07 14:51 ` Sharma, Nishit
2026-03-25 12:44 ` [PATCH i-g-t v6 8/9] tests/intel/xe_madvise: Add per-vma-tracking subtest Arvind Yadav
2026-04-07 7:20 ` Sharma, Nishit
2026-04-07 8:49 ` Yadav, Arvind
2026-03-25 12:44 ` [PATCH i-g-t v6 9/9] tests/intel/xe_madvise: Add per-vma-protection subtest Arvind Yadav
2026-04-07 7:31 ` Sharma, Nishit
2026-04-07 8:54 ` Yadav, Arvind
2026-03-25 22:59 ` ✓ Xe.CI.BAT: success for tests/xe: Add purgeable memory madvise tests for system allocator (rev6) Patchwork
2026-03-25 23:15 ` ✓ i915.CI.BAT: " Patchwork
2026-03-26 9:19 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-03-26 11:22 ` ✓ i915.CI.Full: success " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=753ee211-bb5e-4883-85b7-d7e97a5f20dd@intel.com \
--to=arvind.yadav@intel.com \
--cc=himal.prasad.ghimiray@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=matthew.brost@intel.com \
--cc=nishit.sharma@intel.com \
--cc=pravalika.gurram@intel.com \
--cc=thomas.hellstrom@linux.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.