igt-dev.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH i-g-t 0/5]
@ 2025-08-29 14:54 nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure nishit.sharma
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: nishit.sharma @ 2025-08-29 14:54 UTC (permalink / raw)
  To: igt-dev, pravalika.gurram, himal.prasad.ghimiray, matthew.brost,
	nishit.sharma

From: Nishit Sharma <nishit.sharma@intel.com>

Revision 1:
Added madvise tests in IGT which validate different features related
to attributes passed. Madvise tests related to Atomic operation,
Preferred Loc have been added and validated. Madvise tests are called as
part of different struct section and available as madvise-<test-name> in
list of subtests.

ver2:
- added back subtest which was deleted due to rebasing

ver3:
- added variable deleted during rebase.

ver4:
- Removed redundant loop for multi-vma test. Instead added multi-vma check
  in which is manipulating address, batch addreess only and the
  remaining execution is done as per default flow.
- Passed region DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC in prefetch tests.

ver5:
- Incorporated review comments
- Removed section from test which was not required
- Added subtests description
- Tests executed on latest drm tip

ver6:
- Incorporated review comments
- Removed dead code checked-in due to rebasing
- Added few more sub-tests under struct section msections
- Added description of new sub-tests

Nishit Sharma (5):
  DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure
  lib/xe: Add xe_vm_madvise ioctl support
  lib/xe: Add Helper to get memory attributes
  tests/intel/xe_exec_system_allocator: Add preferred-loc-smem test
  tests/intel/xe_exec_system_allocator: Add atomic_batch test in IGT

 include/drm-uapi/xe_drm.h              | 289 +++++++++++-
 lib/xe/xe_ioctl.c                      | 149 ++++++
 lib/xe/xe_ioctl.h                      |   9 +-
 tests/intel/xe_exec_system_allocator.c | 630 ++++++++++++++++++++++---
 4 files changed, 997 insertions(+), 80 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH i-g-t 1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure
  2025-08-29 14:54 [PATCH i-g-t 0/5] nishit.sharma
@ 2025-08-29 14:54 ` nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 2/5] lib/xe: Add xe_vm_madvise ioctl support nishit.sharma
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: nishit.sharma @ 2025-08-29 14:54 UTC (permalink / raw)
  To: igt-dev, pravalika.gurram, himal.prasad.ghimiray, matthew.brost,
	nishit.sharma

From: Nishit Sharma <nishit.sharma@intel.com>

Defined IOCTL number for madvise operation. Added drm_xe_madvise
which is passed as Input to MADVISE IOCTL.

Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
 include/drm-uapi/xe_drm.h | 289 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 281 insertions(+), 8 deletions(-)

diff --git a/include/drm-uapi/xe_drm.h b/include/drm-uapi/xe_drm.h
index a52f95593..e9a27a844 100644
--- a/include/drm-uapi/xe_drm.h
+++ b/include/drm-uapi/xe_drm.h
@@ -3,8 +3,8 @@
  * Copyright © 2023 Intel Corporation
  */
 
-#ifndef _XE_DRM_H_
-#define _XE_DRM_H_
+#ifndef _UAPI_XE_DRM_H_
+#define _UAPI_XE_DRM_H_
 
 #include "drm.h"
 
@@ -81,6 +81,8 @@ extern "C" {
  *  - &DRM_IOCTL_XE_EXEC
  *  - &DRM_IOCTL_XE_WAIT_USER_FENCE
  *  - &DRM_IOCTL_XE_OBSERVATION
+ *  - &DRM_IOCTL_XE_MADVISE
+ *  - &DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS
  */
 
 /*
@@ -102,6 +104,8 @@ extern "C" {
 #define DRM_XE_EXEC			0x09
 #define DRM_XE_WAIT_USER_FENCE		0x0a
 #define DRM_XE_OBSERVATION		0x0b
+#define DRM_XE_MADVISE			0x0c
+#define DRM_XE_VM_QUERY_MEM_REGION_ATTRS	0x0d
 
 /* Must be kept compact -- no holes */
 
@@ -117,6 +121,8 @@ extern "C" {
 #define DRM_IOCTL_XE_EXEC			DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec)
 #define DRM_IOCTL_XE_WAIT_USER_FENCE		DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
 #define DRM_IOCTL_XE_OBSERVATION		DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param)
+#define DRM_IOCTL_XE_MADVISE			DRM_IOW(DRM_COMMAND_BASE + DRM_XE_MADVISE, struct drm_xe_madvise)
+#define DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS	DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_QUERY_MEM_REGION_ATTRS, struct drm_xe_vm_query_mem_range_attr)
 
 /**
  * DOC: Xe IOCTL Extensions
@@ -134,7 +140,7 @@ extern "C" {
  * redefine the interface more easily than an ever growing struct of
  * increasing complexity, and for large parts of that interface to be
  * entirely optional. The downside is more pointer chasing; chasing across
- * the boundary with pointers encapsulated inside u64.
+ * the __user boundary with pointers encapsulated inside u64.
  *
  * Example chaining:
  *
@@ -925,9 +931,9 @@ struct drm_xe_gem_mmap_offset {
  *  - %DRM_XE_VM_CREATE_FLAG_LR_MODE - An LR, or Long Running VM accepts
  *    exec submissions to its exec_queues that don't have an upper time
  *    limit on the job execution time. But exec submissions to these
- *    don't allow any of the flags DRM_XE_SYNC_FLAG_SYNCOBJ,
- *    DRM_XE_SYNC_FLAG_TIMELINE_SYNCOBJ, DRM_XE_SYNC_FLAG_DMA_BUF,
- *    used as out-syncobjs, that is, together with DRM_XE_SYNC_FLAG_SIGNAL.
+ *    don't allow any of the sync types DRM_XE_SYNC_TYPE_SYNCOBJ,
+ *    DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ, used as out-syncobjs, that is,
+ *    together with sync flag DRM_XE_SYNC_FLAG_SIGNAL.
  *    LR VMs can be created in recoverable page-fault mode using
  *    DRM_XE_VM_CREATE_FLAG_FAULT_MODE, if the device supports it.
  *    If that flag is omitted, the UMD can not rely on the slightly
@@ -1003,6 +1009,10 @@ struct drm_xe_vm_destroy {
  *    valid on VMs with DRM_XE_VM_CREATE_FLAG_FAULT_MODE set. The CPU address
  *    mirror flag are only valid for DRM_XE_VM_BIND_OP_MAP operations, the BO
  *    handle MBZ, and the BO offset MBZ.
+ *
+ * The @prefetch_mem_region_instance for %DRM_XE_VM_BIND_OP_PREFETCH can also be:
+ *  - %DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, which ensures prefetching occurs in
+ *    the memory region advised by madvise.
  */
 struct drm_xe_vm_bind_op {
 	/** @extensions: Pointer to the first extension struct, if any */
@@ -1108,6 +1118,7 @@ struct drm_xe_vm_bind_op {
 	/** @flags: Bind flags */
 	__u32 flags;
 
+#define DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC	-1
 	/**
 	 * @prefetch_mem_region_instance: Memory region to prefetch VMA to.
 	 * It is a region instance, not a mask.
@@ -1394,7 +1405,7 @@ struct drm_xe_sync {
 
 	/**
 	 * @timeline_value: Input for the timeline sync object. Needs to be
-	 * different than 0 when used with %DRM_XE_SYNC_FLAG_TIMELINE_SYNCOBJ.
+	 * different than 0 when used with %DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ.
 	 */
 	__u64 timeline_value;
 
@@ -1974,8 +1985,270 @@ struct drm_xe_query_eu_stall {
 	__u64 sampling_rates[];
 };
 
+/**
+ * struct drm_xe_madvise - Input of &DRM_IOCTL_XE_MADVISE
+ *
+ * This structure is used to set memory attributes for a virtual address range
+ * in a VM. The type of attribute is specified by @type, and the corresponding
+ * union member is used to provide additional parameters for @type.
+ *
+ * Supported attribute types:
+ * - DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC: Set preferred memory location.
+ * - DRM_XE_MEM_RANGE_ATTR_ATOMIC: Set atomic access policy.
+ * - DRM_XE_MEM_RANGE_ATTR_PAT: Set page attribute table index.
+ *
+ * Example:
+ *
+ * .. code-block:: C
+ *
+ * struct drm_xe_madvise madvise = {
+ *          .vm_id = vm_id,
+ *          .start = 0x100000,
+ *          .range = 0x2000,
+ *          .type = DRM_XE_MEM_RANGE_ATTR_ATOMIC,
+ *          .atomic_val = DRM_XE_ATOMIC_DEVICE,
+ *          .pad = 0,
+ *         };
+ *
+ * ioctl(fd, DRM_IOCTL_XE_MADVISE, &madvise);
+ *
+ */
+struct drm_xe_madvise {
+	/** @extensions: Pointer to the first extension struct, if any */
+	__u64 extensions;
+
+	/** @start: start of the virtual address range */
+	__u64 start;
+
+	/** @range: size of the virtual address range */
+	__u64 range;
+
+	/** @vm_id: vm_id of the virtual range */
+	__u32 vm_id;
+
+#define DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC	0
+#define DRM_XE_MEM_RANGE_ATTR_ATOMIC		1
+#define DRM_XE_MEM_RANGE_ATTR_PAT		2
+	/** @type: type of attribute */
+	__u32 type;
+
+	union {
+		/**
+		 * @preferred_mem_loc: preferred memory location
+		 *
+		 * Used when @type == DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC
+		 *
+		 * Supported values for @preferred_mem_loc.devmem_fd:
+		 * - DRM_XE_PREFERRED_LOC_DEFAULT_DEVICE: set vram of faulting tile as preferred loc
+		 * - DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM: set smem as preferred loc
+		 *
+		 * Supported values for @preferred_mem_loc.migration_policy:
+		 * - DRM_XE_MIGRATE_ALL_PAGES
+		 * - DRM_XE_MIGRATE_ONLY_SYSTEM_PAGES
+		 */
+		struct {
+#define DRM_XE_PREFERRED_LOC_DEFAULT_DEVICE	0
+#define DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM	-1
+			/** @preferred_mem_loc.devmem_fd: fd for preferred loc */
+			__u32 devmem_fd;
+
+#define DRM_XE_MIGRATE_ALL_PAGES		0
+#define DRM_XE_MIGRATE_ONLY_SYSTEM_PAGES	1
+			/** @preferred_mem_loc.migration_policy: Page migration policy */
+			__u16 migration_policy;
+
+			/** @preferred_mem_loc.pad : MBZ */
+			__u16 pad;
+
+			/** @preferred_mem_loc.reserved : Reserved */
+			__u64 reserved;
+		} preferred_mem_loc;
+
+		/**
+		 * @atomic: Atomic access policy
+		 *
+		 * Used when @type == DRM_XE_MEM_RANGE_ATTR_ATOMIC.
+		 *
+		 * Supported values for @atomic.val:
+		 * - DRM_XE_ATOMIC_UNDEFINED: Undefined or default behaviour
+		 *   Support both GPU and CPU atomic operations for system allocator
+		 *   Support GPU atomic operations for normal(bo) allocator
+		 * - DRM_XE_ATOMIC_DEVICE: Support GPU atomic operations
+		 * - DRM_XE_ATOMIC_GLOBAL: Support both GPU and CPU atomic operations
+		 * - DRM_XE_ATOMIC_CPU: Support CPU atomic
+		 */
+		struct {
+#define DRM_XE_ATOMIC_UNDEFINED	0
+#define DRM_XE_ATOMIC_DEVICE	1
+#define DRM_XE_ATOMIC_GLOBAL	2
+#define DRM_XE_ATOMIC_CPU	3
+			/** @atomic.val: value of atomic operation */
+			__u32 val;
+
+			/** @atomic.pad: MBZ */
+			__u32 pad;
+
+			/** @atomic.reserved: Reserved */
+			__u64 reserved;
+		} atomic;
+
+		/**
+		 * @pat_index: Page attribute table index
+		 *
+		 * Used when @type == DRM_XE_MEM_RANGE_ATTR_PAT.
+		 */
+		struct {
+			/** @pat_index.val: PAT index value */
+			__u32 val;
+
+			/** @pat_index.pad: MBZ */
+			__u32 pad;
+
+			/** @pat_index.reserved: Reserved */
+			__u64 reserved;
+		} pat_index;
+	};
+
+	/** @reserved: Reserved */
+	__u64 reserved[2];
+};
+
+/**
+ * struct drm_xe_mem_range_attr - Output of &DRM_IOCTL_XE_VM_QUERY_MEM_RANGES_ATTRS
+ *
+ * This structure is provided by userspace and filled by KMD in response to the
+ * DRM_IOCTL_XE_VM_QUERY_MEM_RANGES_ATTRS ioctl. It describes memory attributes of
+ * a memory ranges within a user specified address range in a VM.
+ *
+ * The structure includes information such as atomic access policy,
+ * page attribute table (PAT) index, and preferred memory location.
+ * Userspace allocates an array of these structures and passes a pointer to the
+ * ioctl to retrieve attributes for each memory ranges
+ *
+ * @extensions: Pointer to the first extension struct, if any
+ * @start: Start address of the memory range
+ * @end: End address of the virtual memory range
+ *
+ */
+struct drm_xe_mem_range_attr {
+	 /** @extensions: Pointer to the first extension struct, if any */
+	__u64 extensions;
+
+	/** @start: start of the memory range */
+	__u64 start;
+
+	/** @end: end of the memory range */
+	__u64 end;
+
+	/** @preferred_mem_loc: preferred memory location */
+	struct {
+		/** @preferred_mem_loc.devmem_fd: fd for preferred loc */
+		__u32 devmem_fd;
+
+		/** @preferred_mem_loc.migration_policy: Page migration policy */
+		__u32 migration_policy;
+	} preferred_mem_loc;
+
+	struct {
+		/** @atomic.val: atomic attribute */
+		__u32 val;
+
+		/** @atomic.reserved: Reserved */
+		__u32 reserved;
+	} atomic;
+
+	struct {
+		/** @pat_index.val: PAT index */
+		__u32 val;
+
+		/** @pat_index.reserved: Reserved */
+		__u32 reserved;
+	} pat_index;
+
+	/** @reserved: Reserved */
+	__u64 reserved[2];
+};
+
+/**
+ * struct drm_xe_vm_query_mem_range_attr - Input of &DRM_IOCTL_XE_VM_QUERY_MEM_ATTRIBUTES
+ *
+ * This structure is used to query memory attributes of memory regions
+ * within a user specified address range in a VM. It provides detailed
+ * information about each memory range, including atomic access policy,
+ * page attribute table (PAT) index, and preferred memory location.
+ *
+ * Userspace first calls the ioctl with @num_mem_ranges = 0,
+ * @sizeof_mem_ranges_attr = 0 and @vector_of_vma_mem_attr = NULL to retrieve
+ * the number of memory regions and size of each memory range attribute.
+ * Then, it allocates a buffer of that size and calls the ioctl again to fill
+ * the buffer with memory range attributes.
+ *
+ * If second call fails with -ENOSPC, it means memory ranges changed between
+ * first call and now, retry IOCTL again with @num_mem_ranges = 0,
+ * @sizeof_mem_ranges_attr = 0 and @vector_of_vma_mem_attr = NULL followed by
+ * Second ioctl call.
+ *
+ * Example:
+ *
+ * .. code-block:: C
+ *    struct drm_xe_vm_query_mem_range_attr query = {
+ *         .vm_id = vm_id,
+ *         .start = 0x100000,
+ *         .range = 0x2000,
+ *     };
+ *
+ *    // First ioctl call to get num of mem regions and sizeof each attribute
+ *    ioctl(fd, DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS, &query);
+ *
+ *    // Allocate buffer for the memory region attributes
+ *    void *ptr = malloc(query.num_mem_ranges * query.sizeof_mem_range_attr);
+ *
+ *    query.vector_of_mem_attr = (uintptr_t)ptr;
+ *
+ *    // Second ioctl call to actually fill the memory attributes
+ *    ioctl(fd, DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS, &query);
+ *
+ *    // Iterate over the returned memory region attributes
+ *    for (unsigned int i = 0; i < query.num_mem_ranges; ++i) {
+ *       struct drm_xe_mem_range_attr *attr = (struct drm_xe_mem_range_attr *)ptr;
+ *
+ *       // Do something with attr
+ *
+ *       // Move pointer by one entry
+ *       ptr += query.sizeof_mem_range_attr;
+ *     }
+ *
+ *    free(ptr);
+ */
+struct drm_xe_vm_query_mem_range_attr {
+	/** @extensions: Pointer to the first extension struct, if any */
+	__u64 extensions;
+
+	/** @vm_id: vm_id of the virtual range */
+	__u32 vm_id;
+
+	/** @num_mem_ranges: number of mem_ranges in range */
+	__u32 num_mem_ranges;
+
+	/** @start: start of the virtual address range */
+	__u64 start;
+
+	/** @range: size of the virtual address range */
+	__u64 range;
+
+	/** @sizeof_mem_range_attr: size of struct drm_xe_mem_range_attr */
+	__u64 sizeof_mem_range_attr;
+
+	/** @vector_of_ops: userptr to array of struct drm_xe_mem_range_attr */
+	__u64 vector_of_mem_attr;
+
+	/** @reserved: Reserved */
+	__u64 reserved[2];
+
+};
+
 #if defined(__cplusplus)
 }
 #endif
 
-#endif /* _XE_DRM_H_ */
+#endif /* _UAPI_XE_DRM_H_ */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH i-g-t 2/5] lib/xe: Add xe_vm_madvise ioctl support
  2025-08-29 14:54 [PATCH i-g-t 0/5] nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure nishit.sharma
@ 2025-08-29 14:54 ` nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 3/5] lib/xe: Add Helper to get memory attributes nishit.sharma
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: nishit.sharma @ 2025-08-29 14:54 UTC (permalink / raw)
  To: igt-dev, pravalika.gurram, himal.prasad.ghimiray, matthew.brost,
	nishit.sharma

From: Nishit Sharma <nishit.sharma@intel.com>

xe_vm_madvise() defined which issues madvise ioctl DRM_IOCTL_XE_MADVISE for
VM region advising the driver about expected usage or memory policy for
specified address range. MADVISE ioctl requires pointer to drm_xe_madvise
structure as one of the inputs. Depending upon type of madvise operation
like Atomic, Preferred LOC or PAT required members of drm_xe_madvise
structure are initialized and passed in MADVISE ioctl.

Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
 lib/xe/xe_ioctl.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/xe/xe_ioctl.h |  5 +++-
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/lib/xe/xe_ioctl.c b/lib/xe/xe_ioctl.c
index 1e95af409..b64ba3106 100644
--- a/lib/xe/xe_ioctl.c
+++ b/lib/xe/xe_ioctl.c
@@ -585,3 +585,61 @@ int64_t xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
 	igt_assert_eq(__xe_wait_ufence(fd, addr, value, exec_queue, &timeout), 0);
 	return timeout;
 }
+
+int __xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range,
+		    uint64_t ext, uint32_t type, uint32_t op_val, uint16_t policy)
+{
+	struct drm_xe_madvise madvise = {
+		.type = type,
+		.extensions = ext,
+		.vm_id = vm,
+		.start = addr,
+		.range = range,
+	};
+
+	switch (type) {
+	case DRM_XE_MEM_RANGE_ATTR_ATOMIC:
+		madvise.atomic.val = op_val;
+		break;
+	case DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC:
+		madvise.preferred_mem_loc.devmem_fd = op_val;
+		madvise.preferred_mem_loc.migration_policy = policy;
+		igt_debug("madvise.preferred_mem_loc.devmem_fd = %d\n",
+			  madvise.preferred_mem_loc.devmem_fd);
+		break;
+	case DRM_XE_MEM_RANGE_ATTR_PAT:
+		madvise.pat_index.val = op_val;
+		break;
+	default:
+		igt_warn("Unknown attribute\n");
+		return -EINVAL;
+	}
+
+	if (igt_ioctl(fd, DRM_IOCTL_XE_MADVISE, &madvise))
+		return -errno;
+
+	return 0;
+}
+
+/**
+ * xe_vm_madvise:
+ * @fd: xe device fd
+ * @vm: vm_id of the virtual range
+ * @addr: start of the virtual address range
+ * @range: size of the virtual address range
+ * @ext: Pointer to the first extension struct, if any
+ * @type: type of attribute
+ * @op_val: fd/atomic value/pat index, depending upon type of operation
+ * @policy: Page migration policy
+ *
+ * Function initializes different members of struct drm_xe_madvise and calls
+ * MADVISE IOCTL .
+ *
+ * Returns 0 if success and asserts otherwise.
+ */
+int xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range,
+		  uint64_t ext, uint32_t type, uint32_t op_val, uint16_t policy)
+{
+	igt_assert_eq(__xe_vm_madvise(fd, vm, addr, range, ext, type, op_val, policy), 0);
+	return 0;
+}
diff --git a/lib/xe/xe_ioctl.h b/lib/xe/xe_ioctl.h
index 6302d1a7d..a5996cf65 100644
--- a/lib/xe/xe_ioctl.h
+++ b/lib/xe/xe_ioctl.h
@@ -99,5 +99,8 @@ int __xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
 		     uint32_t exec_queue, int64_t *timeout);
 int64_t xe_wait_ufence(int fd, uint64_t *addr, uint64_t value,
 		       uint32_t exec_queue, int64_t timeout);
-
+int __xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range, uint64_t ext,
+		    uint32_t type, uint32_t op_val, uint16_t policy);
+int xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range, uint64_t ext,
+		  uint32_t type, uint32_t op_val, uint16_t policy);
 #endif /* XE_IOCTL_H */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH i-g-t 3/5] lib/xe: Add Helper to get memory attributes
  2025-08-29 14:54 [PATCH i-g-t 0/5] nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 2/5] lib/xe: Add xe_vm_madvise ioctl support nishit.sharma
@ 2025-08-29 14:54 ` nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 4/5] tests/intel/xe_exec_system_allocator: Add preferred-loc-smem test nishit.sharma
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: nishit.sharma @ 2025-08-29 14:54 UTC (permalink / raw)
  To: igt-dev, pravalika.gurram, himal.prasad.ghimiray, matthew.brost,
	nishit.sharma

From: Nishit Sharma <nishit.sharma@intel.com>

xe_vm_print_mem_attr_values_in_range() function added which calls
QUERY_MEM_RANGES_ATTRS ioctl to get different memory attributes from KMD
and then prints memory attributes returned by KMD for different access
policies like atomic access, preferred loc and pat index.

Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
 lib/xe/xe_ioctl.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/xe/xe_ioctl.h |  4 +++
 2 files changed, 96 insertions(+)

diff --git a/lib/xe/xe_ioctl.c b/lib/xe/xe_ioctl.c
index b64ba3106..f393aaf92 100644
--- a/lib/xe/xe_ioctl.c
+++ b/lib/xe/xe_ioctl.c
@@ -57,6 +57,98 @@ uint64_t xe_bb_size(int fd, uint64_t reqsize)
 	             xe_get_default_alignment(fd));
 }
 
+int xe_vm_number_vmas_in_range(int fd, struct drm_xe_vm_query_mem_range_attr *vmas_attr)
+{
+	if (igt_ioctl(fd, DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS, vmas_attr))
+		return -errno;
+	return 0;
+}
+
+int xe_vm_vma_attrs(int fd, struct drm_xe_vm_query_mem_range_attr *vmas_attr,
+		    struct drm_xe_mem_range_attr *mem_attr)
+{
+	if (!mem_attr)
+		return -EINVAL;
+
+	vmas_attr->vector_of_mem_attr = (uintptr_t)mem_attr;
+
+	if (igt_ioctl(fd, DRM_IOCTL_XE_VM_QUERY_MEM_RANGE_ATTRS, vmas_attr))
+		return -errno;
+
+	return 0;
+}
+
+/**
+ * xe_vm_print_mem_attr_values_in_range:
+ * @fd: xe device fd
+ * @vm: vm_id of the virtual range
+ * @start: start of the virtual address range
+ * @range: size of the virtual address range
+ *
+ * Calls QUERY_MEM_RANGES_ATTRS ioctl to get memory attributes for different
+ * memory ranges from KMD. prints memory attributes as returned by KMD for
+ * atomic, prefrred loc and pat index types.
+ *
+ * Returns 0 for success or error for failure
+ */
+
+int xe_vm_print_mem_attr_values_in_range(int fd, uint32_t vm, uint64_t start, uint64_t range)
+{
+
+	void *ptr_start, *ptr;
+	int err;
+	struct drm_xe_vm_query_mem_range_attr query = {
+		.vm_id = vm,
+		.start = start,
+		.range = range,
+		.num_mem_ranges = 0,
+		.sizeof_mem_range_attr = 0,
+		.vector_of_mem_attr = (uintptr_t)NULL,
+	};
+
+	igt_debug("mem_attr_values_in_range called start = %"PRIu64"\n range = %"PRIu64"\n",
+		  start, range);
+
+	err  = xe_vm_number_vmas_in_range(fd, &query);
+	if (err || !query.num_mem_ranges || !query.sizeof_mem_range_attr) {
+		igt_warn("ioctl failed for xe_vm_number_vmas_in_range\n");
+		igt_debug("vmas_in_range err = %d query.num_mem_ranges = %u query.sizeof_mem_range_attr=%lld\n",
+			 err, query.num_mem_ranges, query.sizeof_mem_range_attr);
+		return err;
+	}
+
+	/* Allocate buffer for the memory region attributes */
+	ptr = malloc(query.num_mem_ranges * query.sizeof_mem_range_attr);
+	ptr_start = ptr;
+
+	if (!ptr)
+		return -ENOMEM;
+
+	err = xe_vm_vma_attrs(fd, &query, ptr);
+	if (err) {
+		igt_warn("ioctl failed for vma_attrs err = %d\n", err);
+		return err;
+	}
+
+	/* Iterate over the returned memory region attributes */
+	for (unsigned int i = 0; i < query.num_mem_ranges; ++i) {
+		struct drm_xe_mem_range_attr *mem_attrs = (struct drm_xe_mem_range_attr *)ptr;
+
+		igt_debug("vma_id = %d\nvma_start = 0x%016llx\nvma_end = 0x%016llx\n"
+				"vma:atomic = %d\nvma:pat_index = %d\nvma:preferred_loc_region = %d\n"
+				"vma:preferred_loc_devmem_fd = %d\n\n\n", i, mem_attrs->start,
+				mem_attrs->end,
+				mem_attrs->atomic.val, mem_attrs->pat_index.val,
+				mem_attrs->preferred_mem_loc.migration_policy,
+				mem_attrs->preferred_mem_loc.devmem_fd);
+
+		ptr += query.sizeof_mem_range_attr;
+	}
+
+	free(ptr_start);
+	return 0;
+}
+
 uint32_t xe_vm_create(int fd, uint32_t flags, uint64_t ext)
 {
 	struct drm_xe_vm_create create = {
diff --git a/lib/xe/xe_ioctl.h b/lib/xe/xe_ioctl.h
index a5996cf65..ae16af233 100644
--- a/lib/xe/xe_ioctl.h
+++ b/lib/xe/xe_ioctl.h
@@ -103,4 +103,8 @@ int __xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range, uint64_t
 		    uint32_t type, uint32_t op_val, uint16_t policy);
 int xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range, uint64_t ext,
 		  uint32_t type, uint32_t op_val, uint16_t policy);
+int xe_vm_number_vmas_in_range(int fd, struct drm_xe_vm_query_mem_range_attr *vmas_attr);
+int xe_vm_vma_attrs(int fd, struct drm_xe_vm_query_mem_range_attr *vmas_attr,
+		    struct drm_xe_mem_range_attr *mem_attr);
+int xe_vm_print_mem_attr_values_in_range(int fd, uint32_t vm, uint64_t start, uint64_t range);
 #endif /* XE_IOCTL_H */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH i-g-t 4/5] tests/intel/xe_exec_system_allocator: Add preferred-loc-smem test
  2025-08-29 14:54 [PATCH i-g-t 0/5] nishit.sharma
                   ` (2 preceding siblings ...)
  2025-08-29 14:54 ` [PATCH i-g-t 3/5] lib/xe: Add Helper to get memory attributes nishit.sharma
@ 2025-08-29 14:54 ` nishit.sharma
  2025-08-29 14:54 ` [PATCH i-g-t 5/5] tests/intel/xe_exec_system_allocator: Add atomic_batch test in IGT nishit.sharma
  2025-08-29 19:08 ` ✗ Fi.CI.BUILD: failure for series starting with [i-g-t,1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure Patchwork
  5 siblings, 0 replies; 7+ messages in thread
From: nishit.sharma @ 2025-08-29 14:54 UTC (permalink / raw)
  To: igt-dev, pravalika.gurram, himal.prasad.ghimiray, matthew.brost,
	nishit.sharma

From: Nishit Sharma <nishit.sharma@intel.com>

preferred-loc-smem test introduced which is called in combination with other
tests as well. In this test the buffer object preferred location is
system memory. MADVISE ioctl is called with preferred_loc attribute and
default_system system memory as preferred location.

Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
 tests/intel/xe_exec_system_allocator.c | 225 ++++++++++++++++++++-----
 1 file changed, 187 insertions(+), 38 deletions(-)

diff --git a/tests/intel/xe_exec_system_allocator.c b/tests/intel/xe_exec_system_allocator.c
index 007d9bdc0..70ca5fc2e 100644
--- a/tests/intel/xe_exec_system_allocator.c
+++ b/tests/intel/xe_exec_system_allocator.c
@@ -138,7 +138,6 @@ static void signal_pdata(struct process_data *pdata)
 #define CPU_FAULT_THREADS	(0x1 << 2)
 #define CPU_FAULT_PROCESS	(0x1 << 3)
 #define CPU_FAULT_SAME_PAGE	(0x1 << 4)
-
 static void process_check(void *ptr, uint64_t alloc_size, uint64_t stride,
 			  unsigned int flags)
 {
@@ -406,6 +405,39 @@ static void __aligned_partial_free(struct aligned_alloc_type  *aligned_alloc_typ
 		       aligned_alloc_type->__size - aligned_alloc_type->size - begin_size);
 }
 
+#define MAX_N_EXEC_QUEUES       16
+
+#define MMAP                    (0x1 << 0)
+#define NEW                     (0x1 << 1)
+#define BO_UNMAP                (0x1 << 2)
+#define FREE                    (0x1 << 3)
+#define BUSY                    (0x1 << 4)
+#define BO_MAP                  (0x1 << 5)
+#define RACE                    (0x1 << 6)
+#define SKIP_MEMSET             (0x1 << 7)
+#define FAULT                   (0x1 << 8)
+#define FILE_BACKED             (0x1 << 9)
+#define LOCK                    (0x1 << 10)
+#define MMAP_SHARED             (0x1 << 11)
+#define HUGE_PAGE               (0x1 << 12)
+#define SHARED_ALLOC            (0x1 << 13)
+#define FORK_READ               (0x1 << 14)
+#define FORK_READ_AFTER         (0x1 << 15)
+#define MREMAP                  (0x1 << 16)
+#define DONTUNMAP               (0x1 << 17)
+#define READ_ONLY_REMAP         (0x1 << 18)
+#define SYNC_EXEC               (0x1 << 19)
+#define EVERY_OTHER_CHECK       (0x1 << 20)
+#define MULTI_FAULT             (0x1 << 21)
+#define PREFETCH                (0x1 << 22)
+#define THREADS                 (0x1 << 23)
+#define PROCESSES               (0x1 << 24)
+#define PREFETCH_BENCHMARK      (0x1 << 25)
+#define PREFETCH_SYS_BENCHMARK	(0x1 << 26)
+#define PREFERRED_LOC_SMEM      (0x1 << 27)
+
+#define N_MULTI_FAULT           4
+
 /**
  * SUBTEST: unaligned-alloc
  * Description: allocate unaligned sizes of memory
@@ -460,7 +492,7 @@ many_allocs(int fd, struct drm_xe_engine_class_instance *eci,
 	uint32_t *bos = NULL;
 	struct timespec tv = {};
 	uint64_t submit, read, elapsed;
-	int i;
+	int i, err;
 
 	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE |
 			  DRM_XE_VM_CREATE_FLAG_FAULT_MODE, 0);
@@ -500,6 +532,15 @@ many_allocs(int fd, struct drm_xe_engine_class_instance *eci,
 			alloc.ptr = aligned_alloc(SZ_2M, alloc_size);
 			igt_assert(alloc.ptr);
 		}
+
+		if (flags & PREFERRED_LOC_SMEM) {
+			err = xe_vm_madvise(fd, vm, to_user_pointer(alloc.ptr), alloc_size, 0,
+					    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+					    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
+				if (err)
+					igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size =%"PRIu64"\n",
+						  strerror(errno), vm, to_user_pointer(alloc.ptr), alloc_size);
+		}
 		allocs[i] = alloc;
 
 		touch_all_pages(fd, exec_queue, allocs[i].ptr, alloc_size, stride,
@@ -662,7 +703,7 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 	size_t bo_size = SZ_2M, unmap_offset = 0;
 	uint32_t vm, exec_queue;
 	u64 *exec_ufence = NULL;
-	int i;
+	int i, err;
 	void *old, *new = NULL;
 	struct aligned_alloc_type alloc;
 
@@ -688,6 +729,15 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE, 0, FIVE_SEC);
 	data[0].vm_sync = 0;
 
+	if (flags & PREFERRED_LOC_SMEM) {
+		err = xe_vm_madvise(fd, vm, to_user_pointer(data), bo_size, 0,
+				    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+				    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
+		if (err)
+			igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size = %zu\n",
+				  strerror(errno), vm, to_user_pointer(data), bo_size);
+	}
+
 	exec_ufence = mmap(NULL, SZ_4K, PROT_READ |
 			   PROT_WRITE, MAP_SHARED |
 			   MAP_ANONYMOUS, -1, 0);
@@ -747,38 +797,6 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 	xe_vm_destroy(fd, vm);
 }
 
-#define MAX_N_EXEC_QUEUES	16
-
-#define MMAP			(0x1 << 0)
-#define NEW			(0x1 << 1)
-#define BO_UNMAP		(0x1 << 2)
-#define FREE			(0x1 << 3)
-#define BUSY			(0x1 << 4)
-#define BO_MAP			(0x1 << 5)
-#define RACE			(0x1 << 6)
-#define SKIP_MEMSET		(0x1 << 7)
-#define FAULT			(0x1 << 8)
-#define FILE_BACKED		(0x1 << 9)
-#define LOCK			(0x1 << 10)
-#define MMAP_SHARED		(0x1 << 11)
-#define HUGE_PAGE		(0x1 << 12)
-#define SHARED_ALLOC		(0x1 << 13)
-#define FORK_READ		(0x1 << 14)
-#define FORK_READ_AFTER		(0x1 << 15)
-#define MREMAP			(0x1 << 16)
-#define DONTUNMAP		(0x1 << 17)
-#define READ_ONLY_REMAP		(0x1 << 18)
-#define SYNC_EXEC		(0x1 << 19)
-#define EVERY_OTHER_CHECK	(0x1 << 20)
-#define MULTI_FAULT		(0x1 << 21)
-#define PREFETCH		(0x1 << 22)
-#define THREADS			(0x1 << 23)
-#define PROCESSES		(0x1 << 24)
-#define PREFETCH_BENCHMARK	(0x1 << 25)
-#define PREFETCH_SYS_BENCHMARK	(0x1 << 26)
-
-#define N_MULTI_FAULT		4
-
 /**
  * SUBTEST: once-%s
  * Description: Run %arg[1] system allocator test only once
@@ -951,6 +969,80 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
  * @mmap-new-nomemset:			mmap a new buffer for each exec, skip memset of buffers
  * @mmap-new-huge-nomemset:		mmap huge page new buffer for each exec, skip memset of buffers
  * @mmap-new-race-nomemset:		mmap a new buffer for each exec with race between cpu and gpu access, skip memset of buffers
+ * @free-nomemset-preferred-loc-smem:	malloc and free buffer for each exec and perform preferred loc madvise operation
+ * @free-preferred-loc-smem:		free buffer for each exec and perform preferred loc madvise operation
+ * @free-race-nomemset-preferred-loc-smem:	free buffer for each exec with race between cpu and gpu access and perform madvise operation skipping memset
+ * @free-race-preferred-loc-smem:	free buffer for each exec with race between cpu and gpu access and perform madvise operation
+ * @malloc-bo-unmap-nomemset-preferred-loc-smem:	malloc single buffer for all execs, bind and unbind a BO to same address, skip memset and perform madvise operation
+ * @malloc-busy-nomemset-preferred-loc-smem:	malloc single buffer for all execs, try to unbind while buffer valid, skip memset of buffers and perform madvise operation
+ * @malloc-busy-preferred-loc-smem:	malloc single buffer for all execs, try to unbind while buffer valid and perform madvise operation
+ * @malloc-fork-read-after-preferred-loc-smem:	malloc single buffer for all execs, fork a process to read test output, perform madvise operation
+ * @malloc-fork-read-preferred-loc-smem:	malloc single buffer for all execs, fork a process to read test output, perform madvise operation
+ * @malloc-mlock-nomemset-preferred-loc-smem:	malloc and mlock single buffer for all execs, skip memset of buffers, perform madvise operation
+ * @malloc-mlock-preferred-loc-smem:	malloc and mlock single buffer for all execs, perform madvise operation
+ * @malloc-multi-fault-preferred-loc-smem:	malloc single buffer for all execs and perform madvise operation
+ * @malloc-nomemset-preferred-loc-smem:	malloc single buffer for all execs, skip memset of buffers and perform madvise operation
+ * @malloc-preferred-loc-smem:	malloc single buffer for all execs, issue a command which will trigger multiple faults, perform madvise operation
+ * @malloc-prefetch-preferred-loc-smem:	malloc single buffer for all execs, prefetch buffer before each exec, perform madvise operation
+ * @malloc-prefetch-race-preferred-loc-smem:	malloc single buffer for all execs, prefetch buffer before each exec, perform madvise operation
+ * @malloc-race-nomemset-preferred-loc-smem:	malloc single buffer for all execs with race between cpu and gpu access, perform madvise operation
+ * @malloc-race-preferred-loc-smem:	malloc single buffer for all execs with race between cpu and gpu access, perform madvise operation
+ * @free-race-nomemset-preferred-loc-smem: malloc and free buffer for each exec with race between cpu and gpu access, perform madvise operation
+ * @free-race-preferred-loc-smem:	malloc and free buffer for each exec with race between cpu and gpu access, perform madvise operation
+ * @malloc-bo-unmap-nomemset-preferred-loc-smem: malloc single buffer for all execs, bind and unbind a BO to same address before execs, perform madvise operation
+ * @malloc-bo-unmap-preferred-loc-smem:	malloc single buffer for all execs and perform madvise operation
+ * @malloc-busy-nomemset-preferred-loc-smem:	malloc single buffer for all execs and perform madvise operation
+ * @malloc-busy-preferred-loc-smem:	malloc single buffer for all execs and perform madvise
+ * @mmap-file-mlock-nomemset-preferred-loc-smem:	 mmap and mlock single buffer, with file backing, perform madvise
+ * @mmap-file-mlock-preferred-loc-smem:	mmap and mlock single buffer, with file backing, perform madvise
+ * @mmap-file-nomemset-preferred-loc-smem:	mmap single buffer, with file backing and perform madvise
+ * @mmap-file-preferred-loc-smem:	mmap single buffer, with file backing and perform madvise
+ * @mmap-free-huge-nomemset-preferred-loc-smem:	mmap huge page and free buffer for each exec and perform madvise
+ * @mmap-free-huge-preferred-loc-smem:	mmap huge page and free buffer for each exec and perform madvise
+ * @mmap-free-nomemset-preferred-loc-smem:	mmap and free buffer for each exec and perform madvise
+ * @mmap-free-preferred-loc-smem:	mmap and free buffer for each exec and perform madvise
+ * @mmap-free-race-nomemset-preferred-loc-smem:
+ * @mmap-free-race-preferred-loc-smem:
+ * @mmap-huge-nomemset-preferred-loc-smem:
+ * @mmap-huge-preferred-loc-smem:
+ * @mmap-mlock-nomemset-preferred-loc-smem:
+ * @mmap-mlock-preferred-loc-smem:
+ * @mmap-new-huge-nomemset-preferred-loc-smem:
+ * @mmap-new-huge-preferred-loc-smem:
+ * @mmap-new-nomemset-preferred-loc-smem:
+ * @mmap-new-preferred-loc-smem:
+ * @mmap-new-race-nomemset-preferred-loc-smem:
+ * @mmap-new-race-preferred-loc-smem:
+ * @mmap-nomemset-preferred-loc-smem:
+ * @mmap-preferred-loc-smem:
+ * @mmap-prefetch-preferred-loc-smem:
+ * @mmap-prefetch-shared-preferred-loc-smem:
+ * @mmap-race-nomemset-preferred-loc-smem:
+ * @mmap-race-preferred-loc-smem:
+ * @mmap-remap-dontunmap-eocheck-preferred-loc-smem:
+ * @mmap-remap-dontunmap-preferred-loc-smem:
+ * @mmap-remap-eocheck-preferred-loc-smem:
+ * @mmap-remap-preferred-loc-smem:
+ * @mmap-remap-ro-dontunmap-eocheck-preferred-loc-smem:
+ * @mmap-remap-ro-dontunmap-preferred-loc-smem:
+ * @mmap-remap-ro-eocheck-preferred-loc-smem:
+ * @mmap-remap-ro-preferred-loc-smem:
+ * @mmap-shared-nomemset-preferred-loc-smem:
+ * @mmap-shared-preferred-loc-smem:
+ * @mmap-shared-remap-dontunmap-eocheck-preferred-loc-smem:
+ * @mmap-shared-remap-dontunmap-preferred-loc-smem:
+ * @mmap-shared-remap-eocheck-preferred-loc-smem:
+ * @mmap-shared-remap-preferred-loc-smem:
+ * @new-bo-map-nomemset-preferred-loc-smem:
+ * @new-bo-map-preferred-loc-smem:
+ * @new-busy-nomemset-preferred-loc-smem:
+ * @new-busy-preferred-loc-smem:
+ * @new-nomemset-preferred-loc-smem:
+ * @new-preferred-loc-smem:
+ * @new-prefetch-preferred-loc-smem:
+ * @new-race-nomemset-preferred-loc-smem:
+ * @new-race-preferred-loc-smem:
+ * @prefetch-benchmark:
  *
  * SUBTEST: prefetch-benchmark
  * Description: Prefetch a 64M buffer 128 times, measure bandwidth of prefetch
@@ -1020,7 +1112,7 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 	uint32_t bo = 0, bind_sync = 0;
 	void **pending_free;
 	u64 *exec_ufence = NULL, *bind_ufence = NULL;
-	int i, j, b, file_fd = -1, prev_idx, pf_count;
+	int i, j, b, file_fd = -1, prev_idx, pf_count, err;
 	bool free_vm = false;
 	size_t aligned_size = bo_size ?: xe_get_default_alignment(fd);
 	size_t orig_size = bo_size;
@@ -1133,6 +1225,15 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 
 	addr = to_user_pointer(data);
 
+	if (flags & PREFERRED_LOC_SMEM) {
+		err = xe_vm_madvise(fd, vm, to_user_pointer(data), bo_size, 0,
+				    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+				    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
+		if (err)
+			igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size = %zu\n",
+				 strerror(errno), vm, to_user_pointer(data), bo_size);
+	}
+
 	if (flags & BO_UNMAP) {
 		bo_flags = DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM;
 		bo = xe_bo_create(fd, vm, bo_size,
@@ -1202,7 +1303,7 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 		uint64_t batch_addr = addr + batch_offset;
 		uint64_t sdi_offset = (char *)&data[idx].data - (char *)data;
 		uint64_t sdi_addr = addr + sdi_offset;
-		int e = i % n_exec_queues, err;
+		int e = i % n_exec_queues;
 		bool fault_inject = (FAULT & flags) && i == n_execs / 2;
 		bool fault_injected = (FAULT & flags) && i > n_execs;
 
@@ -1232,6 +1333,16 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 			aligned_alloc_type = __aligned_alloc(aligned_size, bo_size);
 			next_data = aligned_alloc_type.ptr;
 			igt_assert(next_data);
+
+			if (flags & PREFERRED_LOC_SMEM) {
+				err = xe_vm_madvise(fd, vm, to_user_pointer(next_data), bo_size, 0,
+							DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+							DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
+				if (err)
+					igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size = %zu\n",
+						  strerror(errno), vm, to_user_pointer(next_data), bo_size);
+			}
+
 			__aligned_partial_free(&aligned_alloc_type);
 
 			b = 0;
@@ -1253,6 +1364,7 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 			sync[0].addr = to_user_pointer(bind_ufence);
 
 			start = igt_nsec_elapsed(&tv);
+
 			xe_vm_prefetch_async(fd, vm, 0, 0, addr, bo_size, sync,
 					     1, region);
 			end = igt_nsec_elapsed(&tv);
@@ -1355,6 +1467,7 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 				} else {
 					igt_assert_eq(data[idx].data,
 						      READ_VALUE(&data[idx]));
+
 					if (flags & PREFETCH_SYS_BENCHMARK) {
 						struct timespec tv = {};
 						u64 start, end;
@@ -1429,6 +1542,7 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 				aligned_alloc_type = __aligned_alloc(aligned_size, bo_size);
 				data = aligned_alloc_type.ptr;
 				igt_assert(data);
+
 				__aligned_partial_free(&aligned_alloc_type);
 
 				bo_flags = DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM;
@@ -1450,6 +1564,7 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 				}
 				bo = 0;
 				data = aligned_alloc(aligned_size, bo_size);
+
 				igt_assert(data);
 			}
 			addr = to_user_pointer(data);
@@ -1460,6 +1575,15 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 		prev_idx = idx;
 	}
 
+	if (flags & PREFERRED_LOC_SMEM) {
+		err = xe_vm_madvise(fd, vm, to_user_pointer(data), bo_size, 0,
+				    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+				    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
+		if (err)
+			igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size = %zu\n",
+				 strerror(errno), vm, to_user_pointer(data), bo_size);
+	}
+
 	if (flags & PREFETCH_BENCHMARK) {
 		igt_info("Prefetch VRAM execution took %.3fms, %.1f5 GB/s\n",
 			 1e-6 * prefetch_ns,
@@ -1587,6 +1711,7 @@ threads(int fd, int n_exec_queues, int n_execs, size_t bo_size,
 	uint32_t vm = 0;
 	bool go = false;
 	void *alloc = NULL;
+	int err;
 
 	if ((FILE_BACKED | FORK_READ) & flags)
 		return;
@@ -1614,6 +1739,15 @@ threads(int fd, int n_exec_queues, int n_execs, size_t bo_size,
 		alloc = aligned_alloc(SZ_2M, alloc_size);
 		igt_assert(alloc);
 
+		if (flags & PREFERRED_LOC_SMEM) {
+			err = xe_vm_madvise(fd, vm, to_user_pointer(alloc), alloc_size, 0,
+					    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+					    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
+			if (err)
+				igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size = %zu\n",
+					  strerror(errno), vm, to_user_pointer(alloc), alloc_size);
+		}
+
 		memset(alloc, 5, alloc_size);
 		flags &= ~SHARED_ALLOC;
 	}
@@ -1831,6 +1965,7 @@ igt_main
 		{ NULL },
 	};
 	int fd;
+	int num_sections;
 
 	igt_fixture {
 		struct xe_device *xe;
@@ -1843,7 +1978,21 @@ igt_main
 		open_sync_file();
 	}
 
-	for (const struct section *s = sections; s->name; s++) {
+
+	num_sections = 0;
+	for (const struct section *s = sections; s[num_sections].name; num_sections++)
+		;
+
+	for (int i = 0; i < num_sections * 2; i++) {
+		struct section *s = &sections[i % num_sections];
+
+		if (i/num_sections == 0) {
+			static char modified_name[256];
+			snprintf(modified_name, sizeof(modified_name), "%s-preferred-loc-smem", s->name);
+			s->name = modified_name;
+			s->flags |= PREFERRED_LOC_SMEM;
+		}
+
 		igt_subtest_f("once-%s", s->name)
 			xe_for_each_engine(fd, hwe)
 				test_exec(fd, hwe, 1, 1, 0, 0, 0, NULL,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH i-g-t 5/5] tests/intel/xe_exec_system_allocator: Add atomic_batch test in IGT
  2025-08-29 14:54 [PATCH i-g-t 0/5] nishit.sharma
                   ` (3 preceding siblings ...)
  2025-08-29 14:54 ` [PATCH i-g-t 4/5] tests/intel/xe_exec_system_allocator: Add preferred-loc-smem test nishit.sharma
@ 2025-08-29 14:54 ` nishit.sharma
  2025-08-29 19:08 ` ✗ Fi.CI.BUILD: failure for series starting with [i-g-t,1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure Patchwork
  5 siblings, 0 replies; 7+ messages in thread
From: nishit.sharma @ 2025-08-29 14:54 UTC (permalink / raw)
  To: igt-dev, pravalika.gurram, himal.prasad.ghimiray, matthew.brost,
	nishit.sharma

From: Nishit Sharma <nishit.sharma@intel.com>

ATOMIC_BATCH flag is introduced when true MI_ATOMIC | MI_ATOMIC_INC
operation will be called. This will avoid writing another function which
performs atomic increment operations. ATOMIC_BATCH flag is passed as
argument in write_dword() if true then value will be written on passed
address and incremented by ATOMIC_INC operation. For all memory
operations this flag will be used to verify if ATOMIC operation is
working or not.

Signed-off-by: Nishit Sharma <nishit.sharma@intel.com>
---
 lib/xe/xe_ioctl.c                      |   3 +-
 tests/intel/xe_exec_system_allocator.c | 623 +++++++++++++++++++------
 2 files changed, 482 insertions(+), 144 deletions(-)

diff --git a/lib/xe/xe_ioctl.c b/lib/xe/xe_ioctl.c
index f393aaf92..b4274f3db 100644
--- a/lib/xe/xe_ioctl.c
+++ b/lib/xe/xe_ioctl.c
@@ -732,6 +732,5 @@ int __xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range,
 int xe_vm_madvise(int fd, uint32_t vm, uint64_t addr, uint64_t range,
 		  uint64_t ext, uint32_t type, uint32_t op_val, uint16_t policy)
 {
-	igt_assert_eq(__xe_vm_madvise(fd, vm, addr, range, ext, type, op_val, policy), 0);
-	return 0;
+	return __xe_vm_madvise(fd, vm, addr, range, ext, type, op_val, policy);
 }
diff --git a/tests/intel/xe_exec_system_allocator.c b/tests/intel/xe_exec_system_allocator.c
index 70ca5fc2e..80cf730d1 100644
--- a/tests/intel/xe_exec_system_allocator.c
+++ b/tests/intel/xe_exec_system_allocator.c
@@ -21,6 +21,7 @@
 #include "lib/intel_reg.h"
 #include "xe_drm.h"
 
+#include "intel_pat.h"
 #include "xe/xe_gt.h"
 #include "xe/xe_ioctl.h"
 #include "xe/xe_query.h"
@@ -29,6 +30,14 @@
 #define USER_FENCE_VALUE	0xdeadbeefdeadbeefull
 #define QUARTER_SEC		(NSEC_PER_SEC / 4)
 #define FIVE_SEC		(5LL * NSEC_PER_SEC)
+struct test_exec_data {
+	uint32_t batch[32];
+	uint64_t pad;
+	uint64_t vm_sync;
+	uint64_t exec_sync;
+	uint32_t data;
+	uint32_t expected_data;
+};
 
 struct batch_data {
 	uint32_t batch[16];
@@ -37,6 +46,7 @@ struct batch_data {
 	uint32_t expected_data;
 };
 
+#define VAL_ATOMIC_EXPECTED  56
 #define WRITE_VALUE(data__, i__)	({			\
 	if (!(data__)->expected_data)				\
 		(data__)->expected_data = rand() << 12 | (i__);	\
@@ -53,10 +63,19 @@ static void __write_dword(uint32_t *batch, uint64_t sdi_addr, uint32_t wdata,
 	batch[(*idx)++] = wdata;
 }
 
-static void write_dword(uint32_t *batch, uint64_t sdi_addr, uint32_t wdata,
-			int *idx)
+static void write_dword(struct test_exec_data *data, uint64_t sdi_addr, uint32_t wdata,
+			int *idx, bool atomic)
 {
-	__write_dword(batch, sdi_addr, wdata, idx);
+	uint32_t *batch = data->batch;
+
+	if (atomic) {
+		data->data = 55;
+		batch[(*idx)++] = MI_ATOMIC | MI_ATOMIC_INC;
+		batch[(*idx)++] = sdi_addr;
+		batch[(*idx)++] = sdi_addr >> 32;
+	} else {
+		__write_dword(batch, sdi_addr, wdata, idx);
+	}
 	batch[(*idx)++] = MI_BATCH_BUFFER_END;
 }
 
@@ -302,7 +321,7 @@ static void touch_all_pages(int fd, uint32_t exec_queue, void *ptr,
 		uint64_t sdi_addr = addr + sdi_offset;
 		int b = 0;
 
-		write_dword(data->batch, sdi_addr, WRITE_VALUE(data, i), &b);
+		write_dword((struct test_exec_data *)data, sdi_addr, WRITE_VALUE(data, i), &b, false);
 		igt_assert(b <= ARRAY_SIZE(data->batch));
 	}
 
@@ -405,39 +424,6 @@ static void __aligned_partial_free(struct aligned_alloc_type  *aligned_alloc_typ
 		       aligned_alloc_type->__size - aligned_alloc_type->size - begin_size);
 }
 
-#define MAX_N_EXEC_QUEUES       16
-
-#define MMAP                    (0x1 << 0)
-#define NEW                     (0x1 << 1)
-#define BO_UNMAP                (0x1 << 2)
-#define FREE                    (0x1 << 3)
-#define BUSY                    (0x1 << 4)
-#define BO_MAP                  (0x1 << 5)
-#define RACE                    (0x1 << 6)
-#define SKIP_MEMSET             (0x1 << 7)
-#define FAULT                   (0x1 << 8)
-#define FILE_BACKED             (0x1 << 9)
-#define LOCK                    (0x1 << 10)
-#define MMAP_SHARED             (0x1 << 11)
-#define HUGE_PAGE               (0x1 << 12)
-#define SHARED_ALLOC            (0x1 << 13)
-#define FORK_READ               (0x1 << 14)
-#define FORK_READ_AFTER         (0x1 << 15)
-#define MREMAP                  (0x1 << 16)
-#define DONTUNMAP               (0x1 << 17)
-#define READ_ONLY_REMAP         (0x1 << 18)
-#define SYNC_EXEC               (0x1 << 19)
-#define EVERY_OTHER_CHECK       (0x1 << 20)
-#define MULTI_FAULT             (0x1 << 21)
-#define PREFETCH                (0x1 << 22)
-#define THREADS                 (0x1 << 23)
-#define PROCESSES               (0x1 << 24)
-#define PREFETCH_BENCHMARK      (0x1 << 25)
-#define PREFETCH_SYS_BENCHMARK	(0x1 << 26)
-#define PREFERRED_LOC_SMEM      (0x1 << 27)
-
-#define N_MULTI_FAULT           4
-
 /**
  * SUBTEST: unaligned-alloc
  * Description: allocate unaligned sizes of memory
@@ -478,6 +464,54 @@ static void __aligned_partial_free(struct aligned_alloc_type  *aligned_alloc_typ
  * SUBTEST: processes-evict-malloc-mix-bo
  * Description: multi-process trigger eviction of VRAM allocated via malloc and BO create
  * Test category: stress test
+ *
+ * SUBTEST: madvise-multi-vma
+ * Description: performs multiple madvise operations on multiple virtual memory area using atomic device attributes
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-split-vma
+ * Description: perform madvise operations on multiple type VMAs (BO and CPU VMAs)
+ * Test category: perform madvise operations on multiple type VMAs (BO and CPU VMAs)
+ *
+ * SUBTEST: madvise-atomic-vma
+ * Description: perform madvise atomic operations on BO in VRAM/SMEM if atomic ATTR global/device
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-split-vma-with-mapping
+ * Description: performs prefetch and page migration
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-preffered-loc-atomic-vram
+ * Description: performs both atomic and preferred loc madvise operations atomic device attributes set
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-preffered-loc-atomic-gl
+ * Description: performs both atomic and preferred loc madvise operations with atomic global attributes set
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-preffered-loc-atomic-cpu
+ * Description: performs both atomic and preferred loc madvise operations with atomic cpu attributes set
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-preffered-loc-sram-migrate-pages
+ * Description: performs preferred loc madvise operations and migrating all pages in smem
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-no-range-invalidate-same-attr
+ * Description: performs atomic global madvise operation, prefetch and again madvise operation with same atomic attribute
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-range-invalidate-change-attr
+ * Description: performs atomic global madvise operation, prefetch and again madvise operation with different atomic attribute
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-preffered-loc-atomic-und
+ * Description: Tests madvise with preferred location set for atomic operations, but with an undefined
+ * Test category: functionality test
+ *
+ * SUBTEST: madvise-atomic-inc
+ * Description: Tests madvise atomic operations
+ * Test category: functionality test
  */
 
 static void
@@ -492,7 +526,7 @@ many_allocs(int fd, struct drm_xe_engine_class_instance *eci,
 	uint32_t *bos = NULL;
 	struct timespec tv = {};
 	uint64_t submit, read, elapsed;
-	int i, err;
+	int i;
 
 	vm = xe_vm_create(fd, DRM_XE_VM_CREATE_FLAG_LR_MODE |
 			  DRM_XE_VM_CREATE_FLAG_FAULT_MODE, 0);
@@ -533,14 +567,6 @@ many_allocs(int fd, struct drm_xe_engine_class_instance *eci,
 			igt_assert(alloc.ptr);
 		}
 
-		if (flags & PREFERRED_LOC_SMEM) {
-			err = xe_vm_madvise(fd, vm, to_user_pointer(alloc.ptr), alloc_size, 0,
-					    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
-					    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
-				if (err)
-					igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size =%"PRIu64"\n",
-						  strerror(errno), vm, to_user_pointer(alloc.ptr), alloc_size);
-		}
 		allocs[i] = alloc;
 
 		touch_all_pages(fd, exec_queue, allocs[i].ptr, alloc_size, stride,
@@ -703,7 +729,7 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 	size_t bo_size = SZ_2M, unmap_offset = 0;
 	uint32_t vm, exec_queue;
 	u64 *exec_ufence = NULL;
-	int i, err;
+	int i;
 	void *old, *new = NULL;
 	struct aligned_alloc_type alloc;
 
@@ -729,15 +755,6 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 	xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE, 0, FIVE_SEC);
 	data[0].vm_sync = 0;
 
-	if (flags & PREFERRED_LOC_SMEM) {
-		err = xe_vm_madvise(fd, vm, to_user_pointer(data), bo_size, 0,
-				    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
-				    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
-		if (err)
-			igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size = %zu\n",
-				  strerror(errno), vm, to_user_pointer(data), bo_size);
-	}
-
 	exec_ufence = mmap(NULL, SZ_4K, PROT_READ |
 			   PROT_WRITE, MAP_SHARED |
 			   MAP_ANONYMOUS, -1, 0);
@@ -750,7 +767,8 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 		uint64_t sdi_addr = addr + sdi_offset;
 		int b = 0;
 
-		write_dword(data[i].batch, sdi_addr, WRITE_VALUE(&data[i], i), &b);
+		write_dword((struct test_exec_data *)&data[i], sdi_addr, WRITE_VALUE(&data[i], i),
+			     &b, false);
 		igt_assert(b <= ARRAY_SIZE(data[i].batch));
 
 		if (!i)
@@ -773,7 +791,8 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 		xe_wait_ufence(fd, new ?: exec_ufence, USER_FENCE_VALUE,
 			       exec_queue, FIVE_SEC);
 		if (i || (flags & CPU_FAULT))
-			igt_assert_eq(data[i].data, READ_VALUE(&data[i]));
+			igt_assert_eq(data[i].data,
+				      READ_VALUE(&data[i]));
 		exec_ufence[0] = 0;
 
 		if (!i) {
@@ -797,6 +816,52 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
 	xe_vm_destroy(fd, vm);
 }
 
+#define MAX_N_EXEC_QUEUES       16
+
+#define MMAP				(0x1 << 0)
+#define NEW				(0x1 << 1)
+#define BO_UNMAP			(0x1 << 2)
+#define FREE				(0x1 << 3)
+#define BUSY				(0x1 << 4)
+#define BO_MAP				(0x1 << 5)
+#define RACE				(0x1 << 6)
+#define SKIP_MEMSET			(0x1 << 7)
+#define FAULT				(0x1 << 8)
+#define FILE_BACKED			(0x1 << 9)
+#define LOCK				(0x1 << 10)
+#define MMAP_SHARED			(0x1 << 11)
+#define HUGE_PAGE			(0x1 << 12)
+#define SHARED_ALLOC			(0x1 << 13)
+#define FORK_READ			(0x1 << 14)
+#define FORK_READ_AFTER			(0x1 << 15)
+#define MREMAP				(0x1 << 16)
+#define DONTUNMAP			(0x1 << 17)
+#define READ_ONLY_REMAP			(0x1 << 18)
+#define SYNC_EXEC			(0x1 << 19)
+#define EVERY_OTHER_CHECK		(0x1 << 20)
+#define MULTI_FAULT			(0x1 << 21)
+#define PREFETCH			(0x1 << 22)
+#define THREADS				(0x1 << 23)
+#define PROCESSES			(0x1 << 24)
+#define PREFETCH_BENCHMARK		(0x1 << 25)
+#define PREFETCH_SYS_BENCHMARK		(0x1 << 26)
+#define PREFERRED_LOC_SMEM		(0x1 << 27)
+#define ATOMIC_BATCH			(0x1 << 28)
+#define MIGRATE_ALL_PAGES		(0x1 << 29)
+#define PREFERRED_LOC_ATOMIC_DEVICE	(0x1 << 30)
+#define PREFERRED_LOC_ATOMIC_GL		(0x1ull << 31)
+#define PREFERRED_LOC_ATOMIC_CPU	(0x1ull << 32)
+#define MADVISE_MULTI_VMA		(0x1ull << 33)
+#define MADVISE_SPLIT_VMA		(0x1ull << 34)
+#define MADVISE_ATOMIC_VMA		(0x1ull << 35)
+#define PREFETCH_SPLIT_VMA		(0x1ull << 36)
+#define PREFETCH_CHANGE_ATTR		(0x1ull << 37)
+#define PREFETCH_SAME_ATTR		(0x1ull << 38)
+#define PREFERRED_LOC_ATOMIC_UND	(0x1ull << 39)
+#define MADVISE_ATOMIC_INC		(0x1ull << 40)
+
+#define N_MULTI_FAULT           4
+
 /**
  * SUBTEST: once-%s
  * Description: Run %arg[1] system allocator test only once
@@ -1001,48 +1066,48 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
  * @mmap-free-huge-preferred-loc-smem:	mmap huge page and free buffer for each exec and perform madvise
  * @mmap-free-nomemset-preferred-loc-smem:	mmap and free buffer for each exec and perform madvise
  * @mmap-free-preferred-loc-smem:	mmap and free buffer for each exec and perform madvise
- * @mmap-free-race-nomemset-preferred-loc-smem:
- * @mmap-free-race-preferred-loc-smem:
- * @mmap-huge-nomemset-preferred-loc-smem:
- * @mmap-huge-preferred-loc-smem:
- * @mmap-mlock-nomemset-preferred-loc-smem:
- * @mmap-mlock-preferred-loc-smem:
- * @mmap-new-huge-nomemset-preferred-loc-smem:
- * @mmap-new-huge-preferred-loc-smem:
- * @mmap-new-nomemset-preferred-loc-smem:
- * @mmap-new-preferred-loc-smem:
- * @mmap-new-race-nomemset-preferred-loc-smem:
- * @mmap-new-race-preferred-loc-smem:
- * @mmap-nomemset-preferred-loc-smem:
- * @mmap-preferred-loc-smem:
- * @mmap-prefetch-preferred-loc-smem:
- * @mmap-prefetch-shared-preferred-loc-smem:
- * @mmap-race-nomemset-preferred-loc-smem:
- * @mmap-race-preferred-loc-smem:
- * @mmap-remap-dontunmap-eocheck-preferred-loc-smem:
- * @mmap-remap-dontunmap-preferred-loc-smem:
- * @mmap-remap-eocheck-preferred-loc-smem:
- * @mmap-remap-preferred-loc-smem:
- * @mmap-remap-ro-dontunmap-eocheck-preferred-loc-smem:
- * @mmap-remap-ro-dontunmap-preferred-loc-smem:
- * @mmap-remap-ro-eocheck-preferred-loc-smem:
- * @mmap-remap-ro-preferred-loc-smem:
- * @mmap-shared-nomemset-preferred-loc-smem:
- * @mmap-shared-preferred-loc-smem:
- * @mmap-shared-remap-dontunmap-eocheck-preferred-loc-smem:
- * @mmap-shared-remap-dontunmap-preferred-loc-smem:
- * @mmap-shared-remap-eocheck-preferred-loc-smem:
- * @mmap-shared-remap-preferred-loc-smem:
- * @new-bo-map-nomemset-preferred-loc-smem:
- * @new-bo-map-preferred-loc-smem:
- * @new-busy-nomemset-preferred-loc-smem:
- * @new-busy-preferred-loc-smem:
- * @new-nomemset-preferred-loc-smem:
- * @new-preferred-loc-smem:
- * @new-prefetch-preferred-loc-smem:
- * @new-race-nomemset-preferred-loc-smem:
- * @new-race-preferred-loc-smem:
- * @prefetch-benchmark:
+ * @mmap-free-race-nomemset-preferred-loc-smem: mmap and free buffer for each exec with race between cpu and gpu access, perform madvise operation
+ * @mmap-free-race-preferred-loc-smem: mmap and free buffer for each exec with race between cpu and gpu access, perform madvise operation
+ * @mmap-huge-nomemset-preferred-loc-smem: mmap huge page single buffer for all execs, skips memset and perform madvise operation
+ * @mmap-huge-preferred-loc-smem: mmap huge page single buffer for all execs, perform madvise operation
+ * @mmap-mlock-nomemset-preferred-loc-smem: mmap and mlock of a buffer with preferred location set to system memory, skipping memset
+ * @mmap-mlock-preferred-loc-smem: mmap and mlock of a buffer with preferred location set to system memory
+ * @mmap-new-huge-nomemset-preferred-loc-smem: mmap of a newly allocated buffer using huge pages, with preferred location set to system memory and skipping memset
+ * @mmap-new-huge-preferred-loc-smem: mmap of a newly allocated buffer using huge pages, with preferred location set to system memory
+ * @mmap-new-nomemset-preferred-loc-smem: mmap of a newly allocated buffer with preferred location set to system memory and skipping memset
+ * @mmap-new-preferred-loc-smem: mmap of a newly allocated buffer with preferred location set to system memory
+ * @mmap-new-race-nomemset-preferred-loc-smem: mmap of a newly allocated buffer with preferred location set to system memory and skipping memset
+ * @mmap-new-race-preferred-loc-smem: mmap of a newly allocated buffer with preferred location set to system memory
+ * @mmap-nomemset-preferred-loc-smem: mmap of a buffer with preferred location set to system memory, skipping memset
+ * @mmap-preferred-loc-smem: mmap of a buffer with preferred location set to system memory
+ * @mmap-prefetch-preferred-loc-smem: prefetching mmap buffer with preferred location set to system memory
+ * @mmap-prefetch-shared-preferred-loc-smem: mmap of a shared buffer with prefetch and preferred location set to system memory
+ * @mmap-race-nomemset-preferred-loc-smem: Tests mmap of a buffer with preferred location set to system memory, skipping memset
+ * @mmap-race-preferred-loc-smem: mmap buffer with race between GPU and CPU access with preferred location set to system memory
+ * @mmap-remap-dontunmap-eocheck-preferred-loc-smem: mmap and remap of a buffer with preferred location set to system memory, does not unmap after use
+ * @mmap-remap-dontunmap-preferred-loc-smem: mmap and remap of a buffer with preferred location set to system memory, does not unmap after use
+ * @mmap-remap-eocheck-preferred-loc-smem: mmap and remap of a buffer with preferred location set to system memory
+ * @mmap-remap-preferred-loc-smem: mmap and remap of a buffer with preferred location set to system memory
+ * @mmap-remap-ro-dontunmap-eocheck-preferred-loc-smem: mmap and remap of a read-only buffer with preferred location set to system memory, does not unmap after use
+ * @mmap-remap-ro-dontunmap-preferred-loc-smem: mmap and remap of a read-only buffer with preferred location set to system memory, does not unmap after use
+ * @mmap-remap-ro-eocheck-preferred-loc-smem: mmap and remap of a read-only buffer with preferred location set to system memory
+ * @mmap-remap-ro-preferred-loc-smem: mmap and remap of a read-only buffer with preferred location set to system memory
+ * @mmap-shared-nomemset-preferred-loc-smem: mmap of a shared buffer with preferred location set to system memory, skipping memset
+ * @mmap-shared-preferred-loc-smem: mmap of a shared buffer with preferred location set to system memory
+ * @mmap-shared-remap-dontunmap-eocheck-preferred-loc-smem: mmap and remap of a shared buffer with preferred location set to system memory, does not unmap after use
+ * @mmap-shared-remap-dontunmap-preferred-loc-smem: mmap and remap of a shared buffer with preferred location set to system memory
+ * @mmap-shared-remap-eocheck-preferred-loc-smem: mmap and remap of a shared buffer with preferred location set to system memory with end of check validation
+ * @mmap-shared-remap-preferred-loc-smem: mmap and remap of a shared buffer with preferred location set to system memory without end of check validation
+ * @new-bo-map-nomemset-preferred-loc-smem: Tests allocation and mapping of a new buffer object with preferred location set to system memory, skipping memset
+ * @new-bo-map-preferred-loc-smem: ests allocation and mapping of a new buffer object with preferred location set to system memory
+ * @new-busy-nomemset-preferred-loc-smem: Tests allocation and usage of a new busy buffer object with preferred location set to system memory, skipping memset
+ * @new-busy-preferred-loc-smem: ests allocation and usage of a new busy buffer object with preferred location set to system memory
+ * @new-nomemset-preferred-loc-smem: Tests allocation of a new buffer object with preferred location set to system memory, skipping memset
+ * @new-preferred-loc-smem: Tests allocation of a new buffer object with preferred location set to system memory
+ * @new-prefetch-preferred-loc-smem: Tests allocation and prefetching of a new buffer object with preferred location set to system memory
+ * @new-race-nomemset-preferred-loc-smem: Tests allocation of a new buffer object with preferred location set to system memory, skipping memset
+ * @new-race-preferred-loc-smem: tests allocation of a new buffer object with preferred location set to system memory
+ *
  *
  * SUBTEST: prefetch-benchmark
  * Description: Prefetch a 64M buffer 128 times, measure bandwidth of prefetch
@@ -1072,16 +1137,6 @@ partial(int fd, struct drm_xe_engine_class_instance *eci, unsigned int flags)
  * Description: Create multiple threads with a faults on different hardware engines to same addresses, racing between CPU and GPU access
  * Test category: stress test
  */
-
-struct test_exec_data {
-	uint32_t batch[32];
-	uint64_t pad;
-	uint64_t vm_sync;
-	uint64_t exec_sync;
-	uint32_t data;
-	uint32_t expected_data;
-};
-
 static void igt_require_hugepages(void)
 {
 	igt_skip_on_f(!igt_get_meminfo("HugePages_Total"),
@@ -1090,11 +1145,37 @@ static void igt_require_hugepages(void)
 		      "No huge pages available!\n");
 }
 
+static int
+xe_vm_madvixe_pat_attr(int fd, uint32_t vm, uint64_t addr, uint64_t range,
+			int pat_index)
+{
+	return	xe_vm_madvise(fd, vm, addr, range, 0,
+			      DRM_XE_MEM_RANGE_ATTR_PAT, pat_index, 0);
+}
+
+static int
+xe_vm_madvise_atomic_attr(int fd, uint32_t vm, uint64_t addr, uint64_t range,
+			  int mem_attr)
+{
+	return	xe_vm_madvise(fd, vm, addr, range, 0,
+			      DRM_XE_MEM_RANGE_ATTR_ATOMIC,
+			      mem_attr, 0);
+}
+
+static int
+xe_vm_madvise_migrate_pages(int fd, uint32_t vm, uint64_t addr, uint64_t range)
+{
+	return	xe_vm_madvise(fd, vm, addr, range, 0,
+			      DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+			      DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM,
+			      DRM_XE_MIGRATE_ALL_PAGES);
+}
+
 static void
 test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 	  int n_exec_queues, int n_execs, size_t bo_size,
 	  size_t stride, uint32_t vm, void *alloc, pthread_barrier_t *barrier,
-	  unsigned int flags)
+	  unsigned long long flags)
 {
 	uint64_t addr;
 	struct drm_xe_sync sync[1] = {
@@ -1107,9 +1188,10 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 		.syncs = to_user_pointer(sync),
 	};
 	uint32_t exec_queues[MAX_N_EXEC_QUEUES];
-	struct test_exec_data *data, *next_data = NULL;
+	struct test_exec_data *data, *next_data = NULL, *org_data;
 	uint32_t bo_flags;
 	uint32_t bo = 0, bind_sync = 0;
+	uint32_t val;
 	void **pending_free;
 	u64 *exec_ufence = NULL, *bind_ufence = NULL;
 	int i, j, b, file_fd = -1, prev_idx, pf_count, err;
@@ -1234,6 +1316,151 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 				 strerror(errno), vm, to_user_pointer(data), bo_size);
 	}
 
+	if (flags & MADVISE_ATOMIC_INC) {
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+						DRM_XE_ATOMIC_DEVICE);
+		if (err)
+			igt_warn("failure in atomic device attr err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+	}
+
+	if (flags & PREFERRED_LOC_SMEM) {
+		if (flags & MIGRATE_ALL_PAGES) {
+			err = xe_vm_madvise_migrate_pages(fd, vm, to_user_pointer(data), bo_size);
+			if (err)
+				igt_warn("failure in page migration err = %s, vm =%u, data=%"PRIu64"\n",
+					 strerror(errno), vm, to_user_pointer(data));
+		} else {
+			err = xe_vm_madvise(fd, vm, to_user_pointer(data), bo_size, 0,
+					    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
+					    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, -1);
+		}
+	}
+
+	if (flags & PREFERRED_LOC_ATOMIC_UND) {
+		err = xe_vm_madvise_migrate_pages(fd, vm, to_user_pointer(data), bo_size);
+		if (err)
+			igt_warn("failure in page migration err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+						DRM_XE_ATOMIC_UNDEFINED);
+		if (err)
+			igt_warn("failure in atomic device attr err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+	}
+
+	if (flags & PREFERRED_LOC_ATOMIC_DEVICE) {
+		err = xe_vm_madvise_migrate_pages(fd, vm, to_user_pointer(data), bo_size);
+		if (err)
+			igt_warn("failure in page migration err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+						DRM_XE_ATOMIC_DEVICE);
+		if (err)
+			igt_warn("failure in atomic device attr err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+	}
+	if (flags & PREFERRED_LOC_ATOMIC_GL) {
+		err = xe_vm_madvise_migrate_pages(fd, vm, to_user_pointer(data), bo_size);
+		if (err)
+			igt_warn("failure in page migration err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+						DRM_XE_ATOMIC_GLOBAL);
+		if (err)
+			igt_warn("failure in atomic global attr err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+	}
+	if (flags & PREFERRED_LOC_ATOMIC_CPU) {
+		err = xe_vm_madvise_migrate_pages(fd, vm, to_user_pointer(data), bo_size);
+		if (err)
+			igt_warn("failure in page migration err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+						DRM_XE_ATOMIC_CPU);
+		if (err)
+			igt_warn("failure in atomic cpu attr err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+	}
+	if (flags & MADVISE_MULTI_VMA) {
+		if (bo_size)
+			bo_size = ALIGN(bo_size, SZ_4K);
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data) + bo_size/2,
+						bo_size/2, DRM_XE_ATOMIC_DEVICE);
+		if (err)
+			igt_warn("failure in atomic device attr err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+
+		err = xe_vm_madvixe_pat_attr(fd, vm, to_user_pointer(data) + bo_size/2, bo_size/2,
+					     intel_get_pat_idx_wb(fd));
+		if (err)
+			igt_warn("failure in pat attr index 8 err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data) + bo_size,
+						bo_size, DRM_XE_ATOMIC_DEVICE);
+		if (err)
+			igt_warn("failure in atomic multi_vma err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+
+		err = xe_vm_madvixe_pat_attr(fd, vm, to_user_pointer(data), bo_size, intel_get_pat_idx_wb(fd));
+		if (err)
+			igt_warn("failure in pat attr index 4 err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+
+	}
+	if (flags & MADVISE_SPLIT_VMA) {
+		if (bo_size)
+			bo_size = ALIGN(bo_size, SZ_4K);
+
+		bo_flags = DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM;
+		bo = xe_bo_create(fd, vm, bo_size,
+				  vram_if_possible(fd, eci->gt_id), bo_flags);
+		xe_vm_bind_async(fd, vm, 0, bo, 0, to_user_pointer(data) + bo_size/2,
+				 bo_size/2, 0, 0);
+
+		__xe_vm_bind_assert(fd, vm, 0, 0, 0, to_user_pointer(data) + bo_size/2,
+				    bo_size/2, DRM_XE_VM_BIND_OP_MAP,
+				    DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR, sync,
+				    1, 0, 0);
+		xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE, 0, FIVE_SEC);
+		data[0].vm_sync = 0;
+		gem_close(fd, bo);
+		bo = 0;
+
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data),
+						bo_size/2, DRM_XE_ATOMIC_DEVICE);
+		if (err)
+			igt_warn("failure in split atomic device attr err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+	}
+	if (flags & MADVISE_ATOMIC_VMA) {
+		if (bo_size)
+			bo_size = ALIGN(bo_size, SZ_4K);
+
+		bo_flags = DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM;
+		bo = xe_bo_create(fd, vm, bo_size, vram_if_possible(fd, eci->gt_id), bo_flags);
+		xe_vm_bind_async(fd, vm, 0, bo, 0, to_user_pointer(data), bo_size, 0, 0);
+
+		__xe_vm_bind_assert(fd, vm, 0, 0, 0, to_user_pointer(data), bo_size,
+				    DRM_XE_VM_BIND_OP_MAP,
+				    DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR, sync,
+				    1, 0, 0);
+		xe_wait_ufence(fd, &data[0].vm_sync, USER_FENCE_VALUE, 0, FIVE_SEC);
+		data[0].vm_sync = 0;
+		gem_close(fd, bo);
+		bo = 0;
+
+		err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size/2,
+						DRM_XE_ATOMIC_GLOBAL);
+		if (err)
+			igt_warn("failure in atomic vma err = %s, vm =%u data=%"PRIu64"\n",
+				 strerror(errno), vm, to_user_pointer(data));
+	}
+
 	if (flags & BO_UNMAP) {
 		bo_flags = DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM;
 		bo = xe_bo_create(fd, vm, bo_size,
@@ -1307,6 +1534,39 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 		bool fault_inject = (FAULT & flags) && i == n_execs / 2;
 		bool fault_injected = (FAULT & flags) && i > n_execs;
 
+		if (flags & MADVISE_MULTI_VMA) {
+			addr = addr + i * bo_size;
+			org_data = data;
+			data = from_user_pointer(addr);
+			batch_offset = (char *)&(data[idx].batch) - (char *)data;
+			batch_addr = addr + batch_offset;
+			sdi_offset = (char *)&(data[idx].data) - (char *)data;
+			sdi_addr = addr + sdi_offset;
+		}
+
+		if (flags & MADVISE_SPLIT_VMA) {
+			// Write to first half of split VMA
+			uint64_t first_half_addr, sdi_addr_1;
+			uint64_t second_half_addr, sdi_addr_2;
+			sdi_offset = (char *)&data[idx].data - (char *)data;
+			sdi_addr_1 = first_half_addr + sdi_offset;
+			first_half_addr = addr;
+			b = 0;
+			write_dword(&data[idx], sdi_addr_1,
+					WRITE_VALUE(&data[idx], idx), &b,
+					flags & ATOMIC_BATCH ? true : false);
+			igt_assert(b <= ARRAY_SIZE(data[idx].batch));
+
+			// Write to second half of split VMA
+			second_half_addr = addr + bo_size/2;
+			sdi_addr_2 = second_half_addr + sdi_offset;
+			b = 0;
+			write_dword(&data[idx], sdi_addr_2,
+					WRITE_VALUE(&data[idx], idx), &b,
+					flags & ATOMIC_BATCH ? true : false);
+			igt_assert(b <= ARRAY_SIZE(data[idx].batch));
+		}
+
 		if (barrier)
 			pthread_barrier_wait(barrier);
 
@@ -1316,18 +1576,68 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 				__write_dword(data[idx].batch,
 					      sdi_addr + j * orig_size,
 					      WRITE_VALUE(&data[idx], idx), &b);
-			write_dword(data[idx].batch, sdi_addr + j * orig_size,
-				    WRITE_VALUE(&data[idx], idx), &b);
+			write_dword(&data[idx], sdi_addr + j * orig_size,
+				    WRITE_VALUE(&data[idx], idx), &b,
+				    flags & ATOMIC_BATCH ? true : false);
 			igt_assert(b <= ARRAY_SIZE(data[idx].batch));
 		} else if (!(flags & EVERY_OTHER_CHECK)) {
 			b = 0;
-			write_dword(data[idx].batch, sdi_addr,
-				    WRITE_VALUE(&data[idx], idx), &b);
+			write_dword(&data[idx], sdi_addr,
+				    WRITE_VALUE(&data[idx], idx), &b,
+				    flags & ATOMIC_BATCH ? true : false);
 			igt_assert(b <= ARRAY_SIZE(data[idx].batch));
+			if (flags & PREFETCH) {
+				if (flags & PREFETCH_SPLIT_VMA) {
+					bo_size = ALIGN(bo_size, SZ_4K);
+
+					xe_vm_prefetch_async(fd, vm, 0, 0, addr, bo_size, NULL, 0, 0);
+
+					igt_debug("num_vmas before madvise = %d \n", val);
+
+					val = xe_vm_print_mem_attr_values_in_range(fd, vm, addr,  bo_size);
+
+					err = xe_vm_madvise_migrate_pages(fd, vm, to_user_pointer(data), bo_size/2);
+					if (err)
+						igt_warn("failure in prefetch split vma err = %s, vm =%u data=%"PRIu64"\n",
+								strerror(errno), vm, to_user_pointer(data));
+					igt_debug("num_vmas after madvise= %d \n", val);
+					val = xe_vm_print_mem_attr_values_in_range(fd, vm, addr,  bo_size);
+				} else if (flags & PREFETCH_SAME_ATTR) {
+					err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+							DRM_XE_ATOMIC_GLOBAL);
+					if (err)
+						igt_warn("failure in prefetch same attr err = %s, vm =%u data=%"PRIu64"\n",
+								strerror(errno), vm, to_user_pointer(data));
+					val = xe_vm_print_mem_attr_values_in_range(fd, vm, addr,  bo_size);
+					xe_vm_prefetch_async(fd, vm, 0, 0, addr, bo_size, NULL, 0, DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC);
+					err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size/2,
+							DRM_XE_ATOMIC_GLOBAL);
+					if (err)
+						igt_warn("failure in prefetch atomic attr err = %s, vm =%u data=%"PRIu64"\n",
+								strerror(errno), vm, to_user_pointer(data));
+				} else if (flags & PREFETCH_CHANGE_ATTR) {
+					err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+							DRM_XE_ATOMIC_GLOBAL);
+					if (err)
+						igt_warn("failure in prefetch atomic attr err = %s, vm =%u data=%"PRIu64"\n",
+								strerror(errno), vm, to_user_pointer(data));
+					val = xe_vm_print_mem_attr_values_in_range(fd, vm, addr,  bo_size);
+
+					xe_vm_prefetch_async(fd, vm, 0, 0, addr, bo_size, NULL, 0, DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC);
+
+					err = xe_vm_madvise_atomic_attr(fd, vm, to_user_pointer(data), bo_size,
+							DRM_XE_ATOMIC_DEVICE);
+					if (err)
+						igt_warn("failure in prefetch change attr err = %s, vm =%u data=%"PRIu64"\n",
+								strerror(errno), vm, to_user_pointer(data));
+					val = xe_vm_print_mem_attr_values_in_range(fd, vm, addr,  bo_size);
+					}
+				}
 		} else if (flags & EVERY_OTHER_CHECK && !odd(i)) {
 			b = 0;
-			write_dword(data[idx].batch, sdi_addr,
-				    WRITE_VALUE(&data[idx], idx), &b);
+			write_dword(&data[idx], sdi_addr,
+				    WRITE_VALUE(&data[idx], idx), &b,
+				    flags & ATOMIC_BATCH ? true : false);
 			igt_assert(b <= ARRAY_SIZE(data[idx].batch));
 
 			aligned_alloc_type = __aligned_alloc(aligned_size, bo_size);
@@ -1346,10 +1656,11 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 			__aligned_partial_free(&aligned_alloc_type);
 
 			b = 0;
-			write_dword(data[next_idx].batch,
+			write_dword(&data[next_idx],
 				    to_user_pointer(next_data) +
 				    (char *)&data[next_idx].data - (char *)data,
-				    WRITE_VALUE(&data[next_idx], next_idx), &b);
+				    WRITE_VALUE(&data[next_idx], next_idx), &b,
+				    flags & ATOMIC_BATCH ? true : false);
 			igt_assert(b <= ARRAY_SIZE(data[next_idx].batch));
 		}
 
@@ -1404,9 +1715,18 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 					       exec_queues[e], &timeout);
 			igt_assert(err == -ETIME || err == -EIO);
 		} else {
-			xe_wait_ufence(fd, exec_ufence ? exec_ufence :
-				       &data[idx].exec_sync, USER_FENCE_VALUE,
-				       exec_queues[e], FIVE_SEC);
+			if (flags & PREFERRED_LOC_ATOMIC_CPU || flags & PREFERRED_LOC_ATOMIC_UND) {
+				int64_t timeout = QUARTER_SEC;
+				err = __xe_wait_ufence(fd, exec_ufence ? exec_ufence :
+						       &data[idx].exec_sync,
+						       USER_FENCE_VALUE,
+						       exec_queues[e], &timeout);
+				if (err)
+					goto cleanup;
+			} else
+				xe_wait_ufence(fd, exec_ufence ? exec_ufence :
+					       &data[idx].exec_sync, USER_FENCE_VALUE,
+					       exec_queues[e], FIVE_SEC);
 			if (flags & LOCK && !i)
 				munlock(data, bo_size);
 
@@ -1456,17 +1776,17 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 				if (flags & FORK_READ) {
 					igt_fork(child, 1)
 						igt_assert_eq(data[idx].data,
-							      READ_VALUE(&data[idx]));
+							      flags & ATOMIC_BATCH ? VAL_ATOMIC_EXPECTED : READ_VALUE(&data[idx]));
 					if (!(flags & FORK_READ_AFTER))
 						igt_assert_eq(data[idx].data,
-							      READ_VALUE(&data[idx]));
+							      flags & ATOMIC_BATCH ? VAL_ATOMIC_EXPECTED : READ_VALUE(&data[idx]));
 					igt_waitchildren();
 					if (flags & FORK_READ_AFTER)
 						igt_assert_eq(data[idx].data,
-							      READ_VALUE(&data[idx]));
+							      flags & ATOMIC_BATCH ? VAL_ATOMIC_EXPECTED : READ_VALUE(&data[idx]));
 				} else {
 					igt_assert_eq(data[idx].data,
-						      READ_VALUE(&data[idx]));
+						      flags & ATOMIC_BATCH ? VAL_ATOMIC_EXPECTED : READ_VALUE(&data[idx]));
 
 					if (flags & PREFETCH_SYS_BENCHMARK) {
 						struct timespec tv = {};
@@ -1494,13 +1814,13 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 								((void *)data) + j * orig_size;
 
 							igt_assert_eq(__data[idx].data,
-								      READ_VALUE(&data[idx]));
+								      flags & ATOMIC_BATCH ? VAL_ATOMIC_EXPECTED : READ_VALUE(&data[idx]));
 						}
 					}
 				}
 				if (flags & EVERY_OTHER_CHECK)
 					igt_assert_eq(data[prev_idx].data,
-						      READ_VALUE(&data[prev_idx]));
+						      flags & ATOMIC_BATCH ? VAL_ATOMIC_EXPECTED : READ_VALUE(&data[prev_idx]));
 			}
 		}
 
@@ -1521,6 +1841,9 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 			gem_close(fd, bo);
 		}
 
+		if (flags & MADVISE_MULTI_VMA)
+			data = org_data;
+
 		if (flags & NEW) {
 			if (flags & MMAP) {
 				if (flags & FREE)
@@ -1575,15 +1898,6 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 		prev_idx = idx;
 	}
 
-	if (flags & PREFERRED_LOC_SMEM) {
-		err = xe_vm_madvise(fd, vm, to_user_pointer(data), bo_size, 0,
-				    DRM_XE_MEM_RANGE_ATTR_PREFERRED_LOC,
-				    DRM_XE_PREFERRED_LOC_DEFAULT_SYSTEM, 0);
-		if (err)
-			igt_warn("MADVISE_FAILURE err = %s, vm =%u data=%"PRIu64" alloc_size = %zu\n",
-				 strerror(errno), vm, to_user_pointer(data), bo_size);
-	}
-
 	if (flags & PREFETCH_BENCHMARK) {
 		igt_info("Prefetch VRAM execution took %.3fms, %.1f5 GB/s\n",
 			 1e-6 * prefetch_ns,
@@ -1610,6 +1924,7 @@ test_exec(int fd, struct drm_xe_engine_class_instance *eci,
 				 pf_count, pf_count_after);
 	}
 
+cleanup:
 	if (bo) {
 		sync[0].addr = to_user_pointer(bind_ufence);
 		__xe_vm_bind_assert(fd, vm, 0,
@@ -1864,7 +2179,7 @@ processes(int fd, int n_exec_queues, int n_execs, size_t bo_size,
 
 struct section {
 	const char *name;
-	unsigned int flags;
+	unsigned long long flags;
 };
 
 igt_main
@@ -1964,6 +2279,21 @@ igt_main
 		{ "malloc-mix-bo", MIX_BO_ALLOC },
 		{ NULL },
 	};
+	const struct section msections[] = {
+		{ "atomic-inc", MADVISE_ATOMIC_INC | ATOMIC_BATCH },
+		{ "preffered-loc-sram-migrate-pages", PREFERRED_LOC_SMEM | MIGRATE_ALL_PAGES | ATOMIC_BATCH },
+		{ "preffered-loc-atomic-vram", PREFERRED_LOC_ATOMIC_DEVICE | ATOMIC_BATCH },
+		{ "preffered-loc-atomic-gl", PREFERRED_LOC_ATOMIC_GL | ATOMIC_BATCH },
+		{ "preffered-loc-atomic-cpu", PREFERRED_LOC_ATOMIC_CPU | ATOMIC_BATCH },
+		{ "preffered-loc-atomic-und", PREFERRED_LOC_ATOMIC_UND | ATOMIC_BATCH },
+		{ "multi-vma", MADVISE_MULTI_VMA | ATOMIC_BATCH },
+		{ "split-vma", MADVISE_SPLIT_VMA | ATOMIC_BATCH },
+		{ "atomic-vma", MADVISE_ATOMIC_VMA | ATOMIC_BATCH },
+		{ "split-vma-with-mapping", PREFETCH | PREFETCH_SPLIT_VMA | ATOMIC_BATCH },
+		{ "range-invalidate-change-attr", PREFETCH | PREFETCH_CHANGE_ATTR | ATOMIC_BATCH },
+		{ "no-range-invalidate-same-attr", PREFETCH | PREFETCH_SAME_ATTR | ATOMIC_BATCH },
+		{ NULL },
+	};
 	int fd;
 	int num_sections;
 
@@ -1983,10 +2313,11 @@ igt_main
 	for (const struct section *s = sections; s[num_sections].name; num_sections++)
 		;
 
-	for (int i = 0; i < num_sections * 2; i++) {
-		struct section *s = &sections[i % num_sections];
+	for (int i = 0; i < num_sections * 3; i++) {
+		struct section p = sections[i % num_sections];
+		struct section *s = &p;
 
-		if (i/num_sections == 0) {
+		if (i/num_sections == 1) {
 			static char modified_name[256];
 			snprintf(modified_name, sizeof(modified_name), "%s-preferred-loc-smem", s->name);
 			s->name = modified_name;
@@ -2175,6 +2506,14 @@ igt_main
 			processes_evict(fd, SZ_8M, SZ_1M, s->flags);
 	}
 
+	for (const struct section *s = msections; s->name; s++) {
+		igt_subtest_f("madvise-%s", s->name) {
+			xe_for_each_engine(fd, hwe)
+				test_exec(fd, hwe, 1, 1, SZ_64K, 0, 0, NULL,
+						NULL, s->flags);
+		}
+	}
+
 	igt_fixture {
 		xe_device_put(fd);
 		drm_close_driver(fd);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* ✗ Fi.CI.BUILD: failure for series starting with [i-g-t,1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure
  2025-08-29 14:54 [PATCH i-g-t 0/5] nishit.sharma
                   ` (4 preceding siblings ...)
  2025-08-29 14:54 ` [PATCH i-g-t 5/5] tests/intel/xe_exec_system_allocator: Add atomic_batch test in IGT nishit.sharma
@ 2025-08-29 19:08 ` Patchwork
  5 siblings, 0 replies; 7+ messages in thread
From: Patchwork @ 2025-08-29 19:08 UTC (permalink / raw)
  To: nishit.sharma; +Cc: igt-dev

== Series Details ==

Series: series starting with [i-g-t,1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure
URL   : https://patchwork.freedesktop.org/series/153718/
State : failure

== Summary ==

Applying: DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure
Applying: lib/xe: Add xe_vm_madvise ioctl support
Applying: lib/xe: Add Helper to get memory attributes
Applying: tests/intel/xe_exec_system_allocator: Add preferred-loc-smem test
Applying: tests/intel/xe_exec_system_allocator: Add atomic_batch test in IGT
Using index info to reconstruct a base tree...
M	tests/intel/xe_exec_system_allocator.c
Falling back to patching base and 3-way merge...
Auto-merging tests/intel/xe_exec_system_allocator.c
CONFLICT (content): Merge conflict in tests/intel/xe_exec_system_allocator.c
Patch failed at 0005 tests/intel/xe_exec_system_allocator: Add atomic_batch test in IGT
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-08-29 19:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-29 14:54 [PATCH i-g-t 0/5] nishit.sharma
2025-08-29 14:54 ` [PATCH i-g-t 1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure nishit.sharma
2025-08-29 14:54 ` [PATCH i-g-t 2/5] lib/xe: Add xe_vm_madvise ioctl support nishit.sharma
2025-08-29 14:54 ` [PATCH i-g-t 3/5] lib/xe: Add Helper to get memory attributes nishit.sharma
2025-08-29 14:54 ` [PATCH i-g-t 4/5] tests/intel/xe_exec_system_allocator: Add preferred-loc-smem test nishit.sharma
2025-08-29 14:54 ` [PATCH i-g-t 5/5] tests/intel/xe_exec_system_allocator: Add atomic_batch test in IGT nishit.sharma
2025-08-29 19:08 ` ✗ Fi.CI.BUILD: failure for series starting with [i-g-t,1/5] DO-NOT-MERGE: include/drm-uapi: Add drm_xe_madvise structure Patchwork

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).