From: "Sharma, Nishit" <nishit.sharma@intel.com>
To: Arvind Yadav <arvind.yadav@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 3/9] tests/intel/xe_madvise: Add dontneed-before-mmap subtest
Date: Mon, 6 Apr 2026 16:00:15 +0530 [thread overview]
Message-ID: <c30a0712-9d64-4752-af84-cd9dd598caf3@intel.com> (raw)
In-Reply-To: <1db6f1ca-4706-4ed3-9ad0-219a956e4cd3@intel.com>
On 4/6/2026 3:23 PM, Sharma, Nishit wrote:
>
> On 3/25/2026 6:14 PM, Arvind Yadav wrote:
>> This test validates that mmap() fails with -EBUSY when attempting to
>> map a BO marked DONTNEED. The mmap offset ioctl succeeds (it just
>> returns the pre-allocated offset); the purgeable check happens in
>> xe_gem_object_mmap() at mmap() time.
>>
>> - DONTNEED BOs: return -EBUSY (temporary purgeable state, BO still
>> has backing store but can be purged at any time)
>> - Purged BOs: return -EINVAL (permanent, backing store discarded)
>>
>> v4:
>> - Move unmap outside the block. (Pravalika)
>> - Added proper resource cleanup before calling igt_skip(). (Nishit)
>> - Added assertion for xe_bo_map. (Nishit)
>>
>> v5:
>> - Add kernel capability check *_FLAG_HAS_PURGING_SUPPORT for
>> purgeable support. (Jose)
>> - Drop memory pressure trigger path; mark DONTNEED directly and
>> assert -EBUSY from mmap offset ioctl; restore WILLNEED before
>> cleanup.
>>
>> v6:
>> - Support iGPU by using total system RAM as the pressure baseline
>> instead of VRAM size (which is 0 on iGPU).
>> - Raise overpressure from 25% to 50% of the baseline to ensure the
>> kernel shrinker is forced to reclaim on systems with large free
>> RAM.
>> - The DONTNEED enforcement point is mmap() itself, not the
>> DRM_IOCTL_XE_GEM_MMAP_OFFSET ioctl. Update the test to mark
>> DONTNEED
>> first, then verify DRM_IOCTL_XE_GEM_MMAP_OFFSET still succeeds, and
>> finally verify that mmap() fails with -EBUSY
>>
>> 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>
>> Cc: Pravalika Gurram <pravalika.gurram@intel.com>
>> Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
>> ---
>> tests/intel/xe_madvise.c | 233 +++++++++++++++++++++++++++++++++++++++
>> tests/meson.build | 1 +
>> 2 files changed, 234 insertions(+)
>> create mode 100644 tests/intel/xe_madvise.c
>>
>> diff --git a/tests/intel/xe_madvise.c b/tests/intel/xe_madvise.c
>> new file mode 100644
>> index 000000000..de4a6e34c
>> --- /dev/null
>> +++ b/tests/intel/xe_madvise.c
>> @@ -0,0 +1,233 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright © 2025 Intel Corporation
>> + */
>> +
>> +/**
>> + * TEST: Validate purgeable BO madvise functionality
>> + * Category: Core
>> + * Mega feature: General Core features
>> + * Sub-category: Memory management tests
>> + * Functionality: madvise, purgeable
>> + */
>> +
>> +#include "igt.h"
>> +#include "xe_drm.h"
>> +
>> +#include "xe/xe_ioctl.h"
>> +#include "xe/xe_query.h"
>> +
>> +static bool xe_has_purgeable_support(int fd)
>> +{
>> + struct drm_xe_query_config *config = xe_config(fd);
>> +
>> + return config->info[DRM_XE_QUERY_CONFIG_FLAGS] &
>> + DRM_XE_QUERY_CONFIG_FLAG_HAS_PURGING_SUPPORT;
>> +}
>> +
>> +/* Purgeable test constants */
>> +#define PURGEABLE_ADDR 0x1a0000
>> +#define PURGEABLE_BO_SIZE 4096
>> +
>> +/**
>> + * trigger_memory_pressure - Fill VRAM/RAM + 50% to force purgeable
>> reclaim
>> + * @fd: DRM file descriptor
>> + * @vm: VM handle (unused, kept for API compatibility)
>> + *
>> + * Allocates BOs in a temporary VM until memory is overcommitted by
>> 50%,
>> + * forcing the kernel to purge DONTNEED-marked BOs.
>> + */
>> +static void trigger_memory_pressure(int fd, uint32_t vm)
>> +{
>> + uint64_t vram_size, mem_size, overpressure;
>> + const uint64_t chunk = 8ull << 20; /* 8 MiB */
>> + int max_objs, n = 0;
>> + uint32_t *handles;
>> + uint64_t total;
>> + void *p;
>> + uint32_t handle, temp_vm;
>> +
>> + /* Use a separate VM so pressure BOs don't affect the test VM */
>> + temp_vm = xe_vm_create(fd, 0, 0);
>> +
>> + vram_size = xe_visible_vram_size(fd, 0);
>> + if (vram_size > 0) {
>> + /* dGPU: pressure VRAM to trigger purgeable reclaim */
>> + mem_size = vram_size;
>> + } else {
>> + /*
>> + * iGPU: purgeable BOs reside in system memory. Use *total*
>> + * RAM (not just available) as the baseline so that we always
>> + * over-commit regardless of how much is already in use.
>> + */
>> + mem_size = igt_get_total_ram_mb() << 20;
>> + }
>> +
>> + /* Scale overpressure to 50% of memory, minimum 64MB */
>> + overpressure = mem_size / 2;
>> + if (overpressure < (64 << 20))
>> + overpressure = 64 << 20;
>> +
>> + max_objs = (mem_size + overpressure) / chunk + 1;
>> + handles = malloc(max_objs * sizeof(*handles));
>> + igt_assert(handles);
>> +
>> + total = 0;
>> + while (total < mem_size + overpressure && n < max_objs) {
>> + uint32_t err;
>> +
>> + err = __xe_bo_create(fd, temp_vm, chunk,
>> + vram_if_possible(fd, 0),
>> + DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM,
>> + NULL, &handle);
>> + if (err) /* Out of memory — sufficient pressure achieved */
>> + break;
>> +
>> + handles[n++] = handle;
>> + total += chunk;
>> +
>> + p = xe_bo_map(fd, handle, chunk);
>> + igt_assert(p != MAP_FAILED);
>> +
>> + /* Fault in all pages so they actually consume memory */
>> + memset(p, 0xCD, chunk);
>> + munmap(p, chunk);
>> + }
>> +
>> + /* Allow shrinker time to process pressure */
>> + usleep(100000);
>> +
>> + for (int i = 0; i < n; i++)
>> + gem_close(fd, handles[i]);
>> +
>> + free(handles);
>> +
>> + xe_vm_destroy(fd, temp_vm);
>> +}
> This function is called from below function which is not part of this
> Patch-3/9. This must be removed and introduced in Patch-4/9.
>> +
>> +static jmp_buf jmp;
>> +
>> +__noreturn static void sigtrap(int sig)
>> +{
>> + siglongjmp(jmp, sig);
>> +}
>> +
>> +/**
>> + * purgeable_mark_and_verify_purged - Mark DONTNEED, pressure, check
>> purged
>> + * @fd: DRM file descriptor
>> + * @vm: VM handle
>> + * @addr: Virtual address of the BO
>> + * @size: Size of the BO
>> + *
>> + * Returns true if the BO was purged under memory pressure.
>> + */
>> +static bool purgeable_mark_and_verify_purged(int fd, uint32_t vm,
>> uint64_t addr, size_t size)
>> +{
>> + uint32_t retained;
>> +
>> + /* Mark as DONTNEED */
>> + retained = xe_vm_madvise_purgeable(fd, vm, addr, size,
>> + DRM_XE_VMA_PURGEABLE_STATE_DONTNEED);
>> + if (retained != 1)
>> + return false;
>> +
>> + /* Trigger memory pressure */
>> + trigger_memory_pressure(fd, vm);
>> +
>> + /* Verify purged */
>> + retained = xe_vm_madvise_purgeable(fd, vm, addr, size,
>> + DRM_XE_VMA_PURGEABLE_STATE_WILLNEED);
>> + return retained == 0;
>> +}
> This function is introduced in test_dontneed_after_mmap() in
> Patch-4/9. Remove this and introduced in Patch-4/9.
Correction here, this function is called from subtest
test_purged_mmap_blocked(fd); which is in Patch-4/9. Please move these
functions in Patch-4/9
>> +
>> +/**
>> + * purgeable_setup_simple_bo - Setup VM and bind a single BO
>> + * @fd: DRM file descriptor
>> + * @vm: Output VM handle
>> + * @bo: Output BO handle
>> + * @addr: Virtual address to bind at
>> + * @size: Size of the BO
>> + * @use_scratch: Whether to use scratch page flag
>> + *
>> + * Helper to create VM, BO, and bind it at the specified address.
>> + */
>> +static void purgeable_setup_simple_bo(int fd, uint32_t *vm, uint32_t
>> *bo,
>> + uint64_t addr, size_t size, bool use_scratch)
>> +{
>> + struct drm_xe_sync sync = {
>> + .type = DRM_XE_SYNC_TYPE_USER_FENCE,
>> + .flags = DRM_XE_SYNC_FLAG_SIGNAL,
>> + .timeline_value = 1,
>> + };
>> + uint64_t sync_val = 0;
>> +
>> + *vm = xe_vm_create(fd, use_scratch ?
>> DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE : 0, 0);
>> + *bo = xe_bo_create(fd, *vm, size, vram_if_possible(fd, 0),
>> + DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
>> +
>> + sync.addr = to_user_pointer(&sync_val);
>> + xe_vm_bind_async(fd, *vm, 0, *bo, 0, addr, size, &sync, 1);
>> + xe_wait_ufence(fd, &sync_val, 1, 0, NSEC_PER_SEC);
>> +}
>> +
>> +/**
>> + * SUBTEST: dontneed-before-mmap
>> + * Description: Mark BO as DONTNEED before mmap, verify mmap() fails
>> with -EBUSY
>> + * Test category: functionality test
>> + */
>> +static void test_dontneed_before_mmap(int fd)
>> +{
>> + uint32_t bo, vm;
>> + uint64_t addr = PURGEABLE_ADDR;
>> + size_t bo_size = PURGEABLE_BO_SIZE;
>> + struct drm_xe_gem_mmap_offset mmo = {};
>> + uint32_t retained;
>> + void *ptr;
>> +
>> + purgeable_setup_simple_bo(fd, &vm, &bo, addr, bo_size, false);
>> +
>> + /* Mark BO as DONTNEED - new mmap operations must be blocked */
>> + retained = xe_vm_madvise_purgeable(fd, vm, addr, bo_size,
>> + DRM_XE_VMA_PURGEABLE_STATE_DONTNEED);
>> + igt_assert_eq(retained, 1);
>> +
>> + /* Ioctl succeeds even for DONTNEED BO; blocking happens at
>> mmap() time. */
>> + mmo.handle = bo;
>> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_GEM_MMAP_OFFSET, &mmo),
>> 0);
>> +
>> + /* mmap() on a DONTNEED BO must fail with EBUSY. */
>> + ptr = mmap(NULL, bo_size, PROT_READ | PROT_WRITE, MAP_SHARED,
>> fd, mmo.offset);
>> + igt_assert_eq_u64((uint64_t)ptr, (uint64_t)MAP_FAILED);
>> + igt_assert_eq(errno, EBUSY);
>> +
>> + /* Restore to WILLNEED before cleanup */
>> + xe_vm_madvise_purgeable(fd, vm, addr, bo_size,
>> + DRM_XE_VMA_PURGEABLE_STATE_WILLNEED);
>> +
>> + gem_close(fd, bo);
>> + xe_vm_destroy(fd, vm);
>> +}
>> +
>> +int igt_main()
>> +{
>> + struct drm_xe_engine_class_instance *hwe;
>> + int fd;
>> +
>> + igt_fixture() {
>> + fd = drm_open_driver(DRIVER_XE);
>> + xe_device_get(fd);
>> + igt_require_f(xe_has_purgeable_support(fd),
>> + "Kernel does not support purgeable buffer
>> objects\n");
>> + }
>> +
>> + igt_subtest("dontneed-before-mmap")
>> + xe_for_each_engine(fd, hwe) {
>> + test_dontneed_before_mmap(fd);
>> + break;
>> + }
>> +
>> + igt_fixture() {
>> + xe_device_put(fd);
>> + drm_close_driver(fd);
>> + }
>> +}
>> diff --git a/tests/meson.build b/tests/meson.build
>> index cecb4a8ae..a6370b685 100644
>> --- a/tests/meson.build
>> +++ b/tests/meson.build
>> @@ -314,6 +314,7 @@ intel_xe_progs = [
>> 'xe_huc_copy',
>> 'xe_intel_bb',
>> 'xe_live_ktest',
>> + 'xe_madvise',
>> 'xe_media_fill',
>> 'xe_mmap',
>> 'xe_module_load',
next prev parent reply other threads:[~2026-04-06 10: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 [this message]
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
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=c30a0712-9d64-4752-af84-cd9dd598caf3@intel.com \
--to=nishit.sharma@intel.com \
--cc=arvind.yadav@intel.com \
--cc=himal.prasad.ghimiray@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=matthew.brost@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.