From: Tejas Upadhyay <tejas.upadhyay@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: matthew.auld@intel.com, matthew.brost@intel.com,
thomas.hellstrom@linux.intel.com,
himal.prasad.ghimiray@intel.com,
Tejas Upadhyay <tejas.upadhyay@intel.com>
Subject: [PATCH i-g-t] [DO_NOT_REVIEW] tests/xe_mempage_offline: Add Tests for memory page offline feature
Date: Fri, 27 Mar 2026 17:06:48 +0530 [thread overview]
Message-ID: <20260327113651.2677665-2-tejas.upadhyay@intel.com> (raw)
Add below tests for memory page offlining feature on CRI.
./build/tests/xe_mempage_offline --l
unallocated
user-allocated
user-ggtt-allocated
user-ppgtt-allocated
critical-allocated
reserved
Note: These tests are going to be fit in RASs IGT tests later, so marked as do not review.
This is more towards supporting reviews and general testing of feature on CRI.
Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
---
tests/intel/xe_mempage_offline.c | 229 +++++++++++++++++++++++++++++++
tests/meson.build | 1 +
2 files changed, 230 insertions(+)
create mode 100644 tests/intel/xe_mempage_offline.c
diff --git a/tests/intel/xe_mempage_offline.c b/tests/intel/xe_mempage_offline.c
new file mode 100644
index 000000000..4e7a6106e
--- /dev/null
+++ b/tests/intel/xe_mempage_offline.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+/**
+ * TEST: cause specific category phy address error and check if it got offlined
+ * Category: Core
+ * Mega feature: General Core features
+ * Sub-category: driver
+ * Functionality: memory page offline
+ * Test category: functionality test
+ */
+
+#include <limits.h>
+#include <dirent.h>
+
+#include "igt.h"
+#include "igt_device.h"
+#include "igt_kmod.h"
+#include "igt_sriov_device.h"
+#include "igt_syncobj.h"
+#include "igt_sysfs.h"
+
+#include "xe_drm.h"
+#include "xe/xe_gt.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_query.h"
+#include "xe/xe_spin.h"
+
+/**
+ * SUBTEST: unallocated
+ * Description: Test if device is able to offline unallocated phy address error
+ */
+/**
+ * SUBTEST: user-allocated
+ * Description: Test if device is able to offline user-allocated phy address error
+ */
+/**
+ * SUBTEST: user-ggtt-allocated
+ * Description: Test if device is able to offline ggtt phy address error
+ */
+/**
+ * SUBTEST: user-ppgtt-allocated
+ * Description: Test if device is able to offline ppgtt phy address error
+ */
+/**
+ * SUBTEST: critical-allocated
+ * Description: Test if device is able to offline critical-allocated phy address error
+ */
+/**
+ * SUBTEST: reserved
+ * Description: Test if device is able to handle stolen phy address error
+ */
+ static void
+create_noncritical_bo_with_exec(int fd, uint32_t *bo, size_t bo_size, uint32_t *vm,
+ uint32_t *exec_queue, struct drm_xe_engine_class_instance *inst,
+ uint64_t addr, struct drm_xe_sync *sync, uint32_t placement,
+ struct drm_xe_exec *exec, uint32_t flags)
+{
+ struct {
+ uint32_t batch[16];
+ uint64_t pad;
+ uint32_t data;
+ } *data;
+ uint64_t batch_offset;
+ uint64_t batch_addr;
+ uint64_t sdi_offset;
+ uint64_t sdi_addr;
+ int b = 0;
+
+ *vm = xe_vm_create(fd, 0, 0);
+
+ igt_require_f(placement, "Device doesn't support such memory region\n");
+
+ *bo = xe_bo_create(fd, 0, bo_size, placement, flags);
+ data = xe_bo_map(fd, *bo, bo_size);
+ xe_vm_bind_async(fd, *vm, 0, *bo, 0, addr, bo_size, sync, 1);
+ memset(data, 0, bo_size);
+
+ *exec_queue = xe_exec_queue_create(fd, *vm, inst, 0);
+ batch_offset = (char *)&data[0].batch - (char *)data;
+ batch_addr = addr + batch_offset;
+ sdi_offset = (char *)&data[0].data - (char *)data;
+ sdi_addr = addr + sdi_offset;
+
+ data[0].batch[b++] = MI_STORE_DWORD_IMM_GEN4;
+ data[0].batch[b++] = sdi_addr;
+ data[0].batch[b++] = sdi_addr >> 32;
+ data[0].batch[b++] = 0xc0ffee;
+ data[0].batch[b++] = MI_BATCH_BUFFER_END;
+
+ sync->flags |= DRM_XE_SYNC_FLAG_SIGNAL;
+
+ exec->exec_queue_id = *exec_queue;
+ exec->address = batch_addr;
+}
+
+ static void
+create_noncritical_user_bo(int fd, uint32_t *bo, size_t bo_size, uint32_t placement,
+ void *map, uint32_t flags)
+{
+
+ igt_require_f(placement, "Device doesn't support such memory region\n");
+
+ *bo = xe_bo_create(fd, 0, bo_size, placement, flags);
+
+ map = xe_bo_map(fd, *bo, bo_size);
+ strcpy(map, "Write some data to the BO!");
+}
+
+igt_main
+{
+ int fd;
+ int dir, ret;
+#define MODE_SIZE 2
+ char mode[MODE_SIZE];
+ uint16_t devid;
+ enum mempage_offline_mode {
+ MEMPAGE_OFFLINE_UNALLOCATED = 0,
+ MEMPAGE_OFFLINE_USER_ALLOCATED = 1,
+ MEMPAGE_OFFLINE_KERNEL_USER_GGTT_ALLOCATED = 2,
+ MEMPAGE_OFFLINE_KERNEL_USER_PPGTT_ALLOCATED = 3,
+ MEMPAGE_OFFLINE_KERNEL_CRITICAL_ALLOCATED = 4,
+ MEMPAGE_OFFLINE_RESERVED = 5,
+ };
+
+ igt_fixture {
+
+ fd = drm_open_driver(DRIVER_XE);
+ devid = intel_get_drm_devid(fd);
+ igt_require(intel_get_device_info(devid)->is_crescentisland);
+ igt_require(igt_debugfs_exists(fd, "invalid_addr_vram0", O_RDWR));
+ dir = igt_debugfs_dir(fd);
+ }
+
+ igt_subtest("unallocated") {
+ snprintf(mode, sizeof(mode), "%d", MEMPAGE_OFFLINE_UNALLOCATED);
+ ret = igt_sysfs_write(dir, "invalid_addr_vram0", mode, sizeof(mode));
+ igt_assert_f(ret == MODE_SIZE, "Test failed with err:%d\n", ret);
+ }
+ igt_subtest("user-allocated") {
+ uint32_t bo;
+ void *map;
+ size_t bo_size = xe_get_default_alignment(fd);
+ create_noncritical_user_bo(fd, &bo, bo_size, vram_memory(fd, 0), map,
+ DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
+ snprintf(mode, sizeof(mode), "%d", MEMPAGE_OFFLINE_USER_ALLOCATED);
+ ret = igt_sysfs_write(dir, "invalid_addr_vram0", mode, sizeof(mode));
+ igt_assert_f(ret == MODE_SIZE, "Test failed with err:%d\n", ret);
+ munmap(map, bo_size);
+ gem_close(fd, bo);
+ }
+ igt_subtest("user-ggtt-allocated") {
+ uint32_t bo, vm, exec_queue;
+ struct drm_xe_sync sync = {
+ .handle = syncobj_create(fd, 0),
+ .type = DRM_XE_SYNC_TYPE_SYNCOBJ,
+ .flags = DRM_XE_SYNC_FLAG_SIGNAL,
+ };
+
+ struct drm_xe_exec exec = {
+ .num_batch_buffer = 1,
+ .num_syncs = 1,
+ .syncs = to_user_pointer(&sync),
+ };
+
+ struct drm_xe_engine_class_instance inst = {
+ .engine_class = DRM_XE_ENGINE_CLASS_RENDER,
+ };
+ uint64_t addr = 0x1a0000;
+ size_t bo_size = xe_get_default_alignment(fd);
+ create_noncritical_bo_with_exec(fd, &bo, bo_size, &vm, &exec_queue, &inst,
+ addr, &sync, vram_memory(fd, 0), &exec,
+ DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
+ snprintf(mode, sizeof(mode), "%d", MEMPAGE_OFFLINE_KERNEL_USER_GGTT_ALLOCATED);
+ igt_assert_eq(__xe_exec(fd, &exec), 0);
+ ret = igt_sysfs_write(dir, "invalid_addr_vram0", mode, sizeof(mode));
+ igt_assert_neq(__xe_exec(fd, &exec), 0);
+ xe_exec_queue_destroy(fd, exec_queue);
+ xe_vm_destroy(fd, vm);
+ gem_close(fd, bo);
+ igt_assert_f(ret == MODE_SIZE, "Test failed with err:%d\n", ret);
+ }
+ igt_subtest("user-ppgtt-allocated") {
+ uint32_t bo, vm, exec_queue;
+ struct drm_xe_sync sync = {
+ .handle = syncobj_create(fd, 0),
+ .type = DRM_XE_SYNC_TYPE_SYNCOBJ,
+ .flags = DRM_XE_SYNC_FLAG_SIGNAL,
+ };
+ struct drm_xe_exec exec = {
+ .num_batch_buffer = 1,
+ .num_syncs = 1,
+ .syncs = to_user_pointer(&sync),
+ };
+
+ struct drm_xe_engine_class_instance inst = {
+ .engine_class = DRM_XE_ENGINE_CLASS_RENDER,
+ };
+ uint64_t addr = 0x1a0000;
+ size_t bo_size = xe_get_default_alignment(fd);
+ create_noncritical_bo_with_exec(fd, &bo, bo_size, &vm, &exec_queue, &inst,
+ addr, &sync, vram_memory(fd, 0), &exec,
+ DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM);
+ igt_assert_eq(__xe_exec(fd, &exec), 0);
+ snprintf(mode, sizeof(mode), "%d", MEMPAGE_OFFLINE_KERNEL_USER_PPGTT_ALLOCATED);
+ ret = igt_sysfs_write(dir, "invalid_addr_vram0", mode, sizeof(mode));
+ igt_assert_neq(__xe_exec(fd, &exec), 0);
+ xe_exec_queue_destroy(fd, exec_queue);
+ xe_vm_destroy(fd, vm);
+ gem_close(fd, bo);
+ igt_assert_f(ret == MODE_SIZE, "Test failed with err:%d\n", ret);
+ }
+ igt_subtest("critical-allocated") {
+ snprintf(mode, sizeof(mode), "%d", MEMPAGE_OFFLINE_KERNEL_CRITICAL_ALLOCATED);
+ ret = igt_sysfs_write(dir, "invalid_addr_vram0", mode, sizeof(mode));
+ igt_assert_f(ret == MODE_SIZE, "Test failed with err:%d\n", ret);
+ }
+ igt_subtest("reserved") {
+ snprintf(mode, sizeof(mode), "%d", MEMPAGE_OFFLINE_RESERVED);
+ ret = igt_sysfs_write(dir, "invalid_addr_vram0", mode, sizeof(mode));
+ igt_assert_f(ret == MODE_SIZE, "Test failed with err:%d\n", ret);
+ }
+ igt_fixture {
+ close(dir);
+ drm_close_driver(fd);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index cecb4a8ae..f38f5a88b 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -169,6 +169,7 @@ intel_i915_progs = [
'gem_lut_handle',
'gem_madvise',
'gem_media_fill',
+ 'xe_mempage_offline',
'gem_media_vme',
'gem_mmap',
'gem_mmap_gtt',
--
2.52.0
reply other threads:[~2026-03-27 11:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20260327113651.2677665-2-tejas.upadhyay@intel.com \
--to=tejas.upadhyay@intel.com \
--cc=himal.prasad.ghimiray@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=matthew.auld@intel.com \
--cc=matthew.brost@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox