All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support
@ 2022-09-21  7:12 Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 1/8] vm_bind: import uapi definitions Niranjana Vishwanathapura
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM
buffer objects (BOs) or sections of a BOs at specified GPU virtual
addresses on a specified address space (VM). Multiple mappings can map
to the same physical pages of an object (aliasing). These mappings (also
referred to as persistent mappings) will be persistent across multiple
GPU submissions (execbuf calls) issued by the UMD, without user having
to provide a list of all required mappings during each submission (as
required by older execbuf mode).

The new execbuf3 ioctl (I915_GEM_EXECBUFFER3) will only work in vm_bind
mode. The vm_bind mode only works with this new execbuf3 ioctl.

Add sanity tests to validate the VM_BIND, VM_UNBIND and execbuf3 ioctls.

Add basic test to create and VM_BIND the objects and issue execbuf3 for
GPU to copy the data from a source to destination buffer.

TODOs:
* More validation support.
* Port some relevant gem_exec_* tests for execbuf3.

NOTEs:
* It is based on below VM_BIND design+uapi rfc.
  Documentation/gpu/rfc/i915_vm_bind.rst

* The i915 VM_BIND support is posted as,
  [RFC v4 00/14] drm/i915/vm_bind: Add VM_BIND functionality

v2: Address some review comments.
    Reformat patches.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>

Adam Miszczak (1):
  lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls

Niranjana Vishwanathapura (4):
  vm_bind: import uapi definitions
  tests/i915/vm_bind: Add vm_bind sanity test
  tests/i915/vm_bind: Add basic VM_BIND test support
  tests/i915/vm_bind: Add userptr subtest

Vishwanathapura, Niranjana (3):
  lib/vm_bind: Add vm_bind mode support for VM
  lib/vm_bind: Add support for VM private objects
  lib/vm_bind: Add prime_handle_to_fd_no_assert()

 include/drm-uapi/i915_drm.h      | 288 ++++++++++++++-
 lib/i915/gem_context.c           |  24 ++
 lib/i915/gem_context.h           |   3 +
 lib/i915/gem_vm.c                |  31 +-
 lib/i915/gem_vm.h                |   3 +-
 lib/i915/intel_memory_region.c   |  14 +-
 lib/i915/intel_memory_region.h   |  21 +-
 lib/intel_chipset.h              |   2 +
 lib/ioctl_wrappers.c             | 117 +++++-
 lib/ioctl_wrappers.h             |   7 +
 tests/i915/gem_create.c          |   4 +-
 tests/i915/gem_eio.c             |   2 +-
 tests/i915/gem_lmem_swapping.c   |   2 +-
 tests/i915/i915_pm_rpm.c         |   6 +-
 tests/i915/i915_query.c          |   2 +-
 tests/i915/i915_vm_bind_basic.c  | 589 +++++++++++++++++++++++++++++++
 tests/i915/i915_vm_bind_sanity.c | 249 +++++++++++++
 tests/meson.build                |   2 +
 tests/prime_mmap.c               |  26 +-
 19 files changed, 1338 insertions(+), 54 deletions(-)
 create mode 100644 tests/i915/i915_vm_bind_basic.c
 create mode 100644 tests/i915/i915_vm_bind_sanity.c

-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 1/8] vm_bind: import uapi definitions
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 2/8] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls Niranjana Vishwanathapura
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

Import required VM_BIND kernel uapi definitions.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 include/drm-uapi/i915_drm.h | 288 +++++++++++++++++++++++++++++++++++-
 1 file changed, 285 insertions(+), 3 deletions(-)

diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index b4efc96c2e..5d0e6397f4 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -470,6 +470,9 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_GEM_VM_CREATE		0x3a
 #define DRM_I915_GEM_VM_DESTROY		0x3b
 #define DRM_I915_GEM_CREATE_EXT		0x3c
+#define DRM_I915_GEM_VM_BIND		0x3d
+#define DRM_I915_GEM_VM_UNBIND		0x3e
+#define DRM_I915_GEM_EXECBUFFER3	0x3f
 /* Must be kept compact -- no holes */
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
@@ -534,6 +537,9 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_QUERY			DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
 #define DRM_IOCTL_I915_GEM_VM_CREATE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_CREATE, struct drm_i915_gem_vm_control)
 #define DRM_IOCTL_I915_GEM_VM_DESTROY	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_VM_DESTROY, struct drm_i915_gem_vm_control)
+#define DRM_IOCTL_I915_GEM_VM_BIND	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_UNBIND	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_unbind)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER3  DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
@@ -749,6 +755,25 @@ typedef struct drm_i915_irq_wait {
 /* Query if the kernel supports the I915_USERPTR_PROBE flag. */
 #define I915_PARAM_HAS_USERPTR_PROBE 56
 
+/*
+ * VM_BIND feature version supported.
+ *
+ * The following versions of VM_BIND have been defined:
+ *
+ * 0: No VM_BIND support.
+ *
+ * 1: In VM_UNBIND calls, the UMD must specify the exact mappings created
+ *    previously with VM_BIND, the ioctl will not support unbinding multiple
+ *    mappings or splitting them. Similarly, VM_BIND calls will not replace
+ *    any existing mappings.
+ *
+ * 2: The restrictions on unbinding partial or multiple mappings is
+ *    lifted, Similarly, binding will replace any mappings in the given range.
+ *
+ * See struct drm_i915_gem_vm_bind and struct drm_i915_gem_vm_unbind.
+ */
+#define I915_PARAM_VM_BIND_VERSION	57
+
 /* Must be kept compact -- no holes and well documented */
 
 typedef struct drm_i915_getparam {
@@ -1254,7 +1279,8 @@ struct drm_i915_gem_exec_fence {
 /*
  * See drm_i915_gem_execbuffer_ext_timeline_fences.
  */
-#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
+#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES  0
+#define DRM_I915_GEM_EXECBUFFER3_EXT_TIMELINE_FENCES 0
 
 /*
  * This structure describes an array of drm_syncobj and associated points for
@@ -1441,6 +1467,103 @@ struct drm_i915_gem_execbuffer2 {
 #define i915_execbuffer2_get_context_id(eb2) \
 	((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
 
+/**
+ * struct drm_i915_gem_timeline_fence - An input or output timeline fence.
+ *
+ * The operation will wait for input fence to signal.
+ *
+ * The returned output fence will be signaled after the completion of the
+ * operation.
+ */
+struct drm_i915_gem_timeline_fence {
+	/** @handle: User's handle for a drm_syncobj to wait on or signal. */
+	__u32 handle;
+
+	/**
+	 * @flags: Supported flags are:
+	 *
+	 * I915_TIMELINE_FENCE_WAIT:
+	 * Wait for the input fence before the operation.
+	 *
+	 * I915_TIMELINE_FENCE_SIGNAL:
+	 * Return operation completion fence as output.
+	 */
+	__u32 flags;
+#define I915_TIMELINE_FENCE_WAIT            (1 << 0)
+#define I915_TIMELINE_FENCE_SIGNAL          (1 << 1)
+#define __I915_TIMELINE_FENCE_UNKNOWN_FLAGS (-(I915_TIMELINE_FENCE_SIGNAL << 1))
+
+	/**
+	 * @value: A point in the timeline.
+	 * Value must be 0 for a binary drm_syncobj. A Value of 0 for a
+	 * timeline drm_syncobj is invalid as it turns a drm_syncobj into a
+	 * binary one.
+	 */
+	__u64 value;
+};
+
+/**
+ * struct drm_i915_gem_execbuffer3 - Structure for DRM_I915_GEM_EXECBUFFER3
+ * ioctl.
+ *
+ * DRM_I915_GEM_EXECBUFFER3 ioctl only works in VM_BIND mode and VM_BIND mode
+ * only works with this ioctl for submission.
+ * See I915_VM_CREATE_FLAGS_USE_VM_BIND.
+ */
+struct drm_i915_gem_execbuffer3 {
+	/**
+	 * @ctx_id: Context id
+	 *
+	 * Only contexts with user engine map are allowed.
+	 */
+	__u32 ctx_id;
+
+	/**
+	 * @engine_idx: Engine index
+	 *
+	 * An index in the user engine map of the context specified by @ctx_id.
+	 */
+	__u32 engine_idx;
+
+	/**
+	 * @batch_address: Batch gpu virtual address/es.
+	 *
+	 * For normal submission, it is the gpu virtual address of the batch
+	 * buffer. For parallel submission, it is a pointer to an array of
+	 * batch buffer gpu virtual addresses with array size equal to the
+	 * number of (parallel) engines involved in that submission (See
+	 * struct i915_context_engines_parallel_submit).
+	 */
+	__u64 batch_address;
+
+	/** @flags: Currently reserved, MBZ */
+	__u64 flags;
+#define __I915_EXEC3_UNKNOWN_FLAGS (~0)
+
+	/** @rsvd1: Reserved, MBZ */
+	__u32 rsvd1;
+
+	/** @fence_count: Number of fences in @timeline_fences array. */
+	__u32 fence_count;
+
+	/**
+	 * @timeline_fences: Pointer to an array of timeline fences.
+	 *
+	 * Timeline fences are of format struct drm_i915_gem_timeline_fence.
+	 */
+	__u64 timeline_fences;
+
+	/** @rsvd2: Reserved, MBZ */
+	__u64 rsvd2;
+
+	/**
+	 * @extensions: Zero-terminated chain of extensions.
+	 *
+	 * For future extensions. See struct i915_user_extension.
+	 */
+	__u64 extensions;
+};
+
 struct drm_i915_gem_pin {
 	/** Handle of the buffer to be pinned. */
 	__u32 handle;
@@ -2397,8 +2520,6 @@ struct drm_i915_gem_context_destroy {
  * The id of new VM (bound to the fd) for use with I915_CONTEXT_PARAM_VM is
  * returned in the outparam @id.
  *
- * No flags are defined, with all bits reserved and must be zero.
- *
  * An extension chain maybe provided, starting with @extensions, and terminated
  * by the @next_extension being 0. Currently, no extensions are defined.
  *
@@ -2410,6 +2531,9 @@ struct drm_i915_gem_context_destroy {
  */
 struct drm_i915_gem_vm_control {
 	__u64 extensions;
+#define I915_VM_CREATE_FLAGS_USE_VM_BIND	(1u << 0)
+#define I915_VM_CREATE_FLAGS_UNKNOWN \
+	(-(I915_VM_CREATE_FLAGS_USE_VM_BIND << 1))
 	__u32 flags;
 	__u32 vm_id;
 };
@@ -3400,9 +3524,13 @@ struct drm_i915_gem_create_ext {
 	 *
 	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
 	 * struct drm_i915_gem_create_ext_protected_content.
+	 *
+	 * For I915_GEM_CREATE_EXT_VM_PRIVATE usage see
+	 * struct drm_i915_gem_create_ext_vm_private.
 	 */
 #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
 #define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
+#define I915_GEM_CREATE_EXT_VM_PRIVATE 2
 	__u64 extensions;
 };
 
@@ -3504,6 +3632,160 @@ struct drm_i915_gem_create_ext_protected_content {
 /* ID of the protected content session managed by i915 when PXP is active */
 #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
 
+/**
+ * struct drm_i915_gem_create_ext_vm_private - Extension to make the object
+ * private to the specified VM.
+ *
+ * See struct drm_i915_gem_create_ext.
+ *
+ * By default, BOs can be mapped on multiple VMs and can also be dma-buf
+ * exported. Hence these BOs are referred to as Shared BOs.
+ * During each execbuf3 submission, the request fence must be added to the
+ * dma-resv fence list of all shared BOs mapped on the VM.
+ *
+ * Unlike Shared BOs, these VM private BOs can only be mapped on the VM they
+ * are private to and can't be dma-buf exported. All private BOs of a VM share
+ * the dma-resv object. Hence during each execbuf3 submission, they need only
+ * one dma-resv fence list updated. Thus, the fast path (where required
+ * mappings are already bound) submission latency is O(1) w.r.t the number of
+ * VM private BOs.
+ */
+struct drm_i915_gem_create_ext_vm_private {
+	/** @base: Extension link. See struct i915_user_extension. */
+	struct i915_user_extension base;
+
+	/** @vm_id: Id of the VM to which Object is private */
+	__u32 vm_id;
+};
+
+/**
+ * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
+ *
+ * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
+ * virtual address (VA) range to the section of an object that should be bound
+ * in the device page table of the specified address space (VM).
+ * The VA range specified must be unique (ie., not currently bound) and can
+ * be mapped to whole object or a section of the object (partial binding).
+ * Multiple VA mappings can be created to the same section of the object
+ * (aliasing).
+ *
+ * The @start, @offset and @length must be 4K page aligned. However the DG2
+ * and XEHPSDV has 64K page size for device local memory and has compact page
+ * table. On those platforms, for binding device local-memory objects, the
+ * @start, @offset and @length must be 64K aligned. Also, UMDs should not mix
+ * the local memory 64K page and the system memory 4K page bindings in the same
+ * 2M range.
+ *
+ * Error code -EINVAL will be returned if @start, @offset and @length are not
+ * properly aligned. In version 1 (See I915_PARAM_VM_BIND_VERSION), error code
+ * -ENOSPC will be returned if the VA range specified can't be reserved.
+ *
+ * VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently
+ * are not ordered. Furthermore, parts of the VM_BIND operation can be done
+ * asynchronously, if valid @fence is specified.
+ */
+struct drm_i915_gem_vm_bind {
+	/** @vm_id: VM (address space) id to bind */
+	__u32 vm_id;
+
+	/** @handle: Object handle */
+	__u32 handle;
+
+	/** @start: Virtual Address start to bind */
+	__u64 start;
+
+	/** @offset: Offset in object to bind */
+	__u64 offset;
+
+	/** @length: Length of mapping to bind */
+	__u64 length;
+
+	/**
+	 * @flags: Currently reserved, MBZ.
+	 *
+	 * Note that @fence carries its own flags.
+	 */
+	__u64 flags;
+
+	/**
+	 * @fence: Timeline fence for bind completion signaling.
+	 *
+	 * Timeline fence is of format struct drm_i915_gem_timeline_fence.
+	 *
+	 * It is an out fence, hence using I915_TIMELINE_FENCE_WAIT flag
+	 * is invalid, and an error will be returned.
+	 *
+	 * If I915_TIMELINE_FENCE_SIGNAL flag is not set, then out fence
+	 * is not requested and binding is completed synchronously.
+	 */
+	struct drm_i915_gem_timeline_fence fence;
+
+	/**
+	 * @extensions: Zero-terminated chain of extensions.
+	 *
+	 * For future extensions. See struct i915_user_extension.
+	 */
+	__u64 extensions;
+};
+
+/**
+ * struct drm_i915_gem_vm_unbind - VA to object mapping to unbind.
+ *
+ * This structure is passed to VM_UNBIND ioctl and specifies the GPU virtual
+ * address (VA) range that should be unbound from the device page table of the
+ * specified address space (VM). VM_UNBIND will force unbind the specified
+ * range from device page table without waiting for any GPU job to complete.
+ * It is UMDs responsibility to ensure the mapping is no longer in use before
+ * calling VM_UNBIND.
+ *
+ * If the specified mapping is not found, the ioctl will simply return without
+ * any error.
+ *
+ * VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently
+ * are not ordered. Furthermore, parts of the VM_UNBIND operation can be done
+ * asynchronously, if valid @fence is specified.
+ */
+struct drm_i915_gem_vm_unbind {
+	/** @vm_id: VM (address space) id to bind */
+	__u32 vm_id;
+
+	/** @rsvd: Reserved, MBZ */
+	__u32 rsvd;
+
+	/** @start: Virtual Address start to unbind */
+	__u64 start;
+
+	/** @length: Length of mapping to unbind */
+	__u64 length;
+
+	/**
+	 * @flags: Currently reserved, MBZ.
+	 *
+	 * Note that @fence carries its own flags.
+	 */
+	__u64 flags;
+
+	/**
+	 * @fence: Timeline fence for unbind completion signaling.
+	 *
+	 * Timeline fence is of format struct drm_i915_gem_timeline_fence.
+	 *
+	 * It is an out fence, hence using I915_TIMELINE_FENCE_WAIT flag
+	 * is invalid, and an error will be returned.
+	 *
+	 * If I915_TIMELINE_FENCE_SIGNAL flag is not set, then out fence
+	 * is not requested and unbinding is completed synchronously.
+	 */
+	struct drm_i915_gem_timeline_fence fence;
+
+	/**
+	 * @extensions: Zero-terminated chain of extensions.
+	 *
+	 * For future extensions. See struct i915_user_extension.
+	 */
+	__u64 extensions;
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 2/8] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 1/8] vm_bind: import uapi definitions Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 3/8] lib/vm_bind: Add vm_bind mode support for VM Niranjana Vishwanathapura
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

From: Adam Miszczak <adam.miszczak@linux.intel.com>

Add required library interfaces for new vm_bind/unbind
and execbuf3 ioctls.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/intel_chipset.h  |  2 ++
 lib/ioctl_wrappers.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
 lib/ioctl_wrappers.h |  6 ++++
 3 files changed, 86 insertions(+)

diff --git a/lib/intel_chipset.h b/lib/intel_chipset.h
index d7a6ff190f..7cf8259157 100644
--- a/lib/intel_chipset.h
+++ b/lib/intel_chipset.h
@@ -225,4 +225,6 @@ void intel_check_pch(void);
 
 #define HAS_FLATCCS(devid)	(intel_get_device_info(devid)->has_flatccs)
 
+#define HAS_64K_PAGES(devid)	(IS_DG2(devid))
+
 #endif /* _INTEL_CHIPSET_H */
diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 09eb3ce7b5..ac37b6bb43 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -706,6 +706,38 @@ void gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf)
 	igt_assert_eq(__gem_execbuf_wr(fd, execbuf), 0);
 }
 
+/**
+ * __gem_execbuf3:
+ * @fd: open i915 drm file descriptor
+ * @execbuf: execbuffer data structure
+ *
+ * This wraps the EXECBUFFER3 ioctl, which submits a batchbuffer for the gpu to
+ * run. This is allowed to fail, with -errno returned.
+ */
+int __gem_execbuf3(int fd, struct drm_i915_gem_execbuffer3 *execbuf)
+{
+	int err = 0;
+	if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER3, execbuf)) {
+		err = -errno;
+		igt_assume(err != 0);
+	}
+	errno = 0;
+	return err;
+}
+
+/**
+ * gem_execbuf3:
+ * @fd: open i915 drm file descriptor
+ * @execbuf: execbuffer data structure
+ *
+ * This wraps the EXECBUFFER3 ioctl, which submits a batchbuffer for the gpu to
+ * run.
+ */
+void gem_execbuf3(int fd, struct drm_i915_gem_execbuffer3 *execbuf)
+{
+	igt_assert_eq(__gem_execbuf3(fd, execbuf), 0);
+}
+
 /**
  * gem_madvise:
  * @fd: open i915 drm file descriptor
@@ -1328,3 +1360,49 @@ bool igt_has_drm_cap(int fd, uint64_t capability)
 	igt_assert(drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap) == 0);
 	return cap.value;
 }
+
+/* VM_BIND */
+
+int __gem_vm_bind(int fd, struct drm_i915_gem_vm_bind *bind)
+{
+	int err = 0;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_BIND, bind))
+		err = -errno;
+	return err;
+}
+
+/**
+ * gem_vm_bind:
+ * @fd: open i915 drm file descriptor
+ * @bind: vm_bind data structure
+ *
+ * This wraps the VM_BIND ioctl to bind an address range to
+ * the specified address space.
+ */
+void gem_vm_bind(int fd, struct drm_i915_gem_vm_bind *bind)
+{
+	igt_assert_eq(__gem_vm_bind(fd, bind), 0);
+}
+
+int __gem_vm_unbind(int fd, struct drm_i915_gem_vm_unbind *unbind)
+{
+	int err = 0;
+
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_VM_UNBIND, unbind))
+		err = -errno;
+	return err;
+}
+
+/**
+ * gem_vm_unbind:
+ * @fd: open i915 drm file descriptor
+ * @unbind: vm_unbind data structure
+ *
+ * This wraps the VM_UNBIND ioctl to unbind an address range from
+ * the specified address space.
+ */
+void gem_vm_unbind(int fd, struct drm_i915_gem_vm_unbind *unbind)
+{
+	igt_assert_eq(__gem_vm_unbind(fd, unbind), 0);
+}
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 9a897fec23..223cd9160c 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -84,6 +84,12 @@ void gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 int __gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 void gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
 int __gem_execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf);
+void gem_execbuf3(int fd, struct drm_i915_gem_execbuffer3 *execbuf);
+int __gem_execbuf3(int fd, struct drm_i915_gem_execbuffer3 *execbuf);
+int __gem_vm_bind(int fd, struct drm_i915_gem_vm_bind *bind);
+void gem_vm_bind(int fd, struct drm_i915_gem_vm_bind *bind);
+int __gem_vm_unbind(int fd, struct drm_i915_gem_vm_unbind *unbind);
+void gem_vm_unbind(int fd, struct drm_i915_gem_vm_unbind *unbind);
 
 #ifndef I915_GEM_DOMAIN_WC
 #define I915_GEM_DOMAIN_WC 0x80
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 3/8] lib/vm_bind: Add vm_bind mode support for VM
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 1/8] vm_bind: import uapi definitions Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 2/8] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 4/8] lib/vm_bind: Add support for VM private objects Niranjana Vishwanathapura
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

From: "Vishwanathapura, Niranjana" <niranjana.vishwanathapura@intel.com>

Add required library interfaces to create VM in
vm_bind mode and assign the VM to a context.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/i915/gem_context.c | 24 ++++++++++++++++++++++++
 lib/i915/gem_context.h |  3 +++
 lib/i915/gem_vm.c      | 31 ++++++++++++++++++++++++++-----
 lib/i915/gem_vm.h      |  3 ++-
 4 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/lib/i915/gem_context.c b/lib/i915/gem_context.c
index fe989a8d1c..2d06b41980 100644
--- a/lib/i915/gem_context.c
+++ b/lib/i915/gem_context.c
@@ -517,3 +517,27 @@ uint32_t gem_context_create_for_class(int i915,
 	*count = i;
 	return p.ctx_id;
 }
+
+uint32_t gem_context_get_vm(int fd, uint32_t ctx_id)
+{
+	struct drm_i915_gem_context_param p = {
+		.param = I915_CONTEXT_PARAM_VM,
+		.ctx_id = ctx_id,
+	};
+
+	gem_context_get_param(fd, &p);
+	igt_assert(p.value);
+
+	return p.value;
+}
+
+void gem_context_set_vm(int fd, uint32_t ctx_id, uint32_t vm_id)
+{
+	struct drm_i915_gem_context_param p = {
+		.param = I915_CONTEXT_PARAM_VM,
+		.ctx_id = ctx_id,
+		.value = vm_id,
+	};
+
+	gem_context_set_param(fd, &p);
+}
diff --git a/lib/i915/gem_context.h b/lib/i915/gem_context.h
index 505d55724e..2a2247fe10 100644
--- a/lib/i915/gem_context.h
+++ b/lib/i915/gem_context.h
@@ -63,4 +63,7 @@ void gem_context_set_persistence(int i915, uint32_t ctx, bool state);
 
 bool gem_context_has_engine(int fd, uint32_t ctx, uint64_t engine);
 
+uint32_t gem_context_get_vm(int fd, uint32_t ctx_id);
+void gem_context_set_vm(int fd, uint32_t ctx_id, uint32_t vm_id);
+
 #endif /* GEM_CONTEXT_H */
diff --git a/lib/i915/gem_vm.c b/lib/i915/gem_vm.c
index 9a022a56c7..ee3c65d06e 100644
--- a/lib/i915/gem_vm.c
+++ b/lib/i915/gem_vm.c
@@ -48,7 +48,7 @@ bool gem_has_vm(int i915)
 {
 	uint32_t vm_id = 0;
 
-	__gem_vm_create(i915, &vm_id);
+	__gem_vm_create(i915, 0, &vm_id);
 	if (vm_id)
 		gem_vm_destroy(i915, vm_id);
 
@@ -67,9 +67,9 @@ void gem_require_vm(int i915)
 	igt_require(gem_has_vm(i915));
 }
 
-int __gem_vm_create(int i915, uint32_t *vm_id)
+int __gem_vm_create(int i915, uint32_t flags, uint32_t *vm_id)
 {
-       struct drm_i915_gem_vm_control ctl = {};
+       struct drm_i915_gem_vm_control ctl = { .flags = flags };
        int err = 0;
 
        if (igt_ioctl(i915, DRM_IOCTL_I915_GEM_VM_CREATE, &ctl) == 0) {
@@ -88,7 +88,8 @@ int __gem_vm_create(int i915, uint32_t *vm_id)
  * @i915: open i915 drm file descriptor
  *
  * This wraps the VM_CREATE ioctl, which is used to allocate a new
- * address space for use with GEM contexts.
+ * address space for use with GEM contexts, with legacy execbuff
+ * method of binding.
  *
  * Returns: The id of the allocated address space.
  */
@@ -96,7 +97,27 @@ uint32_t gem_vm_create(int i915)
 {
 	uint32_t vm_id;
 
-	igt_assert_eq(__gem_vm_create(i915, &vm_id), 0);
+	igt_assert_eq(__gem_vm_create(i915, 0, &vm_id), 0);
+	igt_assert(vm_id != 0);
+
+	return vm_id;
+}
+
+/**
+ * gem_vm_create_in_vm_bind_mode:
+ * @i915: open i915 drm file descriptor
+ *
+ * This wraps the VM_CREATE ioctl with I915_VM_CREATE_FLAGS_USE_VM_BIND,
+ * flag which is used to allocate a new address space for use with GEM contexts
+ * with vm_bind mode of binding.
+ *
+ * Returns: The id of the allocated address space.
+ */
+uint32_t gem_vm_create_in_vm_bind_mode(int i915)
+{
+	uint32_t vm_id;
+
+	igt_assert_eq(__gem_vm_create(i915, I915_VM_CREATE_FLAGS_USE_VM_BIND, &vm_id), 0);
 	igt_assert(vm_id != 0);
 
 	return vm_id;
diff --git a/lib/i915/gem_vm.h b/lib/i915/gem_vm.h
index acbb663e65..6cf46d8876 100644
--- a/lib/i915/gem_vm.h
+++ b/lib/i915/gem_vm.h
@@ -31,7 +31,8 @@ bool gem_has_vm(int i915);
 void gem_require_vm(int i915);
 
 uint32_t gem_vm_create(int i915);
-int __gem_vm_create(int i915, uint32_t *vm_id);
+uint32_t gem_vm_create_in_vm_bind_mode(int i915);
+int __gem_vm_create(int i915, uint32_t flags, uint32_t *vm_id);
 
 void gem_vm_destroy(int i915, uint32_t vm_id);
 int __gem_vm_destroy(int i915, uint32_t vm_id);
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 4/8] lib/vm_bind: Add support for VM private objects
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (2 preceding siblings ...)
  2022-09-21  7:12 ` [igt-dev] [RFC v2 3/8] lib/vm_bind: Add vm_bind mode support for VM Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 5/8] lib/vm_bind: Add prime_handle_to_fd_no_assert() Niranjana Vishwanathapura
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

From: "Vishwanathapura, Niranjana" <niranjana.vishwanathapura@intel.com>

Update library interfaces to support creation of VM private
objects.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/i915/intel_memory_region.c | 14 +++++++++++---
 lib/i915/intel_memory_region.h | 21 +++++++++++++++------
 tests/i915/gem_create.c        |  4 ++--
 tests/i915/gem_eio.c           |  2 +-
 tests/i915/gem_lmem_swapping.c |  2 +-
 tests/i915/i915_pm_rpm.c       |  6 +++---
 tests/i915/i915_query.c        |  2 +-
 7 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/lib/i915/intel_memory_region.c b/lib/i915/intel_memory_region.c
index 568bace949..2d994b890d 100644
--- a/lib/i915/intel_memory_region.c
+++ b/lib/i915/intel_memory_region.c
@@ -197,10 +197,14 @@ bool gem_has_lmem(int fd)
 
 /* A version of gem_create_in_memory_region_list which can be allowed to
    fail so that the object creation can be retried */
-int __gem_create_in_memory_region_list(int fd, uint32_t *handle, uint64_t *size, uint32_t flags,
+int __gem_create_in_memory_region_list(int fd, uint32_t *handle, uint64_t *size, uint32_t flags, uint32_t vm_id,
 				       const struct drm_i915_gem_memory_class_instance *mem_regions,
 				       int num_regions)
 {
+	struct drm_i915_gem_create_ext_vm_private vm_priv = {
+		.base = { .name = I915_GEM_CREATE_EXT_VM_PRIVATE },
+		.vm_id = vm_id,
+	};
 	struct drm_i915_gem_create_ext_memory_regions ext_regions = {
 		.base = { .name = I915_GEM_CREATE_EXT_MEMORY_REGIONS },
 		.num_regions = num_regions,
@@ -208,6 +212,9 @@ int __gem_create_in_memory_region_list(int fd, uint32_t *handle, uint64_t *size,
 	};
 	int ret;
 
+	if (vm_id)
+		ext_regions.base.next_extension = to_user_pointer(&vm_priv.base);
+
 	ret = __gem_create_ext(fd, size, flags, handle, &ext_regions.base);
 	if (flags && ret == -EINVAL)
 		ret = __gem_create_ext(fd, size, 0, handle, &ext_regions.base);
@@ -230,15 +237,16 @@ int __gem_create_in_memory_region_list(int fd, uint32_t *handle, uint64_t *size,
 /* gem_create_in_memory_region_list:
  * @fd: opened i915 drm file descriptor
  * @size: requested size of the buffer
+ * @vm_id: vm_id for VM private Objects. 0 for non-private Objects.
  * @mem_regions: memory regions array (priority list)
  * @num_regions: @mem_regions length
  */
-uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags,
+uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags, uint32_t vm_id,
 					  const struct drm_i915_gem_memory_class_instance *mem_regions,
 					  int num_regions)
 {
 	uint32_t handle;
-	int ret = __gem_create_in_memory_region_list(fd, &handle, &size, flags,
+	int ret = __gem_create_in_memory_region_list(fd, &handle, &size, flags, vm_id,
 						     mem_regions, num_regions);
 	igt_assert_eq(ret, 0);
 	return handle;
diff --git a/lib/i915/intel_memory_region.h b/lib/i915/intel_memory_region.h
index fd04df83b5..4d10800558 100644
--- a/lib/i915/intel_memory_region.h
+++ b/lib/i915/intel_memory_region.h
@@ -64,11 +64,11 @@ unsigned int gem_get_lmem_region_count(int fd);
 
 bool gem_has_lmem(int fd);
 
-int __gem_create_in_memory_region_list(int fd, uint32_t *handle, uint64_t *size, uint32_t flags,
+int __gem_create_in_memory_region_list(int fd, uint32_t *handle, uint64_t *size, uint32_t flags, uint32_t vm_id,
 				       const struct drm_i915_gem_memory_class_instance *mem_regions,
 				       int num_regions);
 
-uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags,
+uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags, uint32_t vm_id,
 					  const struct drm_i915_gem_memory_class_instance *mem_regions,
 					  int num_regions);
 
@@ -84,7 +84,7 @@ uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags,
 		arr_query__[i__].memory_class = MEMORY_TYPE_FROM_REGION(arr__[i__]);  \
 		arr_query__[i__].memory_instance = MEMORY_INSTANCE_FROM_REGION(arr__[i__]);  \
 	} \
-	__gem_create_in_memory_region_list(fd, handle, size, 0, arr_query__, ARRAY_SIZE(arr_query__)); \
+	__gem_create_in_memory_region_list(fd, handle, size, 0, 0, arr_query__, ARRAY_SIZE(arr_query__)); \
 })
 #define gem_create_in_memory_regions(fd, size, regions...) ({ \
 	unsigned int arr__[] = { regions }; \
@@ -93,7 +93,7 @@ uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags,
 		arr_query__[i__].memory_class = MEMORY_TYPE_FROM_REGION(arr__[i__]);  \
 		arr_query__[i__].memory_instance = MEMORY_INSTANCE_FROM_REGION(arr__[i__]);  \
 	} \
-	gem_create_in_memory_region_list(fd, size, 0, arr_query__, ARRAY_SIZE(arr_query__)); \
+	gem_create_in_memory_region_list(fd, size, 0, 0, arr_query__, ARRAY_SIZE(arr_query__)); \
 })
 
 /*
@@ -131,7 +131,7 @@ uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags,
 		arr_query__[i__].memory_instance = 0; \
 		arr_query_size__++; \
 	} \
-	__gem_create_in_memory_region_list(fd, handle, size, ext_flags__, arr_query__, arr_query_size__); \
+	__gem_create_in_memory_region_list(fd, handle, size, ext_flags__, 0, arr_query__, arr_query_size__); \
 })
 #define gem_create_with_cpu_access_in_memory_regions(fd, size, regions...) ({ \
 	unsigned int arr__[] = { regions }; \
@@ -152,7 +152,16 @@ uint32_t gem_create_in_memory_region_list(int fd, uint64_t size, uint32_t flags,
 		arr_query__[i__].memory_instance = 0; \
 		arr_query_size__++; \
 	} \
-	gem_create_in_memory_region_list(fd, size, ext_flags__, arr_query__, arr_query_size__); \
+	gem_create_in_memory_region_list(fd, size, ext_flags__, 0, arr_query__, arr_query_size__); \
+})
+#define gem_create_vm_private_in_memory_regions(fd, size, vm_id, regions...) ({ \
+	unsigned int arr__[] = { regions };				\
+	struct drm_i915_gem_memory_class_instance arr_query__[ARRAY_SIZE(arr__)]; \
+	for (int i__  = 0; i__ < ARRAY_SIZE(arr_query__); ++i__) {	\
+		arr_query__[i__].memory_class = MEMORY_TYPE_FROM_REGION(arr__[i__]); \
+		arr_query__[i__].memory_instance = MEMORY_INSTANCE_FROM_REGION(arr__[i__]); \
+	} \
+	gem_create_in_memory_region_list(fd, size, 0, vm_id, arr_query__, ARRAY_SIZE(arr_query__)); \
 })
 
 struct igt_collection *
diff --git a/tests/i915/gem_create.c b/tests/i915/gem_create.c
index c39390f326..9255897ed8 100644
--- a/tests/i915/gem_create.c
+++ b/tests/i915/gem_create.c
@@ -207,7 +207,7 @@ static void *thread_clear(void *data)
 		npages = get_npages(&arg->max, npages);
 		size = npages << 12;
 
-		igt_assert_eq(__gem_create_in_memory_region_list(i915, &handle, &size, 0, &arg->region, 1), 0);
+		igt_assert_eq(__gem_create_in_memory_region_list(i915, &handle, &size, 0, 0, &arg->region, 1), 0);
 		if (random() & 1)
 			make_resident(i915, batch, handle);
 
@@ -315,7 +315,7 @@ static void busy_create(int i915, const struct gem_memory_region *r, int timeout
 			uint32_t handle;
 			igt_spin_t *next;
 
-			handle = gem_create_in_memory_region_list(i915, 4096, 0, &r->ci, 1);
+			handle = gem_create_in_memory_region_list(i915, 4096, 0, 0, &r->ci, 1);
 			next = __igt_spin_new(i915,
 					      .ahnd = ahnd,
 					      .ctx = ctx,
diff --git a/tests/i915/gem_eio.c b/tests/i915/gem_eio.c
index 70e82b811c..6308346747 100644
--- a/tests/i915/gem_eio.c
+++ b/tests/i915/gem_eio.c
@@ -146,7 +146,7 @@ static void test_create_ext(int fd)
 		igt_assert_eq(__gem_create_in_memory_region_list(fd,
 								 &handle,
 								 &size,
-								 0,
+								 0, 0,
 								 &r->ci, 1),
 			      0);
 
diff --git a/tests/i915/gem_lmem_swapping.c b/tests/i915/gem_lmem_swapping.c
index cccdb3195b..d6f33af68f 100644
--- a/tests/i915/gem_lmem_swapping.c
+++ b/tests/i915/gem_lmem_swapping.c
@@ -132,7 +132,7 @@ static uint32_t create_bo(int i915,
 	int ret;
 
 retry:
-	ret = __gem_create_in_memory_region_list(i915, &handle, size, 0, region, 1);
+	ret = __gem_create_in_memory_region_list(i915, &handle, size, 0, 0, region, 1);
 	if (do_oom_test && ret == -ENOMEM)
 		goto retry;
 	igt_assert_eq(ret, 0);
diff --git a/tests/i915/i915_pm_rpm.c b/tests/i915/i915_pm_rpm.c
index e95875dc70..8ea58a5e65 100644
--- a/tests/i915/i915_pm_rpm.c
+++ b/tests/i915/i915_pm_rpm.c
@@ -1117,7 +1117,7 @@ static void gem_mmap_args(const struct mmap_offset *t,
 	/* Create, map and set data while the device is active. */
 	enable_one_screen_or_forcewake_get_and_wait(&ms_data);
 
-	handle = gem_create_in_memory_region_list(drm_fd, buf_size, 0, mem_regions, 1);
+	handle = gem_create_in_memory_region_list(drm_fd, buf_size, 0, 0, mem_regions, 1);
 
 	gem_buf = __gem_mmap_offset(drm_fd, handle, 0, buf_size,
 				    PROT_READ | PROT_WRITE, t->type);
@@ -1348,7 +1348,7 @@ static void gem_execbuf_subtest(struct drm_i915_gem_memory_class_instance *mem_r
 	/* Create and set data while the device is active. */
 	enable_one_screen_or_forcewake_get_and_wait(&ms_data);
 
-	handle = gem_create_in_memory_region_list(drm_fd, dst_size, 0, mem_regions, 1);
+	handle = gem_create_in_memory_region_list(drm_fd, dst_size, 0, 0, mem_regions, 1);
 
 	cpu_buf = malloc(dst_size);
 	igt_assert(cpu_buf);
@@ -1453,7 +1453,7 @@ gem_execbuf_stress_subtest(int rounds, int wait_flags,
 	if (wait_flags & WAIT_PC8_RES)
 		handle = gem_create(drm_fd, batch_size);
 	else
-		handle = gem_create_in_memory_region_list(drm_fd, batch_size, 0, mem_regions, 1);
+		handle = gem_create_in_memory_region_list(drm_fd, batch_size, 0, 0, mem_regions, 1);
 
 	gem_write(drm_fd, handle, 0, batch_buf, batch_size);
 
diff --git a/tests/i915/i915_query.c b/tests/i915/i915_query.c
index 8befd48bb8..e061cb4a10 100644
--- a/tests/i915/i915_query.c
+++ b/tests/i915/i915_query.c
@@ -821,7 +821,7 @@ static void fill_unallocated(int fd, struct drm_i915_query_item *item, int idx,
 		if (cpu_access)
 			oh->handle = gem_create_with_cpu_access_in_memory_regions(fd, size, id);
 		else
-			oh->handle = gem_create_in_memory_region_list(fd, size, 0, &ci, 1);
+			oh->handle = gem_create_in_memory_region_list(fd, size, 0, 0, &ci, 1);
 		igt_list_add(&oh->link, &handles);
 
 		num_handles++;
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 5/8] lib/vm_bind: Add prime_handle_to_fd_no_assert()
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (3 preceding siblings ...)
  2022-09-21  7:12 ` [igt-dev] [RFC v2 4/8] lib/vm_bind: Add support for VM private objects Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 6/8] tests/i915/vm_bind: Add vm_bind sanity test Niranjana Vishwanathapura
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

From: "Vishwanathapura, Niranjana" <niranjana.vishwanathapura@intel.com>

Make prime_handle_to_fd_no_assert() as a library interface
as VM_BIND functionality will also be using it.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/ioctl_wrappers.c | 39 +++++++++++++++++++++++++++++++++------
 lib/ioctl_wrappers.h |  1 +
 tests/prime_mmap.c   | 26 ++++----------------------
 3 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index ac37b6bb43..bf7f5f430c 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -1153,28 +1153,55 @@ void gem_require_mocs_registers(int fd)
 /* prime */
 
 /**
- * prime_handle_to_fd:
+ * prime_handle_to_fd_no_assert:
  * @fd: open i915 drm file descriptor
  * @handle: file-private gem buffer object handle
+ * @flags: DRM_IOCTL_PRIME_HANDLE_TO_FD ioctl flags
+ * @fd_out: place holder for output file handle
  *
  * This wraps the PRIME_HANDLE_TO_FD ioctl, which is used to export a gem buffer
  * object into a global (i.e. potentially cross-device) dma-buf file-descriptor
  * handle.
  *
- * Returns: The created dma-buf fd handle.
+ * Returns: 0 on sucess, error otherwise. Upon success, it returns
+ *          the created dma-buf fd handle in fd_out.
  */
-int prime_handle_to_fd(int fd, uint32_t handle)
+int prime_handle_to_fd_no_assert(int fd, uint32_t handle, int flags, int *fd_out)
 {
 	struct drm_prime_handle args;
+	int ret;
 
 	memset(&args, 0, sizeof(args));
 	args.handle = handle;
-	args.flags = DRM_CLOEXEC;
+	args.flags = flags;
 	args.fd = -1;
 
-	do_ioctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
+	ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
+	if (ret)
+		ret = -errno;
+	*fd_out = args.fd;
 
-	return args.fd;
+	return ret;
+}
+
+/**
+ * prime_handle_to_fd:
+ * @fd: open i915 drm file descriptor
+ * @handle: file-private gem buffer object handle
+ *
+ * This wraps the PRIME_HANDLE_TO_FD ioctl, which is used to export a gem buffer
+ * object into a global (i.e. potentially cross-device) dma-buf file-descriptor
+ * handle. It asserts that ioctl succeeds.
+ *
+ * Returns: The created dma-buf fd handle.
+ */
+int prime_handle_to_fd(int fd, uint32_t handle)
+{
+	int dmabuf;
+
+	igt_assert_eq(prime_handle_to_fd_no_assert(fd, handle, DRM_CLOEXEC, &dmabuf), 0);
+
+	return dmabuf;
 }
 
 /**
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 223cd9160c..9f50a24153 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -143,6 +143,7 @@ struct local_dma_buf_sync {
 #define LOCAL_DMA_BUF_BASE 'b'
 #define LOCAL_DMA_BUF_IOCTL_SYNC _IOW(LOCAL_DMA_BUF_BASE, 0, struct local_dma_buf_sync)
 
+int prime_handle_to_fd_no_assert(int fd, uint32_t handle, int flags, int *fd_out);
 int prime_handle_to_fd(int fd, uint32_t handle);
 #ifndef DRM_RDWR
 #define DRM_RDWR O_RDWR
diff --git a/tests/prime_mmap.c b/tests/prime_mmap.c
index d53185ff10..4c76564907 100644
--- a/tests/prime_mmap.c
+++ b/tests/prime_mmap.c
@@ -298,24 +298,6 @@ test_dup(uint32_t region, int size)
 	close (dma_buf_fd);
 }
 
-/* Used for error case testing to avoid wrapper */
-static int prime_handle_to_fd_no_assert(uint32_t handle, int flags, int *fd_out)
-{
-	struct drm_prime_handle args;
-	int ret;
-
-	args.handle = handle;
-	args.flags = flags;
-	args.fd = -1;
-
-	ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
-	if (ret)
-		ret = errno;
-	*fd_out = args.fd;
-
-	return ret;
-}
-
 static bool has_userptr(void)
 {
 	uint32_t handle = 0;
@@ -346,9 +328,9 @@ test_userptr(uint32_t region, int size)
 	gem_userptr(fd, (uint32_t *)ptr, size, 0, 0, &handle);
 
 	/* export userptr */
-	ret = prime_handle_to_fd_no_assert(handle, DRM_CLOEXEC, &dma_buf_fd);
+	ret = prime_handle_to_fd_no_assert(fd, handle, DRM_CLOEXEC, &dma_buf_fd);
 	if (ret) {
-		igt_assert(ret == EINVAL || ret == ENODEV);
+		igt_assert(ret == -EINVAL || ret == -ENODEV);
 		goto free_userptr;
 	} else {
 		igt_assert_eq(ret, 0);
@@ -376,7 +358,7 @@ test_errors(uint32_t region, int size)
 	/* Test for invalid flags */
 	handle = gem_create_in_memory_regions(fd, size, region);
 	for (i = 0; i < ARRAY_SIZE(invalid_flags); i++) {
-		prime_handle_to_fd_no_assert(handle, invalid_flags[i], &dma_buf_fd);
+		prime_handle_to_fd_no_assert(fd, handle, invalid_flags[i], &dma_buf_fd);
 		igt_assert_eq(errno, EINVAL);
 		errno = 0;
 	}
@@ -386,7 +368,7 @@ test_errors(uint32_t region, int size)
 	handle = gem_create_in_memory_regions(fd, size, region);
 	fill_bo(handle, size);
 	gem_close(fd, handle);
-	prime_handle_to_fd_no_assert(handle, DRM_CLOEXEC, &dma_buf_fd);
+	prime_handle_to_fd_no_assert(fd, handle, DRM_CLOEXEC, &dma_buf_fd);
 	igt_assert(dma_buf_fd == -1 && errno == ENOENT);
 	errno = 0;
 
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 6/8] tests/i915/vm_bind: Add vm_bind sanity test
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (4 preceding siblings ...)
  2022-09-21  7:12 ` [igt-dev] [RFC v2 5/8] lib/vm_bind: Add prime_handle_to_fd_no_assert() Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  7:12 ` [igt-dev] [RFC v2 7/8] tests/i915/vm_bind: Add basic VM_BIND test support Niranjana Vishwanathapura
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

Add sanity test to exercise vm_bind uapi.
Test for various cases with vm_bind and vm_unbind ioctls.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_vm_bind_sanity.c | 249 +++++++++++++++++++++++++++++++
 tests/meson.build                |   1 +
 2 files changed, 250 insertions(+)
 create mode 100644 tests/i915/i915_vm_bind_sanity.c

diff --git a/tests/i915/i915_vm_bind_sanity.c b/tests/i915/i915_vm_bind_sanity.c
new file mode 100644
index 0000000000..063bdf746a
--- /dev/null
+++ b/tests/i915/i915_vm_bind_sanity.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/** @file i915_vm_bind_sanity.c
+ *
+ * This is the sanity test for VM_BIND UAPI.
+ *
+ * The goal is to test the UAPI interface.
+ */
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+
+#include "igt_syncobj.h"
+#include "i915/gem.h"
+#include "i915/gem_create.h"
+#include "igt.h"
+
+#include "i915/gem_vm.h"
+
+#define EOPNOTSUPP    95
+
+#define PAGE_SIZE   4096
+#define SZ_64K      (16 * PAGE_SIZE)
+
+IGT_TEST_DESCRIPTION("Sanity test vm_bind related interfaces");
+
+#define VA 0xa0000000
+
+static uint64_t
+gettime_ns(void)
+{
+	struct timespec current;
+	clock_gettime(CLOCK_MONOTONIC, &current);
+	return (uint64_t)current.tv_sec * NSEC_PER_SEC + current.tv_nsec;
+}
+
+static bool syncobj_busy(int fd, uint32_t handle)
+{
+	bool result;
+	int sf;
+
+	sf = syncobj_handle_to_fd(fd, handle,
+				  DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE);
+	result = poll(&(struct pollfd){sf, POLLIN}, 1, 0) == 0;
+	close(sf);
+
+	return result;
+}
+
+static inline int
+__i915_vm_bind(int fd, uint32_t vm_id, uint32_t handle, uint64_t start,
+	       uint64_t offset, uint64_t length, uint64_t flags,
+	       struct drm_i915_gem_timeline_fence *fence)
+{
+	struct drm_i915_gem_vm_bind bind;
+
+	memset(&bind, 0, sizeof(bind));
+	bind.vm_id = vm_id;
+	bind.handle = handle;
+	bind.start = start;
+	bind.offset = offset;
+	bind.length = length;
+	bind.flags = flags;
+	if (fence)
+		bind.fence = *fence;
+
+	return __gem_vm_bind(fd, &bind);
+}
+
+static inline void
+i915_vm_bind(int fd, uint32_t vm_id, uint32_t handle, uint64_t start,
+	     uint64_t offset, uint64_t length, uint64_t flags,
+	     struct drm_i915_gem_timeline_fence *fence)
+{
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, start,
+				     offset, length, flags, fence), 0);
+	if (fence) {
+		igt_assert(syncobj_timeline_wait(fd, &fence->handle, (uint64_t *)&fence->value,
+						 1, gettime_ns() + (2 * NSEC_PER_SEC),
+						 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+		igt_assert(!syncobj_busy(fd, fence->handle));
+	}
+}
+
+static inline int
+__i915_vm_unbind(int fd, uint32_t vm_id, uint64_t start, uint64_t length, uint64_t flags)
+{
+	struct drm_i915_gem_vm_unbind unbind;
+
+	memset(&unbind, 0, sizeof(unbind));
+	unbind.vm_id = vm_id;
+	unbind.start = start;
+	unbind.length = length;
+	unbind.flags = flags;
+
+	return __gem_vm_unbind(fd, &unbind);
+}
+
+static inline void
+i915_vm_unbind(int fd, uint32_t vm_id, uint64_t start, uint64_t length, uint64_t flags)
+{
+	igt_assert_eq(__i915_vm_unbind(fd, vm_id, start, length, flags), 0);
+}
+
+static void basic(int fd, bool test_lmem)
+{
+	uint32_t vm_id, vm_id2, vm_id_exec_mode, handle, pg_size, size;
+	unsigned int region = test_lmem ? REGION_LMEM(0) : REGION_SMEM;
+	struct drm_i915_gem_timeline_fence fence = {
+		.handle = syncobj_create(fd, 0),
+		.flags = I915_TIMELINE_FENCE_SIGNAL,
+		.value = 0,
+	};
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj;
+	const intel_ctx_t *ctx;
+	int dmabuf;
+
+	pg_size = (test_lmem && HAS_64K_PAGES(intel_get_drm_devid(fd))) ? SZ_64K : PAGE_SIZE;
+	size = pg_size * 4;
+
+	vm_id = gem_vm_create_in_vm_bind_mode(fd);
+	handle = gem_create_in_memory_regions(fd, size, region);
+
+	/* Bind and unbind */
+	i915_vm_bind(fd, vm_id, handle, VA, 0, size, 0, NULL);
+	i915_vm_unbind(fd, vm_id, VA, size, 0);
+
+	/* Bind with out fence */
+	i915_vm_bind(fd, vm_id, handle, VA, 0, size, 0, &fence);
+	i915_vm_unbind(fd, vm_id, VA, size, 0);
+
+	/* Aliasing bind and unbind */
+	i915_vm_bind(fd, vm_id, handle, VA, 0, size, 0, NULL);
+	i915_vm_bind(fd, vm_id, handle, VA + size, 0, size, 0, NULL);
+	i915_vm_unbind(fd, vm_id, VA, size, 0);
+	i915_vm_unbind(fd, vm_id, VA + size, size, 0);
+
+	/* Invalid handle */
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle + 10, VA, 0, size, 0, NULL), -ENOENT);
+
+	/* Invalid mapping range */
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, 0, 0, 0, NULL), -EINVAL);
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, pg_size, size, 0, NULL), -EINVAL);
+
+	/* Unaligned binds */
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, pg_size / 2, pg_size, 0, NULL), -EINVAL);
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, 0, pg_size / 2, 0, NULL), -EINVAL);
+
+	/* range overflow binds */
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, pg_size, -pg_size, 0, NULL), -EINVAL);
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, pg_size * 2, -pg_size, 0, NULL), -EINVAL);
+
+	/* re-bind VA range without unbinding */
+	i915_vm_bind(fd, vm_id, handle, VA, 0, size, 0, NULL);
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, 0, size, 0, NULL), -EEXIST);
+	i915_vm_unbind(fd, vm_id, VA, size, 0);
+
+	/* unbind a non-existing mapping */
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, 0, VA + VA, 0, size, 0, NULL), -ENOENT);
+
+	/* unbind with length mismatch */
+	i915_vm_bind(fd, vm_id, handle, VA, 0, size, 0, NULL);
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, 0, size * 2, 0, NULL), -EINVAL);
+	i915_vm_unbind(fd, vm_id, VA, size, 0);
+
+	/* validate exclusivity of vm_bind & exec modes of binding */
+	vm_id_exec_mode = gem_vm_create(fd);
+	igt_assert_eq(__i915_vm_bind(fd, vm_id_exec_mode, handle, VA, 0, size, 0, NULL), -EOPNOTSUPP);
+
+	ctx = intel_ctx_create_all_physical(fd);
+	gem_context_set_vm(fd, ctx->id, vm_id);
+	(void)gem_context_get_vm(fd, ctx->id);
+
+	memset(&obj, 0, sizeof(obj));
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	obj.handle = handle;
+	i915_execbuffer2_set_context_id(execbuf, ctx->id);
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EOPNOTSUPP);
+
+	intel_ctx_destroy(fd, ctx);
+	gem_vm_destroy(fd, vm_id_exec_mode);
+	gem_close(fd, handle);
+
+	/* validate VM private objects */
+	vm_id2 = gem_vm_create_in_vm_bind_mode(fd);
+	handle = gem_create_vm_private_in_memory_regions(fd, size, vm_id2, region);
+
+	igt_assert_eq(prime_handle_to_fd_no_assert(fd, handle, DRM_CLOEXEC, &dmabuf), -EINVAL);
+	igt_assert_eq(__i915_vm_bind(fd, vm_id, handle, VA, 0, size, 0, NULL), -EINVAL);
+	i915_vm_bind(fd, vm_id2, handle, VA, 0, size, 0, NULL);
+	i915_vm_unbind(fd, vm_id2, VA, size, 0);
+
+	gem_close(fd, handle);
+	gem_vm_destroy(fd, vm_id2);
+	gem_vm_destroy(fd, vm_id);
+	syncobj_destroy(fd, fence.handle);
+}
+
+static int vm_bind_version(int fd)
+{
+	struct drm_i915_getparam gp;
+	int value = 0;
+
+	memset(&gp, 0, sizeof(gp));
+	gp.param = I915_PARAM_VM_BIND_VERSION;
+	gp.value = &value;
+
+	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
+	errno = 0;
+
+	return value;
+}
+
+igt_main
+{
+	int fd;
+	bool has_lmem;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		igt_require(vm_bind_version(fd) == 1);
+		has_lmem = gem_has_lmem(fd);
+	}
+
+	igt_describe("Basic vm_bind sanity test with SMEM");
+	igt_subtest_f("basic-smem") {
+		basic(fd, false);
+	}
+
+	if (has_lmem) {
+		igt_describe("Basic vm_bind sanity test with LMEM");
+		igt_subtest_f("basic-lmem")
+			basic(fd, true);
+	}
+
+	igt_fixture {
+		close(fd);
+	}
+
+	igt_exit();
+}
diff --git a/tests/meson.build b/tests/meson.build
index eb38c17fe8..3ee2230543 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -249,6 +249,7 @@ i915_progs = [
 	'sysfs_heartbeat_interval',
 	'sysfs_preempt_timeout',
 	'sysfs_timeslice_duration',
+	'i915_vm_bind_sanity',
 ]
 
 msm_progs = [
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 7/8] tests/i915/vm_bind: Add basic VM_BIND test support
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (5 preceding siblings ...)
  2022-09-21  7:12 ` [igt-dev] [RFC v2 6/8] tests/i915/vm_bind: Add vm_bind sanity test Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  8:55   ` Petri Latvala
  2022-09-21  7:12 ` [igt-dev] [RFC v2 8/8] tests/i915/vm_bind: Add userptr subtest Niranjana Vishwanathapura
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

Add basic tests for VM_BIND functionality. Bind the buffer objects in
device page table with VM_BIND calls and have GPU copy the data from a
source buffer object to destination buffer object.
Test for different buffer sizes, buffer object placement and with
multiple contexts.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_vm_bind_basic.c | 544 ++++++++++++++++++++++++++++++++
 tests/meson.build               |   1 +
 2 files changed, 545 insertions(+)
 create mode 100644 tests/i915/i915_vm_bind_basic.c

diff --git a/tests/i915/i915_vm_bind_basic.c b/tests/i915/i915_vm_bind_basic.c
new file mode 100644
index 0000000000..b3aa8eac9b
--- /dev/null
+++ b/tests/i915/i915_vm_bind_basic.c
@@ -0,0 +1,544 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/** @file i915_vm_bind_basic.c
+ *
+ * This is the basic test for VM_BIND functionality.
+ *
+ * The goal is to ensure that basics work.
+ */
+
+#include <sys/poll.h>
+
+#include "i915/gem.h"
+#include "igt.h"
+#include "igt_syncobj.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include "drm.h"
+#include "i915/gem_vm.h"
+
+IGT_TEST_DESCRIPTION("Basic test for vm_bind functionality");
+
+#define PAGE_SIZE   4096
+#define PAGE_SHIFT  12
+
+#define GEN9_XY_FAST_COPY_BLT_CMD       (2 << 29 | 0x42 << 22)
+#define BLT_DEPTH_32                    (3 << 24)
+
+#define DEFAULT_BUFF_SIZE  (4 * PAGE_SIZE)
+#define SZ_64K             (16 * PAGE_SIZE)
+#define SZ_2M              (512 * PAGE_SIZE)
+
+#define MAX_CTXTS   2
+#define MAX_CMDS    4
+
+#define BATCH_FENCE  0
+#define SRC_FENCE    1
+#define DST_FENCE    2
+#define EXEC_FENCE   3
+#define NUM_FENCES   4
+
+enum {
+	BATCH_MAP,
+	SRC_MAP,
+	DST_MAP = SRC_MAP + MAX_CMDS,
+	MAX_MAP
+};
+
+struct mapping {
+	uint32_t  obj;
+	uint64_t  va;
+	uint64_t  offset;
+	uint64_t  length;
+	uint64_t  flags;
+};
+
+#define SET_MAP(map, _obj, _va, _offset, _length, _flags)   \
+{                                  \
+	(map).obj = _obj;          \
+	(map).va = _va;            \
+	(map).offset = _offset;	   \
+	(map).length = _length;	   \
+	(map).flags = _flags;	   \
+}
+
+#define MAX_BATCH_DWORD    64
+
+#define abs(x) ((x) >= 0 ? (x) : -(x))
+
+#define TEST_SMEM             BIT(0)
+#define TEST_SKIP_UNBIND      BIT(1)
+#define TEST_SHARE_VM         BIT(2)
+
+#define is_lmem(cfg)        (!((cfg)->flags & TEST_SMEM))
+#define do_unbind(cfg)      (!((cfg)->flags & TEST_SKIP_UNBIND))
+#define do_share_vm(cfg)    ((cfg)->flags & TEST_SHARE_VM)
+
+struct test_cfg {
+	const char *name;
+	uint32_t size;
+	uint8_t num_cmds;
+	uint32_t num_ctxts;
+	uint32_t flags;
+};
+
+static uint64_t
+gettime_ns(void)
+{
+	struct timespec current;
+	clock_gettime(CLOCK_MONOTONIC, &current);
+	return (uint64_t)current.tv_sec * NSEC_PER_SEC + current.tv_nsec;
+}
+
+static bool syncobj_busy(int fd, uint32_t handle)
+{
+	bool result;
+	int sf;
+
+	sf = syncobj_handle_to_fd(fd, handle,
+				  DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE);
+	result = poll(&(struct pollfd){sf, POLLIN}, 1, 0) == 0;
+	close(sf);
+
+	return result;
+}
+
+static inline void i915_vm_bind(int fd, uint32_t vm_id, struct mapping *m,
+				struct drm_i915_gem_timeline_fence *fence)
+{
+	struct drm_i915_gem_vm_bind bind;
+
+	memset(&bind, 0, sizeof(bind));
+	bind.vm_id = vm_id;
+	bind.handle = m->obj;
+	bind.start = m->va;
+	bind.offset = m->offset;
+	bind.length = m->length;
+	bind.flags = m->flags;
+	if (fence) {
+		bind.fence.flags |= I915_TIMELINE_FENCE_SIGNAL;
+		bind.fence.handle = syncobj_create(fd, 0);
+		bind.fence.value = 0;
+
+		fence->handle = bind.fence.handle;
+		fence->flags = I915_TIMELINE_FENCE_WAIT;
+		fence->value = bind.fence.value;
+	}
+
+	igt_info("VM_BIND vm:0x%x h:0x%x v:0x%lx o:0x%lx l:0x%lx f:0x%llx\n",
+		 vm_id, m->obj, m->va, m->offset, m->length, bind.flags);
+	gem_vm_bind(fd, &bind);
+}
+
+static inline void i915_vm_unbind(int fd, uint32_t vm_id, struct mapping *m)
+{
+	struct drm_i915_gem_vm_unbind unbind;
+
+	/* Object handle is not required during unbind */
+	igt_info("VM_UNBIND vm:0x%x v:0x%lx l:0x%lx f:0x%lx\n",
+		 vm_id, m->va, m->length, m->flags);
+	memset(&unbind, 0, sizeof(unbind));
+	unbind.vm_id = vm_id;
+	unbind.start = m->va;
+	unbind.length = m->length;
+	unbind.flags = m->flags;
+
+	gem_vm_unbind(fd, &unbind);
+}
+
+static void print_buffer(void *buf, uint32_t size,
+			 const char *str, bool full)
+{
+	uint32_t i = 0;
+
+	igt_debug("Printing %s 0x%lx size 0x%x\n", str, (uint64_t)buf, size);
+	while (i < size) {
+		uint32_t *b = buf + i;
+
+		igt_debug("\t%s[0x%04x]: 0x%08x 0x%08x 0x%08x 0x%08x %s\n",
+			  str, i, b[0], b[1], b[2], b[3], full ? "" : "...");
+		i += full ? 16 : PAGE_SIZE;
+	}
+}
+
+static int gem_linear_fast_blt(uint32_t *batch, uint64_t src,
+			       uint64_t dst, uint32_t size)
+{
+	uint32_t *cmd = batch;
+	uint64_t src_offset = (uint64_t)src;
+	uint64_t dst_offset = (uint64_t)dst;
+
+	*cmd++ = GEN9_XY_FAST_COPY_BLT_CMD | (10 - 2);
+	*cmd++ = BLT_DEPTH_32 | PAGE_SIZE;
+	*cmd++ = 0;
+	*cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
+	*cmd++ = lower_32_bits(dst_offset);
+	*cmd++ = upper_32_bits(dst_offset);
+	*cmd++ = 0;
+	*cmd++ = PAGE_SIZE;
+	*cmd++ = lower_32_bits(src_offset);
+	*cmd++ = upper_32_bits(src_offset);
+
+	*cmd++ = MI_BATCH_BUFFER_END;
+	*cmd++ = 0;
+
+	return ALIGN((cmd - batch + 1) * sizeof(uint32_t), 8);
+}
+
+static void __gem_copy(int fd, uint64_t src, uint64_t dst, uint32_t offset, uint32_t size,
+		       uint32_t ctx_id, void *batch_addr, unsigned int eb_flags,
+		       struct drm_i915_gem_timeline_fence *fence)
+{
+	uint32_t len, buf[MAX_BATCH_DWORD] = { 0 };
+	struct drm_i915_gem_execbuffer3 execbuf;
+
+	len = gem_linear_fast_blt(buf, src + offset, dst + offset, size);
+
+	memcpy(batch_addr, (void *)buf, len);
+	print_buffer(buf, len, "batch", true);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.ctx_id = ctx_id;
+	execbuf.batch_address = (uint64_t)&batch_addr;
+	execbuf.engine_idx = eb_flags;
+	execbuf.fence_count = NUM_FENCES;
+	execbuf.timeline_fences = to_user_pointer(fence);
+	gem_execbuf3(fd, &execbuf);
+}
+
+static void i915_gem_copy(int fd, uint64_t src, uint64_t dst, uint32_t size,
+			  const intel_ctx_t **ctx, uint32_t num_ctxts,
+			  void **batch_addr, unsigned int eb_flags,
+			  struct drm_i915_gem_timeline_fence (*fence)[NUM_FENCES])
+{
+	uint32_t i, delta = size / num_ctxts;
+
+	for (i = 0; i < num_ctxts; i++) {
+		igt_info("Issuing gem copy on ctx 0x%x\n", ctx[i]->id);
+		__gem_copy(fd, src, dst, (i * delta), delta,
+			   ctx[i]->id, batch_addr[i], eb_flags, fence[i]);
+	}
+}
+
+static void i915_gem_sync(int fd, const intel_ctx_t **ctx, uint32_t num_ctxts,
+			  struct drm_i915_gem_timeline_fence (*fence)[NUM_FENCES])
+{
+	uint32_t i;
+
+	for (i = 0; i < num_ctxts; i++) {
+		uint64_t fence_value = 0;
+
+		igt_assert(syncobj_timeline_wait(fd, &fence[i][EXEC_FENCE].handle,
+						 (uint64_t *)&fence_value, 1,
+						 gettime_ns() + (2 * NSEC_PER_SEC),
+						 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+		igt_assert(!syncobj_busy(fd, fence[i][EXEC_FENCE].handle));
+		igt_info("gem copy completed on ctx 0x%x\n", ctx[i]->id);
+	}
+}
+
+static struct igt_collection *get_region_set(int fd, struct test_cfg *cfg)
+{
+	uint32_t mem_type[] = { I915_SYSTEM_MEMORY, I915_DEVICE_MEMORY };
+	uint32_t lmem_type[] = { I915_DEVICE_MEMORY };
+	struct drm_i915_query_memory_regions *query_info;
+
+	query_info = gem_get_query_memory_regions(fd);
+	igt_assert(query_info);
+
+	if (is_lmem(cfg))
+		return __get_memory_region_set(query_info, lmem_type, 1);
+	else
+		return __get_memory_region_set(query_info, mem_type, 2);
+}
+
+static void create_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint32_t size,
+			    uint32_t num_cmds, void *src_addr[])
+{
+	int i;
+	struct igt_collection *set = get_region_set(fd, cfg);
+	uint32_t region;
+
+	for (i = 0; i < num_cmds; i++) {
+		region = igt_collection_get_value(set, i % set->size);
+		src[i] = gem_create_in_memory_regions(fd, size, region);
+		src_addr[i] = gem_mmap__cpu(fd, src[i], 0, size, PROT_WRITE);
+	}
+}
+
+static void destroy_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint32_t size,
+			     uint32_t num_cmds, void *src_addr[])
+{
+	int i;
+
+	for (i = 0; i < num_cmds; i++) {
+		igt_assert(gem_munmap(src_addr[i], size) == 0);
+		igt_debug("Closing object 0x%x\n", src[i]);
+		gem_close(fd, src[i]);
+	}
+}
+
+static uint32_t create_dst_obj(int fd, struct test_cfg *cfg, uint32_t size, void **dst_addr)
+{
+	uint32_t dst;
+	struct igt_collection *set = get_region_set(fd, cfg);
+
+	dst = gem_create_in_memory_regions(fd, size, igt_collection_get_value(set, 0));
+	*dst_addr = gem_mmap__cpu(fd, dst, 0, size, PROT_WRITE);
+
+	return dst;
+}
+
+static void destroy_dst_obj(int fd, struct test_cfg *cfg, uint32_t dst, uint32_t size, void *dst_addr)
+{
+	igt_assert(gem_munmap(dst_addr, size) == 0);
+	igt_debug("Closing object 0x%x\n", dst);
+	gem_close(fd, dst);
+}
+
+static void pattern_fill_buf(void *src_addr[], uint32_t size, uint32_t num_cmds, uint32_t npages)
+{
+	uint32_t i, j;
+	void *buf;
+
+	/* Allocate buffer and fill pattern */
+	buf = malloc(size);
+	igt_require(buf);
+
+	for (i = 0; i < num_cmds; i++) {
+		for (j = 0; j < npages; j++)
+			memset(buf + j * PAGE_SIZE, i * npages + j + 1, PAGE_SIZE);
+
+		memcpy(src_addr[i], buf, size);
+	}
+
+	free(buf);
+}
+
+static void run_test(int fd, const intel_ctx_t *base_ctx, struct test_cfg *cfg,
+		     const struct intel_execution_engine2 *e)
+{
+	void *src_addr[MAX_CMDS] = { 0 }, *dst_addr = NULL;
+	uint32_t src[MAX_CMDS], dst, i, size = cfg->size;
+	struct drm_i915_gem_timeline_fence exec_fence[MAX_CTXTS][NUM_FENCES];
+	uint32_t shared_vm_id, vm_id[MAX_CTXTS];
+	struct mapping map[MAX_CTXTS][MAX_MAP];
+	uint32_t num_ctxts = cfg->num_ctxts;
+	uint32_t num_cmds = cfg->num_cmds;
+	uint32_t npages = size / PAGE_SIZE;
+	const intel_ctx_t *ctx[MAX_CTXTS];
+	bool share_vm = do_share_vm(cfg);
+	void *batch_addr[MAX_CTXTS];
+	uint32_t batch[MAX_CTXTS];
+	uint64_t src_va, dst_va;
+	uint32_t delta;
+
+	delta = size / num_ctxts;
+	if (share_vm)
+		shared_vm_id = gem_vm_create_in_vm_bind_mode(fd);
+
+	/* Create contexts */
+	num_ctxts = min_t(num_ctxts, MAX_CTXTS, num_ctxts);
+	for (i = 0; i < num_ctxts; i++) {
+		uint32_t vmid;
+
+		if (share_vm)
+			vmid = shared_vm_id;
+		else
+			vmid = gem_vm_create_in_vm_bind_mode(fd);
+
+		ctx[i] = intel_ctx_create(fd, &base_ctx->cfg);
+		gem_context_set_vm(fd, ctx[i]->id, vmid);
+		vm_id[i] = gem_context_get_vm(fd, ctx[i]->id);
+
+		exec_fence[i][EXEC_FENCE].handle = syncobj_create(fd, 0);
+		exec_fence[i][EXEC_FENCE].flags = I915_TIMELINE_FENCE_SIGNAL;
+		exec_fence[i][EXEC_FENCE].value = 0;
+	}
+
+	/* Create objects */
+	num_cmds = min_t(num_cmds, MAX_CMDS, num_cmds);
+	create_src_objs(fd, cfg, src, size, num_cmds, src_addr);
+	dst = create_dst_obj(fd, cfg, size, &dst_addr);
+
+	/*
+	 * mmap'ed addresses are not 64K aligned. On platforms requiring
+	 * 64K alignment, use static addresses.
+	 */
+	if (size < SZ_2M && num_cmds && !HAS_64K_PAGES(intel_get_drm_devid(fd))) {
+		src_va = (uint64_t)src_addr[0];
+		dst_va = (uint64_t)dst_addr;
+	} else {
+		src_va = 0xa000000;
+		dst_va = 0xb000000;
+	}
+
+	pattern_fill_buf(src_addr, size, num_cmds, npages);
+
+	if (num_cmds)
+		print_buffer(src_addr[num_cmds - 1], size, "src_obj", false);
+
+	for (i = 0; i < num_ctxts; i++) {
+		batch[i] = gem_create_vm_private_in_memory_regions(fd, PAGE_SIZE, vm_id[i], REGION_SMEM);
+		batch_addr[i] = gem_mmap__cpu(fd, batch[i], 0, PAGE_SIZE, PROT_WRITE);
+	}
+
+	/* Create mappings */
+	for (i = 0; i < num_ctxts; i++) {
+		uint64_t offset = i * delta;
+		uint32_t j;
+
+		for (j = 0; j < num_cmds; j++)
+			SET_MAP(map[i][SRC_MAP + j], src[j], src_va + offset, offset, delta, 0);
+		SET_MAP(map[i][DST_MAP], dst, dst_va + offset, offset, delta, 0);
+		SET_MAP(map[i][BATCH_MAP], batch[i], (uint64_t)batch_addr[i], 0, PAGE_SIZE, 0);
+	}
+
+	/* Bind the buffers to device page table */
+	for (i = 0; i < num_ctxts; i++) {
+		i915_vm_bind(fd, vm_id[i], &map[i][BATCH_MAP], &exec_fence[i][BATCH_FENCE]);
+		i915_vm_bind(fd, vm_id[i], &map[i][DST_MAP], &exec_fence[i][DST_FENCE]);
+	}
+
+	/* Have GPU do the copy */
+	for (i = 0; i < cfg->num_cmds; i++) {
+		uint32_t j;
+
+		for (j = 0; j < num_ctxts; j++)
+			i915_vm_bind(fd, vm_id[j], &map[j][SRC_MAP + i], &exec_fence[j][SRC_FENCE]);
+
+		i915_gem_copy(fd, src_va, dst_va, size, ctx, num_ctxts,
+			      batch_addr, e->flags, exec_fence);
+
+		i915_gem_sync(fd, ctx, num_ctxts, exec_fence);
+
+		for (j = 0; j < num_ctxts; j++) {
+			syncobj_destroy(fd, exec_fence[j][SRC_FENCE].handle);
+			if (do_unbind(cfg))
+				i915_vm_unbind(fd, vm_id[j], &map[j][SRC_MAP + i]);
+		}
+	}
+
+	/*
+	 * Unbind buffers from device page table.
+	 * If not, it should get unbound while freeing the buffer.
+	 */
+	for (i = 0; i < num_ctxts; i++) {
+		syncobj_destroy(fd, exec_fence[i][BATCH_FENCE].handle);
+		syncobj_destroy(fd, exec_fence[i][DST_FENCE].handle);
+		if (do_unbind(cfg)) {
+			i915_vm_unbind(fd, vm_id[i], &map[i][BATCH_MAP]);
+			i915_vm_unbind(fd, vm_id[i], &map[i][DST_MAP]);
+		}
+	}
+
+	/* Close batch buffers */
+	for (i = 0; i < num_ctxts; i++) {
+		syncobj_destroy(fd, exec_fence[i][EXEC_FENCE].handle);
+		gem_close(fd, batch[i]);
+	}
+
+	/* Accessing the buffer will migrate the pages from device to host */
+	print_buffer(dst_addr, size, "dst_obj", false);
+
+	/* Validate by comparing the last SRC with DST */
+	if (num_cmds)
+		igt_assert(memcmp(src_addr[num_cmds - 1], dst_addr, size) == 0);
+
+	/* Free the objects */
+	destroy_src_objs(fd, cfg, src, size, num_cmds, src_addr);
+	destroy_dst_obj(fd, cfg, dst, size, dst_addr);
+
+	/* Done with the contexts */
+	for (i = 0; i < num_ctxts; i++) {
+		igt_debug("Destroying context 0x%x\n", ctx[i]->id);
+		gem_vm_destroy(fd, vm_id[i]);
+		intel_ctx_destroy(fd, ctx[i]);
+	}
+
+	if (share_vm)
+		gem_vm_destroy(fd, shared_vm_id);
+}
+
+static int vm_bind_version(int fd)
+{
+	struct drm_i915_getparam gp;
+	int value = 0;
+
+	memset(&gp, 0, sizeof(gp));
+	gp.param = I915_PARAM_VM_BIND_VERSION;
+	gp.value = &value;
+
+	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
+	errno = 0;
+
+	return value;
+}
+
+igt_main
+{
+	struct test_cfg *t, tests[] = {
+		{"basic", 0, 1, 1, 0},
+		{"multi_cmds", 0, MAX_CMDS, 1, 0},
+		{"skip_copy", 0, 0, 1, 0},
+		{"skip_unbind",  0, 1, 1, TEST_SKIP_UNBIND},
+		{"multi_ctxts", 0, 1, MAX_CTXTS, 0},
+		{"share_vm", 0, 1, MAX_CTXTS, TEST_SHARE_VM},
+		{"64K", (16 * PAGE_SIZE), 1, 1, 0},
+		{"2M", SZ_2M, 1, 1, 0},
+		{"smem", 0, 1, 1, TEST_SMEM},
+		{"smem_multi_cmds", 0, MAX_CMDS, 1, TEST_SMEM},
+		{ }
+	};
+	int fd;
+	bool has_lmem;
+	uint32_t def_size;
+	struct intel_execution_engine2 *e;
+	const intel_ctx_t *ctx;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		igt_require(vm_bind_version(fd) == 1);
+		has_lmem = gem_has_lmem(fd);
+		def_size = HAS_64K_PAGES(intel_get_drm_devid(fd)) ?
+			   SZ_64K : DEFAULT_BUFF_SIZE;
+		ctx = intel_ctx_create_all_physical(fd);
+	}
+
+	/* Adjust test variables */
+	for (t = tests; t->name; t++) {
+		t->flags |= (has_lmem ? 0 : TEST_SMEM);
+		t->size = t->size ? : (def_size * abs(t->num_ctxts));
+	}
+
+	for (t = tests; t->name; t++) {
+		igt_describe_f("vm_bind %s test", t->name);
+		igt_subtest_with_dynamic_f("%s", t->name)
+			for_each_ctx_engine(fd, ctx, e) {
+				if (e->class == I915_ENGINE_CLASS_COPY) {
+					igt_dynamic(e->name) {
+						run_test(fd, ctx, t, e);
+					}
+				}
+			}
+	}
+
+	igt_fixture {
+		intel_ctx_destroy(fd, ctx);
+		close(fd);
+	}
+
+	igt_exit();
+}
diff --git a/tests/meson.build b/tests/meson.build
index 3ee2230543..b4348130d6 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -250,6 +250,7 @@ i915_progs = [
 	'sysfs_preempt_timeout',
 	'sysfs_timeslice_duration',
 	'i915_vm_bind_sanity',
+	'i915_vm_bind_basic',
 ]
 
 msm_progs = [
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [RFC v2 8/8] tests/i915/vm_bind: Add userptr subtest
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (6 preceding siblings ...)
  2022-09-21  7:12 ` [igt-dev] [RFC v2 7/8] tests/i915/vm_bind: Add basic VM_BIND test support Niranjana Vishwanathapura
@ 2022-09-21  7:12 ` Niranjana Vishwanathapura
  2022-09-21  7:53 ` [igt-dev] ✗ GitLab.Pipeline: warning for vm_bind: Add VM_BIND validation support (rev2) Patchwork
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21  7:12 UTC (permalink / raw)
  To: igt-dev; +Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter

Add userptr object type to vm_bind_basic test.

Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_vm_bind_basic.c | 63 ++++++++++++++++++++++++++++-----
 1 file changed, 54 insertions(+), 9 deletions(-)

diff --git a/tests/i915/i915_vm_bind_basic.c b/tests/i915/i915_vm_bind_basic.c
index b3aa8eac9b..4db1311d43 100644
--- a/tests/i915/i915_vm_bind_basic.c
+++ b/tests/i915/i915_vm_bind_basic.c
@@ -80,10 +80,12 @@ struct mapping {
 #define TEST_SMEM             BIT(0)
 #define TEST_SKIP_UNBIND      BIT(1)
 #define TEST_SHARE_VM         BIT(2)
+#define TEST_USERPTR          BIT(3)
 
 #define is_lmem(cfg)        (!((cfg)->flags & TEST_SMEM))
 #define do_unbind(cfg)      (!((cfg)->flags & TEST_SKIP_UNBIND))
 #define do_share_vm(cfg)    ((cfg)->flags & TEST_SHARE_VM)
+#define is_userptr(cfg)     ((cfg)->flags & TEST_USERPTR)
 
 struct test_cfg {
 	const char *name;
@@ -267,13 +269,21 @@ static void create_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint32
 			    uint32_t num_cmds, void *src_addr[])
 {
 	int i;
-	struct igt_collection *set = get_region_set(fd, cfg);
-	uint32_t region;
 
-	for (i = 0; i < num_cmds; i++) {
-		region = igt_collection_get_value(set, i % set->size);
-		src[i] = gem_create_in_memory_regions(fd, size, region);
-		src_addr[i] = gem_mmap__cpu(fd, src[i], 0, size, PROT_WRITE);
+	if (is_userptr(cfg)) {
+		for (i = 0; i < num_cmds; i++) {
+			igt_assert(posix_memalign(&src_addr[i], SZ_2M, size) == 0);
+			gem_userptr(fd, src_addr[i], size, 0, 0, &src[i]);
+		}
+	} else {
+		struct igt_collection *set = get_region_set(fd, cfg);
+		uint32_t region;
+
+		for (i = 0; i < num_cmds; i++) {
+			region = igt_collection_get_value(set, i % set->size);
+			src[i] = gem_create_in_memory_regions(fd, size, region);
+			src_addr[i] = gem_mmap__cpu(fd, src[i], 0, size, PROT_WRITE);
+		}
 	}
 }
 
@@ -286,16 +296,25 @@ static void destroy_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint3
 		igt_assert(gem_munmap(src_addr[i], size) == 0);
 		igt_debug("Closing object 0x%x\n", src[i]);
 		gem_close(fd, src[i]);
+		if (is_userptr(cfg))
+			free(src_addr[i]);
 	}
 }
 
 static uint32_t create_dst_obj(int fd, struct test_cfg *cfg, uint32_t size, void **dst_addr)
 {
 	uint32_t dst;
-	struct igt_collection *set = get_region_set(fd, cfg);
 
-	dst = gem_create_in_memory_regions(fd, size, igt_collection_get_value(set, 0));
-	*dst_addr = gem_mmap__cpu(fd, dst, 0, size, PROT_WRITE);
+	if (is_userptr(cfg)) {
+		igt_assert(posix_memalign(dst_addr, SZ_2M, size) == 0);
+
+		gem_userptr(fd, *dst_addr, size, 0, 0, &dst);
+	} else {
+		struct igt_collection *set = get_region_set(fd, cfg);
+
+		dst = gem_create_in_memory_regions(fd, size, igt_collection_get_value(set, 0));
+		*dst_addr = gem_mmap__cpu(fd, dst, 0, size, PROT_WRITE);
+	}
 
 	return dst;
 }
@@ -305,6 +324,9 @@ static void destroy_dst_obj(int fd, struct test_cfg *cfg, uint32_t dst, uint32_t
 	igt_assert(gem_munmap(dst_addr, size) == 0);
 	igt_debug("Closing object 0x%x\n", dst);
 	gem_close(fd, dst);
+
+	if (is_userptr(cfg))
+		free(dst_addr);
 }
 
 static void pattern_fill_buf(void *src_addr[], uint32_t size, uint32_t num_cmds, uint32_t npages)
@@ -471,6 +493,25 @@ static void run_test(int fd, const intel_ctx_t *base_ctx, struct test_cfg *cfg,
 		gem_vm_destroy(fd, shared_vm_id);
 }
 
+static int has_userptr(int fd)
+{
+	uint32_t handle = 0;
+	void *ptr;
+	int ret;
+
+	assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
+	ret = __gem_userptr(fd, ptr, PAGE_SIZE, 0, 0, &handle);
+	if (ret != 0) {
+		free(ptr);
+		return 0;
+	}
+
+	gem_close(fd, handle);
+	free(ptr);
+
+	return handle != 0;
+}
+
 static int vm_bind_version(int fd)
 {
 	struct drm_i915_getparam gp;
@@ -499,6 +540,7 @@ igt_main
 		{"2M", SZ_2M, 1, 1, 0},
 		{"smem", 0, 1, 1, TEST_SMEM},
 		{"smem_multi_cmds", 0, MAX_CMDS, 1, TEST_SMEM},
+		{"userptr", 0, 1, 1, TEST_USERPTR},
 		{ }
 	};
 	int fd;
@@ -529,6 +571,9 @@ igt_main
 			for_each_ctx_engine(fd, ctx, e) {
 				if (e->class == I915_ENGINE_CLASS_COPY) {
 					igt_dynamic(e->name) {
+						if (is_userptr(t))
+							igt_require(has_userptr(fd));
+
 						run_test(fd, ctx, t, e);
 					}
 				}
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] ✗ GitLab.Pipeline: warning for vm_bind: Add VM_BIND validation support (rev2)
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (7 preceding siblings ...)
  2022-09-21  7:12 ` [igt-dev] [RFC v2 8/8] tests/i915/vm_bind: Add userptr subtest Niranjana Vishwanathapura
@ 2022-09-21  7:53 ` Patchwork
  2022-09-21  8:23 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
  2022-09-21  9:57 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
  10 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2022-09-21  7:53 UTC (permalink / raw)
  To: Niranjana Vishwanathapura; +Cc: igt-dev

== Series Details ==

Series: vm_bind: Add VM_BIND validation support (rev2)
URL   : https://patchwork.freedesktop.org/series/105881/
State : warning

== Summary ==

Pipeline status: FAILED.

see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/693932 for the overview.

build:tests-debian-meson-armhf has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/28702600):
  ../tests/i915/i915_vm_bind_basic.c:402:12: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
     src_va = (uint64_t)src_addr[0];
              ^
  ../tests/i915/i915_vm_bind_basic.c:403:12: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
     dst_va = (uint64_t)dst_addr;
              ^
  ../tests/i915/i915_vm_bind_basic.c:427:40: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
     SET_MAP(map[i][BATCH_MAP], batch[i], (uint64_t)batch_addr[i], 0, PAGE_SIZE, 0);
                                          ^
  ../tests/i915/i915_vm_bind_basic.c:70:13: note: in definition of macro ‘SET_MAP’
    (map).va = _va;            \
               ^~~
  cc1: some warnings being treated as errors
  ninja: build stopped: subcommand failed.
  section_end:1663746697:step_script
  section_start:1663746697:cleanup_file_variables
  Cleaning up project directory and file based variables
  section_end:1663746698:cleanup_file_variables
  ERROR: Job failed: exit code 1
  

build:tests-debian-meson-mips has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/28702602):
  ../tests/i915/i915_vm_bind_basic.c:402:12: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
     src_va = (uint64_t)src_addr[0];
              ^
  ../tests/i915/i915_vm_bind_basic.c:403:12: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
     dst_va = (uint64_t)dst_addr;
              ^
  ../tests/i915/i915_vm_bind_basic.c:427:40: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
     SET_MAP(map[i][BATCH_MAP], batch[i], (uint64_t)batch_addr[i], 0, PAGE_SIZE, 0);
                                          ^
  ../tests/i915/i915_vm_bind_basic.c:70:13: note: in definition of macro ‘SET_MAP’
    (map).va = _va;            \
               ^~~
  cc1: some warnings being treated as errors
  ninja: build stopped: subcommand failed.
  section_end:1663746705:step_script
  section_start:1663746705:cleanup_file_variables
  Cleaning up project directory and file based variables
  section_end:1663746706:cleanup_file_variables
  ERROR: Job failed: exit code 1

== Logs ==

For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/693932

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

* [igt-dev] ✓ Fi.CI.BAT: success for vm_bind: Add VM_BIND validation support (rev2)
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (8 preceding siblings ...)
  2022-09-21  7:53 ` [igt-dev] ✗ GitLab.Pipeline: warning for vm_bind: Add VM_BIND validation support (rev2) Patchwork
@ 2022-09-21  8:23 ` Patchwork
  2022-09-21  9:57 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
  10 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2022-09-21  8:23 UTC (permalink / raw)
  To: Niranjana Vishwanathapura; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 5376 bytes --]

== Series Details ==

Series: vm_bind: Add VM_BIND validation support (rev2)
URL   : https://patchwork.freedesktop.org/series/105881/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_12163 -> IGTPW_7809
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/index.html

Participating hosts (42 -> 41)
------------------------------

  Additional (1): fi-tgl-u2 
  Missing    (2): fi-rkl-11600 fi-bdw-samus 

Known issues
------------

  Here are the changes found in IGTPW_7809 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_huc_copy@huc-copy:
    - fi-tgl-u2:          NOTRUN -> [SKIP][1] ([i915#2190])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-tgl-u2/igt@gem_huc_copy@huc-copy.html

  * igt@i915_selftest@live@gt_heartbeat:
    - fi-bxt-dsi:         [PASS][2] -> [DMESG-FAIL][3] ([i915#5334])
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/fi-bxt-dsi/igt@i915_selftest@live@gt_heartbeat.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-bxt-dsi/igt@i915_selftest@live@gt_heartbeat.html

  * igt@kms_chamelium@hdmi-edid-read:
    - fi-tgl-u2:          NOTRUN -> [SKIP][4] ([fdo#109284] / [fdo#111827]) +7 similar issues
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-tgl-u2/igt@kms_chamelium@hdmi-edid-read.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor:
    - fi-tgl-u2:          NOTRUN -> [SKIP][5] ([i915#4103])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-tgl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions-varying-size:
    - fi-bsw-kefka:       [PASS][6] -> [FAIL][7] ([i915#6298])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions-varying-size.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions-varying-size.html

  * igt@kms_force_connector_basic@force-load-detect:
    - fi-tgl-u2:          NOTRUN -> [SKIP][8] ([fdo#109285])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-tgl-u2/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-tgl-u2:          NOTRUN -> [SKIP][9] ([i915#3555])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-tgl-u2/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@gt_heartbeat:
    - fi-hsw-4770:        [DMESG-FAIL][10] -> [PASS][11]
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/fi-hsw-4770/igt@i915_selftest@live@gt_heartbeat.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/fi-hsw-4770/igt@i915_selftest@live@gt_heartbeat.html

  * igt@i915_selftest@live@reset:
    - {bat-rpls-1}:       [DMESG-FAIL][12] ([i915#4983] / [i915#5828]) -> [PASS][13]
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/bat-rpls-1/igt@i915_selftest@live@reset.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/bat-rpls-1/igt@i915_selftest@live@reset.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4983]: https://gitlab.freedesktop.org/drm/intel/issues/4983
  [i915#5122]: https://gitlab.freedesktop.org/drm/intel/issues/5122
  [i915#5257]: https://gitlab.freedesktop.org/drm/intel/issues/5257
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#5828]: https://gitlab.freedesktop.org/drm/intel/issues/5828
  [i915#6298]: https://gitlab.freedesktop.org/drm/intel/issues/6298
  [i915#6434]: https://gitlab.freedesktop.org/drm/intel/issues/6434


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_6659 -> IGTPW_7809

  CI-20190529: 20190529
  CI_DRM_12163: 8a052348946d9ec1b368ddcc1d3db5f2fc486f75 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_7809: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/index.html
  IGT_6659: 1becf700a737a7a98555a0cfbe8566355377afb2 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git


Testlist changes
----------------

+igt@i915_vm_bind_basic@2m
+igt@i915_vm_bind_basic@64k
+igt@i915_vm_bind_basic@basic
+igt@i915_vm_bind_basic@multi_cmds
+igt@i915_vm_bind_basic@multi_ctxts
+igt@i915_vm_bind_basic@share_vm
+igt@i915_vm_bind_basic@skip_copy
+igt@i915_vm_bind_basic@skip_unbind
+igt@i915_vm_bind_basic@smem
+igt@i915_vm_bind_basic@smem_multi_cmds
+igt@i915_vm_bind_basic@userptr
+igt@i915_vm_bind_sanity@basic-smem

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/index.html

[-- Attachment #2: Type: text/html, Size: 5996 bytes --]

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

* Re: [igt-dev] [RFC v2 7/8] tests/i915/vm_bind: Add basic VM_BIND test support
  2022-09-21  7:12 ` [igt-dev] [RFC v2 7/8] tests/i915/vm_bind: Add basic VM_BIND test support Niranjana Vishwanathapura
@ 2022-09-21  8:55   ` Petri Latvala
  2022-09-21 18:21     ` Niranjana Vishwanathapura
  0 siblings, 1 reply; 14+ messages in thread
From: Petri Latvala @ 2022-09-21  8:55 UTC (permalink / raw)
  To: Niranjana Vishwanathapura
  Cc: igt-dev, daniel.vetter, thomas.hellstrom, matthew.auld, tvrtko.ursulin

On Wed, Sep 21, 2022 at 12:12:19AM -0700, Niranjana Vishwanathapura wrote:
> Add basic tests for VM_BIND functionality. Bind the buffer objects in
> device page table with VM_BIND calls and have GPU copy the data from a
> source buffer object to destination buffer object.
> Test for different buffer sizes, buffer object placement and with
> multiple contexts.
> 
> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
> ---
>  tests/i915/i915_vm_bind_basic.c | 544 ++++++++++++++++++++++++++++++++
>  tests/meson.build               |   1 +
>  2 files changed, 545 insertions(+)
>  create mode 100644 tests/i915/i915_vm_bind_basic.c
> 
> diff --git a/tests/i915/i915_vm_bind_basic.c b/tests/i915/i915_vm_bind_basic.c
> new file mode 100644
> index 0000000000..b3aa8eac9b
> --- /dev/null
> +++ b/tests/i915/i915_vm_bind_basic.c
> @@ -0,0 +1,544 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2022 Intel Corporation
> + */
> +
> +/** @file i915_vm_bind_basic.c
> + *
> + * This is the basic test for VM_BIND functionality.
> + *
> + * The goal is to ensure that basics work.
> + */
> +
> +#include <sys/poll.h>
> +
> +#include "i915/gem.h"
> +#include "igt.h"
> +#include "igt_syncobj.h"
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <fcntl.h>
> +#include <inttypes.h>
> +#include <errno.h>
> +#include <sys/stat.h>
> +#include <sys/ioctl.h>
> +#include "drm.h"
> +#include "i915/gem_vm.h"
> +
> +IGT_TEST_DESCRIPTION("Basic test for vm_bind functionality");
> +
> +#define PAGE_SIZE   4096
> +#define PAGE_SHIFT  12
> +
> +#define GEN9_XY_FAST_COPY_BLT_CMD       (2 << 29 | 0x42 << 22)
> +#define BLT_DEPTH_32                    (3 << 24)
> +
> +#define DEFAULT_BUFF_SIZE  (4 * PAGE_SIZE)
> +#define SZ_64K             (16 * PAGE_SIZE)
> +#define SZ_2M              (512 * PAGE_SIZE)
> +
> +#define MAX_CTXTS   2
> +#define MAX_CMDS    4
> +
> +#define BATCH_FENCE  0
> +#define SRC_FENCE    1
> +#define DST_FENCE    2
> +#define EXEC_FENCE   3
> +#define NUM_FENCES   4
> +
> +enum {
> +	BATCH_MAP,
> +	SRC_MAP,
> +	DST_MAP = SRC_MAP + MAX_CMDS,
> +	MAX_MAP
> +};
> +
> +struct mapping {
> +	uint32_t  obj;
> +	uint64_t  va;
> +	uint64_t  offset;
> +	uint64_t  length;
> +	uint64_t  flags;
> +};
> +
> +#define SET_MAP(map, _obj, _va, _offset, _length, _flags)   \
> +{                                  \
> +	(map).obj = _obj;          \
> +	(map).va = _va;            \
> +	(map).offset = _offset;	   \
> +	(map).length = _length;	   \
> +	(map).flags = _flags;	   \
> +}
> +
> +#define MAX_BATCH_DWORD    64
> +
> +#define abs(x) ((x) >= 0 ? (x) : -(x))
> +
> +#define TEST_SMEM             BIT(0)
> +#define TEST_SKIP_UNBIND      BIT(1)
> +#define TEST_SHARE_VM         BIT(2)
> +
> +#define is_lmem(cfg)        (!((cfg)->flags & TEST_SMEM))
> +#define do_unbind(cfg)      (!((cfg)->flags & TEST_SKIP_UNBIND))
> +#define do_share_vm(cfg)    ((cfg)->flags & TEST_SHARE_VM)
> +
> +struct test_cfg {
> +	const char *name;
> +	uint32_t size;
> +	uint8_t num_cmds;
> +	uint32_t num_ctxts;
> +	uint32_t flags;
> +};
> +
> +static uint64_t
> +gettime_ns(void)
> +{
> +	struct timespec current;
> +	clock_gettime(CLOCK_MONOTONIC, &current);
> +	return (uint64_t)current.tv_sec * NSEC_PER_SEC + current.tv_nsec;
> +}
> +
> +static bool syncobj_busy(int fd, uint32_t handle)
> +{
> +	bool result;
> +	int sf;
> +
> +	sf = syncobj_handle_to_fd(fd, handle,
> +				  DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE);
> +	result = poll(&(struct pollfd){sf, POLLIN}, 1, 0) == 0;
> +	close(sf);
> +
> +	return result;
> +}
> +
> +static inline void i915_vm_bind(int fd, uint32_t vm_id, struct mapping *m,
> +				struct drm_i915_gem_timeline_fence *fence)
> +{
> +	struct drm_i915_gem_vm_bind bind;
> +
> +	memset(&bind, 0, sizeof(bind));
> +	bind.vm_id = vm_id;
> +	bind.handle = m->obj;
> +	bind.start = m->va;
> +	bind.offset = m->offset;
> +	bind.length = m->length;
> +	bind.flags = m->flags;
> +	if (fence) {
> +		bind.fence.flags |= I915_TIMELINE_FENCE_SIGNAL;
> +		bind.fence.handle = syncobj_create(fd, 0);
> +		bind.fence.value = 0;
> +
> +		fence->handle = bind.fence.handle;
> +		fence->flags = I915_TIMELINE_FENCE_WAIT;
> +		fence->value = bind.fence.value;
> +	}
> +
> +	igt_info("VM_BIND vm:0x%x h:0x%x v:0x%lx o:0x%lx l:0x%lx f:0x%llx\n",
> +		 vm_id, m->obj, m->va, m->offset, m->length, bind.flags);
> +	gem_vm_bind(fd, &bind);
> +}
> +
> +static inline void i915_vm_unbind(int fd, uint32_t vm_id, struct mapping *m)
> +{
> +	struct drm_i915_gem_vm_unbind unbind;
> +
> +	/* Object handle is not required during unbind */
> +	igt_info("VM_UNBIND vm:0x%x v:0x%lx l:0x%lx f:0x%lx\n",
> +		 vm_id, m->va, m->length, m->flags);
> +	memset(&unbind, 0, sizeof(unbind));
> +	unbind.vm_id = vm_id;
> +	unbind.start = m->va;
> +	unbind.length = m->length;
> +	unbind.flags = m->flags;
> +
> +	gem_vm_unbind(fd, &unbind);
> +}
> +
> +static void print_buffer(void *buf, uint32_t size,
> +			 const char *str, bool full)
> +{
> +	uint32_t i = 0;
> +
> +	igt_debug("Printing %s 0x%lx size 0x%x\n", str, (uint64_t)buf, size);
> +	while (i < size) {
> +		uint32_t *b = buf + i;
> +
> +		igt_debug("\t%s[0x%04x]: 0x%08x 0x%08x 0x%08x 0x%08x %s\n",
> +			  str, i, b[0], b[1], b[2], b[3], full ? "" : "...");
> +		i += full ? 16 : PAGE_SIZE;
> +	}
> +}
> +
> +static int gem_linear_fast_blt(uint32_t *batch, uint64_t src,
> +			       uint64_t dst, uint32_t size)
> +{
> +	uint32_t *cmd = batch;
> +	uint64_t src_offset = (uint64_t)src;
> +	uint64_t dst_offset = (uint64_t)dst;
> +
> +	*cmd++ = GEN9_XY_FAST_COPY_BLT_CMD | (10 - 2);
> +	*cmd++ = BLT_DEPTH_32 | PAGE_SIZE;
> +	*cmd++ = 0;
> +	*cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
> +	*cmd++ = lower_32_bits(dst_offset);
> +	*cmd++ = upper_32_bits(dst_offset);
> +	*cmd++ = 0;
> +	*cmd++ = PAGE_SIZE;
> +	*cmd++ = lower_32_bits(src_offset);
> +	*cmd++ = upper_32_bits(src_offset);
> +
> +	*cmd++ = MI_BATCH_BUFFER_END;
> +	*cmd++ = 0;
> +
> +	return ALIGN((cmd - batch + 1) * sizeof(uint32_t), 8);
> +}
> +
> +static void __gem_copy(int fd, uint64_t src, uint64_t dst, uint32_t offset, uint32_t size,
> +		       uint32_t ctx_id, void *batch_addr, unsigned int eb_flags,
> +		       struct drm_i915_gem_timeline_fence *fence)
> +{
> +	uint32_t len, buf[MAX_BATCH_DWORD] = { 0 };
> +	struct drm_i915_gem_execbuffer3 execbuf;
> +
> +	len = gem_linear_fast_blt(buf, src + offset, dst + offset, size);
> +
> +	memcpy(batch_addr, (void *)buf, len);
> +	print_buffer(buf, len, "batch", true);
> +
> +	memset(&execbuf, 0, sizeof(execbuf));
> +	execbuf.ctx_id = ctx_id;
> +	execbuf.batch_address = (uint64_t)&batch_addr;

Use to_user_pointer() to convert addresses to uint64_t.

-- 
Petri Latvala


> +	execbuf.engine_idx = eb_flags;
> +	execbuf.fence_count = NUM_FENCES;
> +	execbuf.timeline_fences = to_user_pointer(fence);
> +	gem_execbuf3(fd, &execbuf);
> +}
> +
> +static void i915_gem_copy(int fd, uint64_t src, uint64_t dst, uint32_t size,
> +			  const intel_ctx_t **ctx, uint32_t num_ctxts,
> +			  void **batch_addr, unsigned int eb_flags,
> +			  struct drm_i915_gem_timeline_fence (*fence)[NUM_FENCES])
> +{
> +	uint32_t i, delta = size / num_ctxts;
> +
> +	for (i = 0; i < num_ctxts; i++) {
> +		igt_info("Issuing gem copy on ctx 0x%x\n", ctx[i]->id);
> +		__gem_copy(fd, src, dst, (i * delta), delta,
> +			   ctx[i]->id, batch_addr[i], eb_flags, fence[i]);
> +	}
> +}
> +
> +static void i915_gem_sync(int fd, const intel_ctx_t **ctx, uint32_t num_ctxts,
> +			  struct drm_i915_gem_timeline_fence (*fence)[NUM_FENCES])
> +{
> +	uint32_t i;
> +
> +	for (i = 0; i < num_ctxts; i++) {
> +		uint64_t fence_value = 0;
> +
> +		igt_assert(syncobj_timeline_wait(fd, &fence[i][EXEC_FENCE].handle,
> +						 (uint64_t *)&fence_value, 1,
> +						 gettime_ns() + (2 * NSEC_PER_SEC),
> +						 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
> +		igt_assert(!syncobj_busy(fd, fence[i][EXEC_FENCE].handle));
> +		igt_info("gem copy completed on ctx 0x%x\n", ctx[i]->id);
> +	}
> +}
> +
> +static struct igt_collection *get_region_set(int fd, struct test_cfg *cfg)
> +{
> +	uint32_t mem_type[] = { I915_SYSTEM_MEMORY, I915_DEVICE_MEMORY };
> +	uint32_t lmem_type[] = { I915_DEVICE_MEMORY };
> +	struct drm_i915_query_memory_regions *query_info;
> +
> +	query_info = gem_get_query_memory_regions(fd);
> +	igt_assert(query_info);
> +
> +	if (is_lmem(cfg))
> +		return __get_memory_region_set(query_info, lmem_type, 1);
> +	else
> +		return __get_memory_region_set(query_info, mem_type, 2);
> +}
> +
> +static void create_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint32_t size,
> +			    uint32_t num_cmds, void *src_addr[])
> +{
> +	int i;
> +	struct igt_collection *set = get_region_set(fd, cfg);
> +	uint32_t region;
> +
> +	for (i = 0; i < num_cmds; i++) {
> +		region = igt_collection_get_value(set, i % set->size);
> +		src[i] = gem_create_in_memory_regions(fd, size, region);
> +		src_addr[i] = gem_mmap__cpu(fd, src[i], 0, size, PROT_WRITE);
> +	}
> +}
> +
> +static void destroy_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint32_t size,
> +			     uint32_t num_cmds, void *src_addr[])
> +{
> +	int i;
> +
> +	for (i = 0; i < num_cmds; i++) {
> +		igt_assert(gem_munmap(src_addr[i], size) == 0);
> +		igt_debug("Closing object 0x%x\n", src[i]);
> +		gem_close(fd, src[i]);
> +	}
> +}
> +
> +static uint32_t create_dst_obj(int fd, struct test_cfg *cfg, uint32_t size, void **dst_addr)
> +{
> +	uint32_t dst;
> +	struct igt_collection *set = get_region_set(fd, cfg);
> +
> +	dst = gem_create_in_memory_regions(fd, size, igt_collection_get_value(set, 0));
> +	*dst_addr = gem_mmap__cpu(fd, dst, 0, size, PROT_WRITE);
> +
> +	return dst;
> +}
> +
> +static void destroy_dst_obj(int fd, struct test_cfg *cfg, uint32_t dst, uint32_t size, void *dst_addr)
> +{
> +	igt_assert(gem_munmap(dst_addr, size) == 0);
> +	igt_debug("Closing object 0x%x\n", dst);
> +	gem_close(fd, dst);
> +}
> +
> +static void pattern_fill_buf(void *src_addr[], uint32_t size, uint32_t num_cmds, uint32_t npages)
> +{
> +	uint32_t i, j;
> +	void *buf;
> +
> +	/* Allocate buffer and fill pattern */
> +	buf = malloc(size);
> +	igt_require(buf);
> +
> +	for (i = 0; i < num_cmds; i++) {
> +		for (j = 0; j < npages; j++)
> +			memset(buf + j * PAGE_SIZE, i * npages + j + 1, PAGE_SIZE);
> +
> +		memcpy(src_addr[i], buf, size);
> +	}
> +
> +	free(buf);
> +}
> +
> +static void run_test(int fd, const intel_ctx_t *base_ctx, struct test_cfg *cfg,
> +		     const struct intel_execution_engine2 *e)
> +{
> +	void *src_addr[MAX_CMDS] = { 0 }, *dst_addr = NULL;
> +	uint32_t src[MAX_CMDS], dst, i, size = cfg->size;
> +	struct drm_i915_gem_timeline_fence exec_fence[MAX_CTXTS][NUM_FENCES];
> +	uint32_t shared_vm_id, vm_id[MAX_CTXTS];
> +	struct mapping map[MAX_CTXTS][MAX_MAP];
> +	uint32_t num_ctxts = cfg->num_ctxts;
> +	uint32_t num_cmds = cfg->num_cmds;
> +	uint32_t npages = size / PAGE_SIZE;
> +	const intel_ctx_t *ctx[MAX_CTXTS];
> +	bool share_vm = do_share_vm(cfg);
> +	void *batch_addr[MAX_CTXTS];
> +	uint32_t batch[MAX_CTXTS];
> +	uint64_t src_va, dst_va;
> +	uint32_t delta;
> +
> +	delta = size / num_ctxts;
> +	if (share_vm)
> +		shared_vm_id = gem_vm_create_in_vm_bind_mode(fd);
> +
> +	/* Create contexts */
> +	num_ctxts = min_t(num_ctxts, MAX_CTXTS, num_ctxts);
> +	for (i = 0; i < num_ctxts; i++) {
> +		uint32_t vmid;
> +
> +		if (share_vm)
> +			vmid = shared_vm_id;
> +		else
> +			vmid = gem_vm_create_in_vm_bind_mode(fd);
> +
> +		ctx[i] = intel_ctx_create(fd, &base_ctx->cfg);
> +		gem_context_set_vm(fd, ctx[i]->id, vmid);
> +		vm_id[i] = gem_context_get_vm(fd, ctx[i]->id);
> +
> +		exec_fence[i][EXEC_FENCE].handle = syncobj_create(fd, 0);
> +		exec_fence[i][EXEC_FENCE].flags = I915_TIMELINE_FENCE_SIGNAL;
> +		exec_fence[i][EXEC_FENCE].value = 0;
> +	}
> +
> +	/* Create objects */
> +	num_cmds = min_t(num_cmds, MAX_CMDS, num_cmds);
> +	create_src_objs(fd, cfg, src, size, num_cmds, src_addr);
> +	dst = create_dst_obj(fd, cfg, size, &dst_addr);
> +
> +	/*
> +	 * mmap'ed addresses are not 64K aligned. On platforms requiring
> +	 * 64K alignment, use static addresses.
> +	 */
> +	if (size < SZ_2M && num_cmds && !HAS_64K_PAGES(intel_get_drm_devid(fd))) {
> +		src_va = (uint64_t)src_addr[0];
> +		dst_va = (uint64_t)dst_addr;
> +	} else {
> +		src_va = 0xa000000;
> +		dst_va = 0xb000000;
> +	}
> +
> +	pattern_fill_buf(src_addr, size, num_cmds, npages);
> +
> +	if (num_cmds)
> +		print_buffer(src_addr[num_cmds - 1], size, "src_obj", false);
> +
> +	for (i = 0; i < num_ctxts; i++) {
> +		batch[i] = gem_create_vm_private_in_memory_regions(fd, PAGE_SIZE, vm_id[i], REGION_SMEM);
> +		batch_addr[i] = gem_mmap__cpu(fd, batch[i], 0, PAGE_SIZE, PROT_WRITE);
> +	}
> +
> +	/* Create mappings */
> +	for (i = 0; i < num_ctxts; i++) {
> +		uint64_t offset = i * delta;
> +		uint32_t j;
> +
> +		for (j = 0; j < num_cmds; j++)
> +			SET_MAP(map[i][SRC_MAP + j], src[j], src_va + offset, offset, delta, 0);
> +		SET_MAP(map[i][DST_MAP], dst, dst_va + offset, offset, delta, 0);
> +		SET_MAP(map[i][BATCH_MAP], batch[i], (uint64_t)batch_addr[i], 0, PAGE_SIZE, 0);
> +	}
> +
> +	/* Bind the buffers to device page table */
> +	for (i = 0; i < num_ctxts; i++) {
> +		i915_vm_bind(fd, vm_id[i], &map[i][BATCH_MAP], &exec_fence[i][BATCH_FENCE]);
> +		i915_vm_bind(fd, vm_id[i], &map[i][DST_MAP], &exec_fence[i][DST_FENCE]);
> +	}
> +
> +	/* Have GPU do the copy */
> +	for (i = 0; i < cfg->num_cmds; i++) {
> +		uint32_t j;
> +
> +		for (j = 0; j < num_ctxts; j++)
> +			i915_vm_bind(fd, vm_id[j], &map[j][SRC_MAP + i], &exec_fence[j][SRC_FENCE]);
> +
> +		i915_gem_copy(fd, src_va, dst_va, size, ctx, num_ctxts,
> +			      batch_addr, e->flags, exec_fence);
> +
> +		i915_gem_sync(fd, ctx, num_ctxts, exec_fence);
> +
> +		for (j = 0; j < num_ctxts; j++) {
> +			syncobj_destroy(fd, exec_fence[j][SRC_FENCE].handle);
> +			if (do_unbind(cfg))
> +				i915_vm_unbind(fd, vm_id[j], &map[j][SRC_MAP + i]);
> +		}
> +	}
> +
> +	/*
> +	 * Unbind buffers from device page table.
> +	 * If not, it should get unbound while freeing the buffer.
> +	 */
> +	for (i = 0; i < num_ctxts; i++) {
> +		syncobj_destroy(fd, exec_fence[i][BATCH_FENCE].handle);
> +		syncobj_destroy(fd, exec_fence[i][DST_FENCE].handle);
> +		if (do_unbind(cfg)) {
> +			i915_vm_unbind(fd, vm_id[i], &map[i][BATCH_MAP]);
> +			i915_vm_unbind(fd, vm_id[i], &map[i][DST_MAP]);
> +		}
> +	}
> +
> +	/* Close batch buffers */
> +	for (i = 0; i < num_ctxts; i++) {
> +		syncobj_destroy(fd, exec_fence[i][EXEC_FENCE].handle);
> +		gem_close(fd, batch[i]);
> +	}
> +
> +	/* Accessing the buffer will migrate the pages from device to host */
> +	print_buffer(dst_addr, size, "dst_obj", false);
> +
> +	/* Validate by comparing the last SRC with DST */
> +	if (num_cmds)
> +		igt_assert(memcmp(src_addr[num_cmds - 1], dst_addr, size) == 0);
> +
> +	/* Free the objects */
> +	destroy_src_objs(fd, cfg, src, size, num_cmds, src_addr);
> +	destroy_dst_obj(fd, cfg, dst, size, dst_addr);
> +
> +	/* Done with the contexts */
> +	for (i = 0; i < num_ctxts; i++) {
> +		igt_debug("Destroying context 0x%x\n", ctx[i]->id);
> +		gem_vm_destroy(fd, vm_id[i]);
> +		intel_ctx_destroy(fd, ctx[i]);
> +	}
> +
> +	if (share_vm)
> +		gem_vm_destroy(fd, shared_vm_id);
> +}
> +
> +static int vm_bind_version(int fd)
> +{
> +	struct drm_i915_getparam gp;
> +	int value = 0;
> +
> +	memset(&gp, 0, sizeof(gp));
> +	gp.param = I915_PARAM_VM_BIND_VERSION;
> +	gp.value = &value;
> +
> +	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
> +	errno = 0;
> +
> +	return value;
> +}
> +
> +igt_main
> +{
> +	struct test_cfg *t, tests[] = {
> +		{"basic", 0, 1, 1, 0},
> +		{"multi_cmds", 0, MAX_CMDS, 1, 0},
> +		{"skip_copy", 0, 0, 1, 0},
> +		{"skip_unbind",  0, 1, 1, TEST_SKIP_UNBIND},
> +		{"multi_ctxts", 0, 1, MAX_CTXTS, 0},
> +		{"share_vm", 0, 1, MAX_CTXTS, TEST_SHARE_VM},
> +		{"64K", (16 * PAGE_SIZE), 1, 1, 0},
> +		{"2M", SZ_2M, 1, 1, 0},
> +		{"smem", 0, 1, 1, TEST_SMEM},
> +		{"smem_multi_cmds", 0, MAX_CMDS, 1, TEST_SMEM},
> +		{ }
> +	};
> +	int fd;
> +	bool has_lmem;
> +	uint32_t def_size;
> +	struct intel_execution_engine2 *e;
> +	const intel_ctx_t *ctx;
> +
> +	igt_fixture {
> +		fd = drm_open_driver(DRIVER_INTEL);
> +		igt_require_gem(fd);
> +		igt_require(vm_bind_version(fd) == 1);
> +		has_lmem = gem_has_lmem(fd);
> +		def_size = HAS_64K_PAGES(intel_get_drm_devid(fd)) ?
> +			   SZ_64K : DEFAULT_BUFF_SIZE;
> +		ctx = intel_ctx_create_all_physical(fd);
> +	}
> +
> +	/* Adjust test variables */
> +	for (t = tests; t->name; t++) {
> +		t->flags |= (has_lmem ? 0 : TEST_SMEM);
> +		t->size = t->size ? : (def_size * abs(t->num_ctxts));
> +	}
> +
> +	for (t = tests; t->name; t++) {
> +		igt_describe_f("vm_bind %s test", t->name);
> +		igt_subtest_with_dynamic_f("%s", t->name)
> +			for_each_ctx_engine(fd, ctx, e) {
> +				if (e->class == I915_ENGINE_CLASS_COPY) {
> +					igt_dynamic(e->name) {
> +						run_test(fd, ctx, t, e);
> +					}
> +				}
> +			}
> +	}
> +
> +	igt_fixture {
> +		intel_ctx_destroy(fd, ctx);
> +		close(fd);
> +	}
> +
> +	igt_exit();
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index 3ee2230543..b4348130d6 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -250,6 +250,7 @@ i915_progs = [
>  	'sysfs_preempt_timeout',
>  	'sysfs_timeslice_duration',
>  	'i915_vm_bind_sanity',
> +	'i915_vm_bind_basic',
>  ]
>  
>  msm_progs = [
> -- 
> 2.21.0.rc0.32.g243a4c7e27
> 

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

* [igt-dev] ✗ Fi.CI.IGT: failure for vm_bind: Add VM_BIND validation support (rev2)
  2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (9 preceding siblings ...)
  2022-09-21  8:23 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
@ 2022-09-21  9:57 ` Patchwork
  10 siblings, 0 replies; 14+ messages in thread
From: Patchwork @ 2022-09-21  9:57 UTC (permalink / raw)
  To: Niranjana Vishwanathapura; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 37707 bytes --]

== Series Details ==

Series: vm_bind: Add VM_BIND validation support (rev2)
URL   : https://patchwork.freedesktop.org/series/105881/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_12163_full -> IGTPW_7809_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_7809_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_7809_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/index.html

Participating hosts (9 -> 6)
------------------------------

  Missing    (3): pig-skl-6260u pig-kbl-iris pig-glk-j5005 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_7809_full:

### IGT changes ###

#### Possible regressions ####

  * {igt@i915_vm_bind_basic@share_vm} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][1] +11 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb7/igt@i915_vm_bind_basic@share_vm.html

  * {igt@i915_vm_bind_basic@skip_copy} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][2] +10 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@i915_vm_bind_basic@skip_copy.html

  * igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1:
    - shard-tglb:         [PASS][3] -> [INCOMPLETE][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-tglb5/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1.html

  
New tests
---------

  New tests have been introduced between CI_DRM_12163_full and IGTPW_7809_full:

### New IGT tests (12) ###

  * igt@i915_vm_bind_basic@2m:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@64k:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@basic:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@multi_cmds:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@multi_ctxts:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@share_vm:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@skip_copy:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@skip_unbind:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@smem:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@smem_multi_cmds:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_basic@userptr:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_sanity@basic-smem:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  

Known issues
------------

  Here are the changes found in IGTPW_7809_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_busy@close-race:
    - shard-iclb:         [PASS][5] -> [TIMEOUT][6] ([i915#6016])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb7/igt@gem_busy@close-race.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb3/igt@gem_busy@close-race.html

  * igt@gem_ccs@block-copy-compressed:
    - shard-tglb:         NOTRUN -> [SKIP][7] ([i915#3555] / [i915#5325])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@gem_ccs@block-copy-compressed.html

  * igt@gem_ctx_persistence@many-contexts:
    - shard-tglb:         NOTRUN -> [FAIL][8] ([i915#2410])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb7/igt@gem_ctx_persistence@many-contexts.html

  * igt@gem_exec_balancer@parallel-keep-in-fence:
    - shard-iclb:         [PASS][9] -> [SKIP][10] ([i915#4525]) +2 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb2/igt@gem_exec_balancer@parallel-keep-in-fence.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb5/igt@gem_exec_balancer@parallel-keep-in-fence.html

  * igt@gem_exec_fair@basic-none-share@rcs0:
    - shard-iclb:         [PASS][11] -> [FAIL][12] ([i915#2842])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb6/igt@gem_exec_fair@basic-none-share@rcs0.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@gem_exec_fair@basic-none-share@rcs0.html

  * igt@gem_exec_fair@basic-none-solo@rcs0:
    - shard-apl:          [PASS][13] -> [FAIL][14] ([i915#2842])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-apl7/igt@gem_exec_fair@basic-none-solo@rcs0.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl3/igt@gem_exec_fair@basic-none-solo@rcs0.html

  * igt@gem_exec_fair@basic-none@rcs0:
    - shard-glk:          NOTRUN -> [FAIL][15] ([i915#2842])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk7/igt@gem_exec_fair@basic-none@rcs0.html

  * igt@gem_exec_fair@basic-pace@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][16] ([i915#2842])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@gem_exec_fair@basic-pace@vcs1.html

  * igt@gem_exec_params@no-bsd:
    - shard-tglb:         NOTRUN -> [SKIP][17] ([fdo#109283])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@gem_exec_params@no-bsd.html

  * igt@gem_exec_params@no-vebox:
    - shard-tglb:         NOTRUN -> [SKIP][18] ([fdo#109283] / [i915#4877])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@gem_exec_params@no-vebox.html
    - shard-iclb:         NOTRUN -> [SKIP][19] ([fdo#109283])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@gem_exec_params@no-vebox.html

  * igt@gem_lmem_swapping@basic:
    - shard-tglb:         NOTRUN -> [SKIP][20] ([i915#4613]) +1 similar issue
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@gem_lmem_swapping@basic.html

  * igt@gem_lmem_swapping@heavy-verify-random:
    - shard-apl:          NOTRUN -> [SKIP][21] ([fdo#109271] / [i915#4613]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl1/igt@gem_lmem_swapping@heavy-verify-random.html

  * igt@gem_lmem_swapping@massive-random:
    - shard-glk:          NOTRUN -> [SKIP][22] ([fdo#109271] / [i915#4613]) +2 similar issues
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk3/igt@gem_lmem_swapping@massive-random.html

  * igt@gem_lmem_swapping@parallel-random-engines:
    - shard-iclb:         NOTRUN -> [SKIP][23] ([i915#4613])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb5/igt@gem_lmem_swapping@parallel-random-engines.html

  * igt@gem_mmap_gtt@coherency:
    - shard-tglb:         NOTRUN -> [SKIP][24] ([fdo#111656])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@gem_mmap_gtt@coherency.html

  * igt@gem_pxp@create-regular-context-1:
    - shard-iclb:         NOTRUN -> [SKIP][25] ([i915#4270]) +1 similar issue
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb1/igt@gem_pxp@create-regular-context-1.html

  * igt@gem_pxp@reject-modify-context-protection-on:
    - shard-tglb:         NOTRUN -> [SKIP][26] ([i915#4270]) +1 similar issue
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb1/igt@gem_pxp@reject-modify-context-protection-on.html

  * igt@gem_userptr_blits@dmabuf-sync:
    - shard-apl:          NOTRUN -> [SKIP][27] ([fdo#109271] / [i915#3323])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl3/igt@gem_userptr_blits@dmabuf-sync.html
    - shard-tglb:         NOTRUN -> [SKIP][28] ([i915#3323])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb6/igt@gem_userptr_blits@dmabuf-sync.html
    - shard-glk:          NOTRUN -> [SKIP][29] ([fdo#109271] / [i915#3323])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk2/igt@gem_userptr_blits@dmabuf-sync.html
    - shard-iclb:         NOTRUN -> [SKIP][30] ([i915#3323])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@gem_userptr_blits@dmabuf-sync.html

  * igt@gem_userptr_blits@invalid-mmap-offset-unsync:
    - shard-tglb:         NOTRUN -> [SKIP][31] ([i915#3297])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@gem_userptr_blits@invalid-mmap-offset-unsync.html
    - shard-iclb:         NOTRUN -> [SKIP][32] ([i915#3297])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@gem_userptr_blits@invalid-mmap-offset-unsync.html

  * igt@gen9_exec_parse@allowed-single:
    - shard-glk:          [PASS][33] -> [DMESG-WARN][34] ([i915#5566] / [i915#716])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk2/igt@gen9_exec_parse@allowed-single.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk5/igt@gen9_exec_parse@allowed-single.html

  * igt@gen9_exec_parse@bb-oversize:
    - shard-iclb:         NOTRUN -> [SKIP][35] ([i915#2856])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@gen9_exec_parse@bb-oversize.html

  * igt@gen9_exec_parse@bb-secure:
    - shard-tglb:         NOTRUN -> [SKIP][36] ([i915#2527] / [i915#2856]) +1 similar issue
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@gen9_exec_parse@bb-secure.html

  * igt@i915_module_load@load:
    - shard-snb:          NOTRUN -> [SKIP][37] ([fdo#109271]) +78 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-snb4/igt@i915_module_load@load.html
    - shard-tglb:         NOTRUN -> [SKIP][38] ([i915#6227])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb5/igt@i915_module_load@load.html
    - shard-iclb:         NOTRUN -> [SKIP][39] ([i915#6227])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@i915_module_load@load.html

  * igt@i915_selftest@live@gt_pm:
    - shard-tglb:         NOTRUN -> [DMESG-FAIL][40] ([i915#1759])
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb7/igt@i915_selftest@live@gt_pm.html

  * igt@kms_big_fb@4-tiled-32bpp-rotate-180:
    - shard-iclb:         NOTRUN -> [SKIP][41] ([i915#5286]) +1 similar issue
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb1/igt@kms_big_fb@4-tiled-32bpp-rotate-180.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-async-flip:
    - shard-tglb:         NOTRUN -> [SKIP][42] ([i915#5286]) +2 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb5/igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html

  * igt@kms_big_fb@yf-tiled-16bpp-rotate-0:
    - shard-tglb:         NOTRUN -> [SKIP][43] ([fdo#111615]) +1 similar issue
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@kms_big_fb@yf-tiled-16bpp-rotate-0.html

  * igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_mc_ccs:
    - shard-glk:          NOTRUN -> [SKIP][44] ([fdo#109271] / [i915#3886]) +3 similar issues
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk1/igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-a-random-ccs-data-y_tiled_gen12_mc_ccs:
    - shard-iclb:         NOTRUN -> [SKIP][45] ([fdo#109278] / [i915#3886])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb8/igt@kms_ccs@pipe-a-random-ccs-data-y_tiled_gen12_mc_ccs.html
    - shard-tglb:         NOTRUN -> [SKIP][46] ([i915#3689] / [i915#3886])
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb1/igt@kms_ccs@pipe-a-random-ccs-data-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc:
    - shard-apl:          NOTRUN -> [SKIP][47] ([fdo#109271] / [i915#3886]) +7 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl3/igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-crc-primary-rotation-180-4_tiled_dg2_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][48] ([i915#3689] / [i915#6095]) +3 similar issues
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@kms_ccs@pipe-b-crc-primary-rotation-180-4_tiled_dg2_mc_ccs.html

  * igt@kms_ccs@pipe-b-random-ccs-data-yf_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][49] ([fdo#111615] / [i915#3689]) +2 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb6/igt@kms_ccs@pipe-b-random-ccs-data-yf_tiled_ccs.html

  * igt@kms_ccs@pipe-c-crc-primary-rotation-180-4_tiled_dg2_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][50] ([i915#6095]) +1 similar issue
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb6/igt@kms_ccs@pipe-c-crc-primary-rotation-180-4_tiled_dg2_mc_ccs.html

  * igt@kms_ccs@pipe-c-random-ccs-data-4_tiled_dg2_rc_ccs:
    - shard-iclb:         NOTRUN -> [SKIP][51] ([fdo#109278]) +8 similar issues
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@kms_ccs@pipe-c-random-ccs-data-4_tiled_dg2_rc_ccs.html

  * igt@kms_ccs@pipe-d-ccs-on-another-bo-y_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][52] ([i915#3689]) +1 similar issue
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb2/igt@kms_ccs@pipe-d-ccs-on-another-bo-y_tiled_ccs.html

  * igt@kms_chamelium@common-hpd-after-suspend:
    - shard-tglb:         NOTRUN -> [SKIP][53] ([fdo#109284] / [fdo#111827]) +5 similar issues
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb1/igt@kms_chamelium@common-hpd-after-suspend.html

  * igt@kms_chamelium@vga-hpd-without-ddc:
    - shard-snb:          NOTRUN -> [SKIP][54] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-snb7/igt@kms_chamelium@vga-hpd-without-ddc.html
    - shard-apl:          NOTRUN -> [SKIP][55] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl2/igt@kms_chamelium@vga-hpd-without-ddc.html
    - shard-glk:          NOTRUN -> [SKIP][56] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk2/igt@kms_chamelium@vga-hpd-without-ddc.html
    - shard-iclb:         NOTRUN -> [SKIP][57] ([fdo#109284] / [fdo#111827]) +1 similar issue
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@kms_chamelium@vga-hpd-without-ddc.html

  * igt@kms_color@deep-color:
    - shard-iclb:         NOTRUN -> [SKIP][58] ([i915#3555]) +1 similar issue
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@kms_color@deep-color.html

  * igt@kms_content_protection@lic:
    - shard-iclb:         NOTRUN -> [SKIP][59] ([fdo#109300] / [fdo#111066])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb5/igt@kms_content_protection@lic.html
    - shard-apl:          NOTRUN -> [TIMEOUT][60] ([i915#1319])
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl3/igt@kms_content_protection@lic.html
    - shard-tglb:         NOTRUN -> [SKIP][61] ([i915#1063])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb5/igt@kms_content_protection@lic.html

  * igt@kms_cursor_crc@cursor-offscreen-512x170:
    - shard-tglb:         NOTRUN -> [SKIP][62] ([fdo#109279] / [i915#3359])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@kms_cursor_crc@cursor-offscreen-512x170.html

  * igt@kms_cursor_legacy@2x-flip-vs-cursor-legacy:
    - shard-tglb:         NOTRUN -> [SKIP][63] ([fdo#109274] / [fdo#111825])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb6/igt@kms_cursor_legacy@2x-flip-vs-cursor-legacy.html

  * igt@kms_cursor_legacy@flip-vs-cursor@toggle:
    - shard-iclb:         NOTRUN -> [FAIL][64] ([i915#2346]) +2 similar issues
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb7/igt@kms_cursor_legacy@flip-vs-cursor@toggle.html

  * igt@kms_cursor_legacy@short-busy-flip-before-cursor:
    - shard-tglb:         NOTRUN -> [SKIP][65] ([i915#4103])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb6/igt@kms_cursor_legacy@short-busy-flip-before-cursor.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-apl:          [PASS][66] -> [FAIL][67] ([i915#4767])
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-apl1/igt@kms_fbcon_fbt@fbc-suspend.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl1/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_flip@2x-flip-vs-expired-vblank:
    - shard-iclb:         NOTRUN -> [SKIP][68] ([fdo#109274])
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb7/igt@kms_flip@2x-flip-vs-expired-vblank.html
    - shard-tglb:         NOTRUN -> [SKIP][69] ([fdo#109274] / [fdo#111825] / [i915#3637]) +1 similar issue
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb6/igt@kms_flip@2x-flip-vs-expired-vblank.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@b-hdmi-a2:
    - shard-glk:          [PASS][70] -> [FAIL][71] ([i915#79]) +1 similar issue
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk1/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-hdmi-a2.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk6/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-hdmi-a2.html

  * igt@kms_flip@wf_vblank-ts-check-interruptible@a-edp1:
    - shard-iclb:         [PASS][72] -> [DMESG-WARN][73] ([i915#402])
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb1/igt@kms_flip@wf_vblank-ts-check-interruptible@a-edp1.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@kms_flip@wf_vblank-ts-check-interruptible@a-edp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-upscaling@pipe-a-valid-mode:
    - shard-iclb:         NOTRUN -> [SKIP][74] ([i915#2587] / [i915#2672]) +3 similar issues
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-upscaling@pipe-a-valid-mode.html
    - shard-tglb:         NOTRUN -> [SKIP][75] ([i915#2587] / [i915#2672])
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-upscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling@pipe-a-default-mode:
    - shard-iclb:         NOTRUN -> [SKIP][76] ([i915#2672]) +6 similar issues
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling@pipe-a-default-mode.html

  * igt@kms_frontbuffer_tracking@fbc-tiling-4:
    - shard-tglb:         NOTRUN -> [SKIP][77] ([i915#5439])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@kms_frontbuffer_tracking@fbc-tiling-4.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-pgflip-blt:
    - shard-tglb:         NOTRUN -> [SKIP][78] ([i915#6497]) +6 similar issues
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-pgflip-blt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-render:
    - shard-iclb:         NOTRUN -> [SKIP][79] ([fdo#109280]) +9 similar issues
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-render:
    - shard-apl:          NOTRUN -> [SKIP][80] ([fdo#109271]) +157 similar issues
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl1/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-fullscreen:
    - shard-tglb:         NOTRUN -> [SKIP][81] ([fdo#109280] / [fdo#111825]) +16 similar issues
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-fullscreen.html

  * igt@kms_hdr@bpc-switch:
    - shard-tglb:         NOTRUN -> [SKIP][82] ([i915#3555]) +2 similar issues
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb1/igt@kms_hdr@bpc-switch.html

  * igt@kms_plane@plane-panning-bottom-right-suspend@pipe-b-planes:
    - shard-iclb:         [PASS][83] -> [DMESG-WARN][84] ([i915#2867])
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb6/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-b-planes.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb5/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-b-planes.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb:
    - shard-glk:          NOTRUN -> [FAIL][85] ([fdo#108145] / [i915#265])
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk5/igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb.html
    - shard-apl:          NOTRUN -> [FAIL][86] ([fdo#108145] / [i915#265])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl7/igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb.html

  * igt@kms_plane_lowres@tiling-x@pipe-b-edp-1:
    - shard-iclb:         NOTRUN -> [SKIP][87] ([i915#3536]) +2 similar issues
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb7/igt@kms_plane_lowres@tiling-x@pipe-b-edp-1.html

  * igt@kms_plane_scaling@planes-downscale-factor-0-5@pipe-a-edp-1:
    - shard-iclb:         [PASS][88] -> [SKIP][89] ([i915#5235]) +2 similar issues
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb7/igt@kms_plane_scaling@planes-downscale-factor-0-5@pipe-a-edp-1.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@kms_plane_scaling@planes-downscale-factor-0-5@pipe-a-edp-1.html

  * igt@kms_psr2_sf@cursor-plane-move-continuous-sf:
    - shard-tglb:         NOTRUN -> [SKIP][90] ([i915#2920]) +1 similar issue
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb1/igt@kms_psr2_sf@cursor-plane-move-continuous-sf.html

  * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area:
    - shard-apl:          NOTRUN -> [SKIP][91] ([fdo#109271] / [i915#658]) +2 similar issues
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl1/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area.html
    - shard-glk:          NOTRUN -> [SKIP][92] ([fdo#109271] / [i915#658]) +1 similar issue
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk6/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area.html
    - shard-iclb:         NOTRUN -> [SKIP][93] ([fdo#111068] / [i915#658])
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area.html

  * igt@kms_psr@psr2_cursor_plane_move:
    - shard-iclb:         [PASS][94] -> [SKIP][95] ([fdo#109441]) +2 similar issues
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb2/igt@kms_psr@psr2_cursor_plane_move.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb4/igt@kms_psr@psr2_cursor_plane_move.html

  * igt@kms_psr@psr2_primary_render:
    - shard-tglb:         NOTRUN -> [FAIL][96] ([i915#132] / [i915#3467])
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb5/igt@kms_psr@psr2_primary_render.html

  * igt@kms_vblank@pipe-d-wait-idle:
    - shard-glk:          NOTRUN -> [SKIP][97] ([fdo#109271] / [i915#533])
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk8/igt@kms_vblank@pipe-d-wait-idle.html

  * igt@nouveau_crc@pipe-d-ctx-flip-detection:
    - shard-glk:          NOTRUN -> [SKIP][98] ([fdo#109271]) +87 similar issues
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk7/igt@nouveau_crc@pipe-d-ctx-flip-detection.html

  * igt@perf@gen12-mi-rpc:
    - shard-iclb:         NOTRUN -> [SKIP][99] ([fdo#109289])
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb8/igt@perf@gen12-mi-rpc.html

  * igt@prime_nv_api@nv_self_import_to_different_fd:
    - shard-iclb:         NOTRUN -> [SKIP][100] ([fdo#109291])
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@prime_nv_api@nv_self_import_to_different_fd.html

  * igt@prime_nv_test@i915_import_cpu_mmap:
    - shard-tglb:         NOTRUN -> [SKIP][101] ([fdo#109291]) +1 similar issue
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb5/igt@prime_nv_test@i915_import_cpu_mmap.html

  * igt@sysfs_clients@recycle-many:
    - shard-apl:          NOTRUN -> [SKIP][102] ([fdo#109271] / [i915#2994])
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl7/igt@sysfs_clients@recycle-many.html

  
#### Possible fixes ####

  * igt@gem_eio@reset-stress:
    - shard-tglb:         [FAIL][103] ([i915#5784]) -> [PASS][104]
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-tglb8/igt@gem_eio@reset-stress.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb1/igt@gem_eio@reset-stress.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-tglb:         [FAIL][105] ([i915#2842]) -> [PASS][106]
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-tglb5/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb3/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace@vcs0:
    - shard-glk:          [FAIL][107] ([i915#2842]) -> [PASS][108] +2 similar issues
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk5/igt@gem_exec_fair@basic-pace@vcs0.html
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk6/igt@gem_exec_fair@basic-pace@vcs0.html

  * igt@gem_softpin@noreloc-s3:
    - shard-tglb:         [INCOMPLETE][109] -> [PASS][110]
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-tglb5/igt@gem_softpin@noreloc-s3.html
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@gem_softpin@noreloc-s3.html

  * igt@i915_pm_dc@dc9-dpms:
    - shard-apl:          [SKIP][111] ([fdo#109271]) -> [PASS][112]
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-apl2/igt@i915_pm_dc@dc9-dpms.html
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl2/igt@i915_pm_dc@dc9-dpms.html

  * igt@kms_big_fb@yf-tiled-32bpp-rotate-270:
    - shard-glk:          [FAIL][113] ([i915#1888]) -> [PASS][114]
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk8/igt@kms_big_fb@yf-tiled-32bpp-rotate-270.html
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk3/igt@kms_big_fb@yf-tiled-32bpp-rotate-270.html

  * igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-atomic:
    - shard-glk:          [DMESG-FAIL][115] ([i915#118] / [i915#1888]) -> [PASS][116]
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk8/igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-atomic.html
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk5/igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-atomic.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@c-hdmi-a2:
    - shard-glk:          [FAIL][117] ([i915#79]) -> [PASS][118]
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk1/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-hdmi-a2.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk6/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-hdmi-a2.html

  * igt@kms_flip@flip-vs-suspend-interruptible@b-dp1:
    - shard-apl:          [DMESG-WARN][119] ([i915#180]) -> [PASS][120] +2 similar issues
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-apl3/igt@kms_flip@flip-vs-suspend-interruptible@b-dp1.html
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-apl1/igt@kms_flip@flip-vs-suspend-interruptible@b-dp1.html

  * igt@kms_hdmi_inject@inject-audio:
    - shard-tglb:         [SKIP][121] ([i915#433]) -> [PASS][122]
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-tglb3/igt@kms_hdmi_inject@inject-audio.html
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb5/igt@kms_hdmi_inject@inject-audio.html

  * igt@kms_plane_lowres@tiling-y@pipe-a-hdmi-a-1:
    - shard-glk:          [DMESG-WARN][123] ([i915#118] / [i915#1888]) -> [PASS][124]
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk5/igt@kms_plane_lowres@tiling-y@pipe-a-hdmi-a-1.html
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk2/igt@kms_plane_lowres@tiling-y@pipe-a-hdmi-a-1.html

  * igt@kms_psr@psr2_primary_blt:
    - shard-iclb:         [SKIP][125] ([fdo#109441]) -> [PASS][126] +2 similar issues
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb1/igt@kms_psr@psr2_primary_blt.html
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@kms_psr@psr2_primary_blt.html

  * igt@perf@stress-open-close:
    - shard-glk:          [INCOMPLETE][127] ([i915#5213]) -> [PASS][128]
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-glk5/igt@perf@stress-open-close.html
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-glk3/igt@perf@stress-open-close.html

  
#### Warnings ####

  * igt@gem_exec_balancer@parallel-ordering:
    - shard-iclb:         [SKIP][129] ([i915#4525]) -> [FAIL][130] ([i915#6117])
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb7/igt@gem_exec_balancer@parallel-ordering.html
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb1/igt@gem_exec_balancer@parallel-ordering.html

  * igt@kms_content_protection@mei_interface:
    - shard-tglb:         [SKIP][131] ([i915#1063]) -> [SKIP][132] ([fdo#109300])
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-tglb5/igt@kms_content_protection@mei_interface.html
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-tglb8/igt@kms_content_protection@mei_interface.html
    - shard-iclb:         [SKIP][133] ([fdo#109300] / [fdo#111066]) -> [SKIP][134] ([fdo#109300])
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb6/igt@kms_content_protection@mei_interface.html
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb5/igt@kms_content_protection@mei_interface.html

  * igt@kms_psr2_sf@cursor-plane-move-continuous-sf:
    - shard-iclb:         [SKIP][135] ([i915#2920]) -> [SKIP][136] ([i915#658])
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb2/igt@kms_psr2_sf@cursor-plane-move-continuous-sf.html
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb6/igt@kms_psr2_sf@cursor-plane-move-continuous-sf.html

  * igt@kms_psr2_sf@overlay-plane-move-continuous-sf:
    - shard-iclb:         [SKIP][137] ([i915#658]) -> [SKIP][138] ([i915#2920])
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb1/igt@kms_psr2_sf@overlay-plane-move-continuous-sf.html
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@kms_psr2_sf@overlay-plane-move-continuous-sf.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-iclb:         [SKIP][139] ([fdo#109642] / [fdo#111068] / [i915#658]) -> [FAIL][140] ([i915#5939])
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12163/shard-iclb6/igt@kms_psr2_su@page_flip-p010.html
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/shard-iclb2/igt@kms_psr2_su@page_flip-p010.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109279]: https://bugs.freedesktop.org/show_bug.cgi?id=109279
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109283]: https://bugs.freedesktop.org/show_bug.cgi?id=109283
  [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
  [fdo#109300]: https://bugs.freedesktop.org/show_bug.cgi?id=109300
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#111066]: https://bugs.freedesktop.org/show_bug.cgi?id=111066
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
  [fdo#111656]: https://bugs.freedesktop.org/show_bug.cgi?id=111656
  [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1063]: https://gitlab.freedesktop.org/drm/intel/issues/1063
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#132]: https://gitlab.freedesktop.org/drm/intel/issues/132
  [i915#1759]: https://gitlab.freedesktop.org/drm/intel/issues/1759
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2410]: https://gitlab.freedesktop.org/drm/intel/issues/2410
  [i915#2527]: https://gitlab.freedesktop.org/drm/intel/issues/2527
  [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
  [i915#2867]: https://gitlab.freedesktop.org/drm/intel/issues/2867
  [i915#2920]: https://gitlab.freedesktop.org/drm/intel/issues/2920
  [i915#2994]: https://gitlab.freedesktop.org/drm/intel/issues/2994
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3323]: https://gitlab.freedesktop.org/drm/intel/issues/3323
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3467]: https://gitlab.freedesktop.org/drm/intel/issues/3467
  [i915#3536]: https://gitlab.freedesktop.org/drm/intel/issues/3536
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3689]: https://gitlab.freedesktop.org/drm/intel/issues/3689
  [i915#3886]: https://gitlab.freedesktop.org/drm/intel/issues/3886
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#433]: https://gitlab.freedesktop.org/drm/intel/issues/433
  [i915#4525]: https://gitlab.freedesktop.org/drm/intel/issues/4525
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4767]: https://gitlab.freedesktop.org/drm/intel/issues/4767
  [i915#4877]: https://gitlab.freedesktop.org/drm/intel/issues/4877
  [i915#5213]: https://gitlab.freedesktop.org/drm/intel/issues/5213
  [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5325]: https://gitlab.freedesktop.org/drm/intel/issues/5325
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#5439]: https://gitlab.freedesktop.org/drm/intel/issues/5439
  [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [i915#5939]: https://gitlab.freedesktop.org/drm/intel/issues/5939
  [i915#6016]: https://gitlab.freedesktop.org/drm/intel/issues/6016
  [i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
  [i915#6117]: https://gitlab.freedesktop.org/drm/intel/issues/6117
  [i915#6227]: https://gitlab.freedesktop.org/drm/intel/issues/6227
  [i915#6497]: https://gitlab.freedesktop.org/drm/intel/issues/6497
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_6659 -> IGTPW_7809
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_12163: 8a052348946d9ec1b368ddcc1d3db5f2fc486f75 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_7809: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/index.html
  IGT_6659: 1becf700a737a7a98555a0cfbe8566355377afb2 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_7809/index.html

[-- Attachment #2: Type: text/html, Size: 46517 bytes --]

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

* Re: [igt-dev] [RFC v2 7/8] tests/i915/vm_bind: Add basic VM_BIND test support
  2022-09-21  8:55   ` Petri Latvala
@ 2022-09-21 18:21     ` Niranjana Vishwanathapura
  0 siblings, 0 replies; 14+ messages in thread
From: Niranjana Vishwanathapura @ 2022-09-21 18:21 UTC (permalink / raw)
  To: Petri Latvala
  Cc: igt-dev, daniel.vetter, thomas.hellstrom, matthew.auld, tvrtko.ursulin

On Wed, Sep 21, 2022 at 11:55:47AM +0300, Petri Latvala wrote:
>On Wed, Sep 21, 2022 at 12:12:19AM -0700, Niranjana Vishwanathapura wrote:
>> Add basic tests for VM_BIND functionality. Bind the buffer objects in
>> device page table with VM_BIND calls and have GPU copy the data from a
>> source buffer object to destination buffer object.
>> Test for different buffer sizes, buffer object placement and with
>> multiple contexts.
>>
>> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
>> ---
>>  tests/i915/i915_vm_bind_basic.c | 544 ++++++++++++++++++++++++++++++++
>>  tests/meson.build               |   1 +
>>  2 files changed, 545 insertions(+)
>>  create mode 100644 tests/i915/i915_vm_bind_basic.c
>>
>> diff --git a/tests/i915/i915_vm_bind_basic.c b/tests/i915/i915_vm_bind_basic.c
>> new file mode 100644
>> index 0000000000..b3aa8eac9b
>> --- /dev/null
>> +++ b/tests/i915/i915_vm_bind_basic.c
>> @@ -0,0 +1,544 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright © 2022 Intel Corporation
>> + */
>> +
>> +/** @file i915_vm_bind_basic.c
>> + *
>> + * This is the basic test for VM_BIND functionality.
>> + *
>> + * The goal is to ensure that basics work.
>> + */
>> +
>> +#include <sys/poll.h>
>> +
>> +#include "i915/gem.h"
>> +#include "igt.h"
>> +#include "igt_syncobj.h"
>> +#include <unistd.h>
>> +#include <stdlib.h>
>> +#include <stdint.h>
>> +#include <stdio.h>
>> +#include <string.h>
>> +#include <fcntl.h>
>> +#include <inttypes.h>
>> +#include <errno.h>
>> +#include <sys/stat.h>
>> +#include <sys/ioctl.h>
>> +#include "drm.h"
>> +#include "i915/gem_vm.h"
>> +
>> +IGT_TEST_DESCRIPTION("Basic test for vm_bind functionality");
>> +
>> +#define PAGE_SIZE   4096
>> +#define PAGE_SHIFT  12
>> +
>> +#define GEN9_XY_FAST_COPY_BLT_CMD       (2 << 29 | 0x42 << 22)
>> +#define BLT_DEPTH_32                    (3 << 24)
>> +
>> +#define DEFAULT_BUFF_SIZE  (4 * PAGE_SIZE)
>> +#define SZ_64K             (16 * PAGE_SIZE)
>> +#define SZ_2M              (512 * PAGE_SIZE)
>> +
>> +#define MAX_CTXTS   2
>> +#define MAX_CMDS    4
>> +
>> +#define BATCH_FENCE  0
>> +#define SRC_FENCE    1
>> +#define DST_FENCE    2
>> +#define EXEC_FENCE   3
>> +#define NUM_FENCES   4
>> +
>> +enum {
>> +	BATCH_MAP,
>> +	SRC_MAP,
>> +	DST_MAP = SRC_MAP + MAX_CMDS,
>> +	MAX_MAP
>> +};
>> +
>> +struct mapping {
>> +	uint32_t  obj;
>> +	uint64_t  va;
>> +	uint64_t  offset;
>> +	uint64_t  length;
>> +	uint64_t  flags;
>> +};
>> +
>> +#define SET_MAP(map, _obj, _va, _offset, _length, _flags)   \
>> +{                                  \
>> +	(map).obj = _obj;          \
>> +	(map).va = _va;            \
>> +	(map).offset = _offset;	   \
>> +	(map).length = _length;	   \
>> +	(map).flags = _flags;	   \
>> +}
>> +
>> +#define MAX_BATCH_DWORD    64
>> +
>> +#define abs(x) ((x) >= 0 ? (x) : -(x))
>> +
>> +#define TEST_SMEM             BIT(0)
>> +#define TEST_SKIP_UNBIND      BIT(1)
>> +#define TEST_SHARE_VM         BIT(2)
>> +
>> +#define is_lmem(cfg)        (!((cfg)->flags & TEST_SMEM))
>> +#define do_unbind(cfg)      (!((cfg)->flags & TEST_SKIP_UNBIND))
>> +#define do_share_vm(cfg)    ((cfg)->flags & TEST_SHARE_VM)
>> +
>> +struct test_cfg {
>> +	const char *name;
>> +	uint32_t size;
>> +	uint8_t num_cmds;
>> +	uint32_t num_ctxts;
>> +	uint32_t flags;
>> +};
>> +
>> +static uint64_t
>> +gettime_ns(void)
>> +{
>> +	struct timespec current;
>> +	clock_gettime(CLOCK_MONOTONIC, &current);
>> +	return (uint64_t)current.tv_sec * NSEC_PER_SEC + current.tv_nsec;
>> +}
>> +
>> +static bool syncobj_busy(int fd, uint32_t handle)
>> +{
>> +	bool result;
>> +	int sf;
>> +
>> +	sf = syncobj_handle_to_fd(fd, handle,
>> +				  DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE);
>> +	result = poll(&(struct pollfd){sf, POLLIN}, 1, 0) == 0;
>> +	close(sf);
>> +
>> +	return result;
>> +}
>> +
>> +static inline void i915_vm_bind(int fd, uint32_t vm_id, struct mapping *m,
>> +				struct drm_i915_gem_timeline_fence *fence)
>> +{
>> +	struct drm_i915_gem_vm_bind bind;
>> +
>> +	memset(&bind, 0, sizeof(bind));
>> +	bind.vm_id = vm_id;
>> +	bind.handle = m->obj;
>> +	bind.start = m->va;
>> +	bind.offset = m->offset;
>> +	bind.length = m->length;
>> +	bind.flags = m->flags;
>> +	if (fence) {
>> +		bind.fence.flags |= I915_TIMELINE_FENCE_SIGNAL;
>> +		bind.fence.handle = syncobj_create(fd, 0);
>> +		bind.fence.value = 0;
>> +
>> +		fence->handle = bind.fence.handle;
>> +		fence->flags = I915_TIMELINE_FENCE_WAIT;
>> +		fence->value = bind.fence.value;
>> +	}
>> +
>> +	igt_info("VM_BIND vm:0x%x h:0x%x v:0x%lx o:0x%lx l:0x%lx f:0x%llx\n",
>> +		 vm_id, m->obj, m->va, m->offset, m->length, bind.flags);
>> +	gem_vm_bind(fd, &bind);
>> +}
>> +
>> +static inline void i915_vm_unbind(int fd, uint32_t vm_id, struct mapping *m)
>> +{
>> +	struct drm_i915_gem_vm_unbind unbind;
>> +
>> +	/* Object handle is not required during unbind */
>> +	igt_info("VM_UNBIND vm:0x%x v:0x%lx l:0x%lx f:0x%lx\n",
>> +		 vm_id, m->va, m->length, m->flags);
>> +	memset(&unbind, 0, sizeof(unbind));
>> +	unbind.vm_id = vm_id;
>> +	unbind.start = m->va;
>> +	unbind.length = m->length;
>> +	unbind.flags = m->flags;
>> +
>> +	gem_vm_unbind(fd, &unbind);
>> +}
>> +
>> +static void print_buffer(void *buf, uint32_t size,
>> +			 const char *str, bool full)
>> +{
>> +	uint32_t i = 0;
>> +
>> +	igt_debug("Printing %s 0x%lx size 0x%x\n", str, (uint64_t)buf, size);
>> +	while (i < size) {
>> +		uint32_t *b = buf + i;
>> +
>> +		igt_debug("\t%s[0x%04x]: 0x%08x 0x%08x 0x%08x 0x%08x %s\n",
>> +			  str, i, b[0], b[1], b[2], b[3], full ? "" : "...");
>> +		i += full ? 16 : PAGE_SIZE;
>> +	}
>> +}
>> +
>> +static int gem_linear_fast_blt(uint32_t *batch, uint64_t src,
>> +			       uint64_t dst, uint32_t size)
>> +{
>> +	uint32_t *cmd = batch;
>> +	uint64_t src_offset = (uint64_t)src;
>> +	uint64_t dst_offset = (uint64_t)dst;
>> +
>> +	*cmd++ = GEN9_XY_FAST_COPY_BLT_CMD | (10 - 2);
>> +	*cmd++ = BLT_DEPTH_32 | PAGE_SIZE;
>> +	*cmd++ = 0;
>> +	*cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
>> +	*cmd++ = lower_32_bits(dst_offset);
>> +	*cmd++ = upper_32_bits(dst_offset);
>> +	*cmd++ = 0;
>> +	*cmd++ = PAGE_SIZE;
>> +	*cmd++ = lower_32_bits(src_offset);
>> +	*cmd++ = upper_32_bits(src_offset);
>> +
>> +	*cmd++ = MI_BATCH_BUFFER_END;
>> +	*cmd++ = 0;
>> +
>> +	return ALIGN((cmd - batch + 1) * sizeof(uint32_t), 8);
>> +}
>> +
>> +static void __gem_copy(int fd, uint64_t src, uint64_t dst, uint32_t offset, uint32_t size,
>> +		       uint32_t ctx_id, void *batch_addr, unsigned int eb_flags,
>> +		       struct drm_i915_gem_timeline_fence *fence)
>> +{
>> +	uint32_t len, buf[MAX_BATCH_DWORD] = { 0 };
>> +	struct drm_i915_gem_execbuffer3 execbuf;
>> +
>> +	len = gem_linear_fast_blt(buf, src + offset, dst + offset, size);
>> +
>> +	memcpy(batch_addr, (void *)buf, len);
>> +	print_buffer(buf, len, "batch", true);
>> +
>> +	memset(&execbuf, 0, sizeof(execbuf));
>> +	execbuf.ctx_id = ctx_id;
>> +	execbuf.batch_address = (uint64_t)&batch_addr;
>
>Use to_user_pointer() to convert addresses to uint64_t.
>

Thanks Petri, will do.

Niranjana

>-- 
>Petri Latvala
>
>
>> +	execbuf.engine_idx = eb_flags;
>> +	execbuf.fence_count = NUM_FENCES;
>> +	execbuf.timeline_fences = to_user_pointer(fence);
>> +	gem_execbuf3(fd, &execbuf);
>> +}
>> +
>> +static void i915_gem_copy(int fd, uint64_t src, uint64_t dst, uint32_t size,
>> +			  const intel_ctx_t **ctx, uint32_t num_ctxts,
>> +			  void **batch_addr, unsigned int eb_flags,
>> +			  struct drm_i915_gem_timeline_fence (*fence)[NUM_FENCES])
>> +{
>> +	uint32_t i, delta = size / num_ctxts;
>> +
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		igt_info("Issuing gem copy on ctx 0x%x\n", ctx[i]->id);
>> +		__gem_copy(fd, src, dst, (i * delta), delta,
>> +			   ctx[i]->id, batch_addr[i], eb_flags, fence[i]);
>> +	}
>> +}
>> +
>> +static void i915_gem_sync(int fd, const intel_ctx_t **ctx, uint32_t num_ctxts,
>> +			  struct drm_i915_gem_timeline_fence (*fence)[NUM_FENCES])
>> +{
>> +	uint32_t i;
>> +
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		uint64_t fence_value = 0;
>> +
>> +		igt_assert(syncobj_timeline_wait(fd, &fence[i][EXEC_FENCE].handle,
>> +						 (uint64_t *)&fence_value, 1,
>> +						 gettime_ns() + (2 * NSEC_PER_SEC),
>> +						 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
>> +		igt_assert(!syncobj_busy(fd, fence[i][EXEC_FENCE].handle));
>> +		igt_info("gem copy completed on ctx 0x%x\n", ctx[i]->id);
>> +	}
>> +}
>> +
>> +static struct igt_collection *get_region_set(int fd, struct test_cfg *cfg)
>> +{
>> +	uint32_t mem_type[] = { I915_SYSTEM_MEMORY, I915_DEVICE_MEMORY };
>> +	uint32_t lmem_type[] = { I915_DEVICE_MEMORY };
>> +	struct drm_i915_query_memory_regions *query_info;
>> +
>> +	query_info = gem_get_query_memory_regions(fd);
>> +	igt_assert(query_info);
>> +
>> +	if (is_lmem(cfg))
>> +		return __get_memory_region_set(query_info, lmem_type, 1);
>> +	else
>> +		return __get_memory_region_set(query_info, mem_type, 2);
>> +}
>> +
>> +static void create_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint32_t size,
>> +			    uint32_t num_cmds, void *src_addr[])
>> +{
>> +	int i;
>> +	struct igt_collection *set = get_region_set(fd, cfg);
>> +	uint32_t region;
>> +
>> +	for (i = 0; i < num_cmds; i++) {
>> +		region = igt_collection_get_value(set, i % set->size);
>> +		src[i] = gem_create_in_memory_regions(fd, size, region);
>> +		src_addr[i] = gem_mmap__cpu(fd, src[i], 0, size, PROT_WRITE);
>> +	}
>> +}
>> +
>> +static void destroy_src_objs(int fd, struct test_cfg *cfg, uint32_t src[], uint32_t size,
>> +			     uint32_t num_cmds, void *src_addr[])
>> +{
>> +	int i;
>> +
>> +	for (i = 0; i < num_cmds; i++) {
>> +		igt_assert(gem_munmap(src_addr[i], size) == 0);
>> +		igt_debug("Closing object 0x%x\n", src[i]);
>> +		gem_close(fd, src[i]);
>> +	}
>> +}
>> +
>> +static uint32_t create_dst_obj(int fd, struct test_cfg *cfg, uint32_t size, void **dst_addr)
>> +{
>> +	uint32_t dst;
>> +	struct igt_collection *set = get_region_set(fd, cfg);
>> +
>> +	dst = gem_create_in_memory_regions(fd, size, igt_collection_get_value(set, 0));
>> +	*dst_addr = gem_mmap__cpu(fd, dst, 0, size, PROT_WRITE);
>> +
>> +	return dst;
>> +}
>> +
>> +static void destroy_dst_obj(int fd, struct test_cfg *cfg, uint32_t dst, uint32_t size, void *dst_addr)
>> +{
>> +	igt_assert(gem_munmap(dst_addr, size) == 0);
>> +	igt_debug("Closing object 0x%x\n", dst);
>> +	gem_close(fd, dst);
>> +}
>> +
>> +static void pattern_fill_buf(void *src_addr[], uint32_t size, uint32_t num_cmds, uint32_t npages)
>> +{
>> +	uint32_t i, j;
>> +	void *buf;
>> +
>> +	/* Allocate buffer and fill pattern */
>> +	buf = malloc(size);
>> +	igt_require(buf);
>> +
>> +	for (i = 0; i < num_cmds; i++) {
>> +		for (j = 0; j < npages; j++)
>> +			memset(buf + j * PAGE_SIZE, i * npages + j + 1, PAGE_SIZE);
>> +
>> +		memcpy(src_addr[i], buf, size);
>> +	}
>> +
>> +	free(buf);
>> +}
>> +
>> +static void run_test(int fd, const intel_ctx_t *base_ctx, struct test_cfg *cfg,
>> +		     const struct intel_execution_engine2 *e)
>> +{
>> +	void *src_addr[MAX_CMDS] = { 0 }, *dst_addr = NULL;
>> +	uint32_t src[MAX_CMDS], dst, i, size = cfg->size;
>> +	struct drm_i915_gem_timeline_fence exec_fence[MAX_CTXTS][NUM_FENCES];
>> +	uint32_t shared_vm_id, vm_id[MAX_CTXTS];
>> +	struct mapping map[MAX_CTXTS][MAX_MAP];
>> +	uint32_t num_ctxts = cfg->num_ctxts;
>> +	uint32_t num_cmds = cfg->num_cmds;
>> +	uint32_t npages = size / PAGE_SIZE;
>> +	const intel_ctx_t *ctx[MAX_CTXTS];
>> +	bool share_vm = do_share_vm(cfg);
>> +	void *batch_addr[MAX_CTXTS];
>> +	uint32_t batch[MAX_CTXTS];
>> +	uint64_t src_va, dst_va;
>> +	uint32_t delta;
>> +
>> +	delta = size / num_ctxts;
>> +	if (share_vm)
>> +		shared_vm_id = gem_vm_create_in_vm_bind_mode(fd);
>> +
>> +	/* Create contexts */
>> +	num_ctxts = min_t(num_ctxts, MAX_CTXTS, num_ctxts);
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		uint32_t vmid;
>> +
>> +		if (share_vm)
>> +			vmid = shared_vm_id;
>> +		else
>> +			vmid = gem_vm_create_in_vm_bind_mode(fd);
>> +
>> +		ctx[i] = intel_ctx_create(fd, &base_ctx->cfg);
>> +		gem_context_set_vm(fd, ctx[i]->id, vmid);
>> +		vm_id[i] = gem_context_get_vm(fd, ctx[i]->id);
>> +
>> +		exec_fence[i][EXEC_FENCE].handle = syncobj_create(fd, 0);
>> +		exec_fence[i][EXEC_FENCE].flags = I915_TIMELINE_FENCE_SIGNAL;
>> +		exec_fence[i][EXEC_FENCE].value = 0;
>> +	}
>> +
>> +	/* Create objects */
>> +	num_cmds = min_t(num_cmds, MAX_CMDS, num_cmds);
>> +	create_src_objs(fd, cfg, src, size, num_cmds, src_addr);
>> +	dst = create_dst_obj(fd, cfg, size, &dst_addr);
>> +
>> +	/*
>> +	 * mmap'ed addresses are not 64K aligned. On platforms requiring
>> +	 * 64K alignment, use static addresses.
>> +	 */
>> +	if (size < SZ_2M && num_cmds && !HAS_64K_PAGES(intel_get_drm_devid(fd))) {
>> +		src_va = (uint64_t)src_addr[0];
>> +		dst_va = (uint64_t)dst_addr;
>> +	} else {
>> +		src_va = 0xa000000;
>> +		dst_va = 0xb000000;
>> +	}
>> +
>> +	pattern_fill_buf(src_addr, size, num_cmds, npages);
>> +
>> +	if (num_cmds)
>> +		print_buffer(src_addr[num_cmds - 1], size, "src_obj", false);
>> +
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		batch[i] = gem_create_vm_private_in_memory_regions(fd, PAGE_SIZE, vm_id[i], REGION_SMEM);
>> +		batch_addr[i] = gem_mmap__cpu(fd, batch[i], 0, PAGE_SIZE, PROT_WRITE);
>> +	}
>> +
>> +	/* Create mappings */
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		uint64_t offset = i * delta;
>> +		uint32_t j;
>> +
>> +		for (j = 0; j < num_cmds; j++)
>> +			SET_MAP(map[i][SRC_MAP + j], src[j], src_va + offset, offset, delta, 0);
>> +		SET_MAP(map[i][DST_MAP], dst, dst_va + offset, offset, delta, 0);
>> +		SET_MAP(map[i][BATCH_MAP], batch[i], (uint64_t)batch_addr[i], 0, PAGE_SIZE, 0);
>> +	}
>> +
>> +	/* Bind the buffers to device page table */
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		i915_vm_bind(fd, vm_id[i], &map[i][BATCH_MAP], &exec_fence[i][BATCH_FENCE]);
>> +		i915_vm_bind(fd, vm_id[i], &map[i][DST_MAP], &exec_fence[i][DST_FENCE]);
>> +	}
>> +
>> +	/* Have GPU do the copy */
>> +	for (i = 0; i < cfg->num_cmds; i++) {
>> +		uint32_t j;
>> +
>> +		for (j = 0; j < num_ctxts; j++)
>> +			i915_vm_bind(fd, vm_id[j], &map[j][SRC_MAP + i], &exec_fence[j][SRC_FENCE]);
>> +
>> +		i915_gem_copy(fd, src_va, dst_va, size, ctx, num_ctxts,
>> +			      batch_addr, e->flags, exec_fence);
>> +
>> +		i915_gem_sync(fd, ctx, num_ctxts, exec_fence);
>> +
>> +		for (j = 0; j < num_ctxts; j++) {
>> +			syncobj_destroy(fd, exec_fence[j][SRC_FENCE].handle);
>> +			if (do_unbind(cfg))
>> +				i915_vm_unbind(fd, vm_id[j], &map[j][SRC_MAP + i]);
>> +		}
>> +	}
>> +
>> +	/*
>> +	 * Unbind buffers from device page table.
>> +	 * If not, it should get unbound while freeing the buffer.
>> +	 */
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		syncobj_destroy(fd, exec_fence[i][BATCH_FENCE].handle);
>> +		syncobj_destroy(fd, exec_fence[i][DST_FENCE].handle);
>> +		if (do_unbind(cfg)) {
>> +			i915_vm_unbind(fd, vm_id[i], &map[i][BATCH_MAP]);
>> +			i915_vm_unbind(fd, vm_id[i], &map[i][DST_MAP]);
>> +		}
>> +	}
>> +
>> +	/* Close batch buffers */
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		syncobj_destroy(fd, exec_fence[i][EXEC_FENCE].handle);
>> +		gem_close(fd, batch[i]);
>> +	}
>> +
>> +	/* Accessing the buffer will migrate the pages from device to host */
>> +	print_buffer(dst_addr, size, "dst_obj", false);
>> +
>> +	/* Validate by comparing the last SRC with DST */
>> +	if (num_cmds)
>> +		igt_assert(memcmp(src_addr[num_cmds - 1], dst_addr, size) == 0);
>> +
>> +	/* Free the objects */
>> +	destroy_src_objs(fd, cfg, src, size, num_cmds, src_addr);
>> +	destroy_dst_obj(fd, cfg, dst, size, dst_addr);
>> +
>> +	/* Done with the contexts */
>> +	for (i = 0; i < num_ctxts; i++) {
>> +		igt_debug("Destroying context 0x%x\n", ctx[i]->id);
>> +		gem_vm_destroy(fd, vm_id[i]);
>> +		intel_ctx_destroy(fd, ctx[i]);
>> +	}
>> +
>> +	if (share_vm)
>> +		gem_vm_destroy(fd, shared_vm_id);
>> +}
>> +
>> +static int vm_bind_version(int fd)
>> +{
>> +	struct drm_i915_getparam gp;
>> +	int value = 0;
>> +
>> +	memset(&gp, 0, sizeof(gp));
>> +	gp.param = I915_PARAM_VM_BIND_VERSION;
>> +	gp.value = &value;
>> +
>> +	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
>> +	errno = 0;
>> +
>> +	return value;
>> +}
>> +
>> +igt_main
>> +{
>> +	struct test_cfg *t, tests[] = {
>> +		{"basic", 0, 1, 1, 0},
>> +		{"multi_cmds", 0, MAX_CMDS, 1, 0},
>> +		{"skip_copy", 0, 0, 1, 0},
>> +		{"skip_unbind",  0, 1, 1, TEST_SKIP_UNBIND},
>> +		{"multi_ctxts", 0, 1, MAX_CTXTS, 0},
>> +		{"share_vm", 0, 1, MAX_CTXTS, TEST_SHARE_VM},
>> +		{"64K", (16 * PAGE_SIZE), 1, 1, 0},
>> +		{"2M", SZ_2M, 1, 1, 0},
>> +		{"smem", 0, 1, 1, TEST_SMEM},
>> +		{"smem_multi_cmds", 0, MAX_CMDS, 1, TEST_SMEM},
>> +		{ }
>> +	};
>> +	int fd;
>> +	bool has_lmem;
>> +	uint32_t def_size;
>> +	struct intel_execution_engine2 *e;
>> +	const intel_ctx_t *ctx;
>> +
>> +	igt_fixture {
>> +		fd = drm_open_driver(DRIVER_INTEL);
>> +		igt_require_gem(fd);
>> +		igt_require(vm_bind_version(fd) == 1);
>> +		has_lmem = gem_has_lmem(fd);
>> +		def_size = HAS_64K_PAGES(intel_get_drm_devid(fd)) ?
>> +			   SZ_64K : DEFAULT_BUFF_SIZE;
>> +		ctx = intel_ctx_create_all_physical(fd);
>> +	}
>> +
>> +	/* Adjust test variables */
>> +	for (t = tests; t->name; t++) {
>> +		t->flags |= (has_lmem ? 0 : TEST_SMEM);
>> +		t->size = t->size ? : (def_size * abs(t->num_ctxts));
>> +	}
>> +
>> +	for (t = tests; t->name; t++) {
>> +		igt_describe_f("vm_bind %s test", t->name);
>> +		igt_subtest_with_dynamic_f("%s", t->name)
>> +			for_each_ctx_engine(fd, ctx, e) {
>> +				if (e->class == I915_ENGINE_CLASS_COPY) {
>> +					igt_dynamic(e->name) {
>> +						run_test(fd, ctx, t, e);
>> +					}
>> +				}
>> +			}
>> +	}
>> +
>> +	igt_fixture {
>> +		intel_ctx_destroy(fd, ctx);
>> +		close(fd);
>> +	}
>> +
>> +	igt_exit();
>> +}
>> diff --git a/tests/meson.build b/tests/meson.build
>> index 3ee2230543..b4348130d6 100644
>> --- a/tests/meson.build
>> +++ b/tests/meson.build
>> @@ -250,6 +250,7 @@ i915_progs = [
>>  	'sysfs_preempt_timeout',
>>  	'sysfs_timeslice_duration',
>>  	'i915_vm_bind_sanity',
>> +	'i915_vm_bind_basic',
>>  ]
>>
>>  msm_progs = [
>> --
>> 2.21.0.rc0.32.g243a4c7e27
>>

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

end of thread, other threads:[~2022-09-21 18:21 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-21  7:12 [igt-dev] [RFC v2 0/8] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 1/8] vm_bind: import uapi definitions Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 2/8] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 3/8] lib/vm_bind: Add vm_bind mode support for VM Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 4/8] lib/vm_bind: Add support for VM private objects Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 5/8] lib/vm_bind: Add prime_handle_to_fd_no_assert() Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 6/8] tests/i915/vm_bind: Add vm_bind sanity test Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 7/8] tests/i915/vm_bind: Add basic VM_BIND test support Niranjana Vishwanathapura
2022-09-21  8:55   ` Petri Latvala
2022-09-21 18:21     ` Niranjana Vishwanathapura
2022-09-21  7:12 ` [igt-dev] [RFC v2 8/8] tests/i915/vm_bind: Add userptr subtest Niranjana Vishwanathapura
2022-09-21  7:53 ` [igt-dev] ✗ GitLab.Pipeline: warning for vm_bind: Add VM_BIND validation support (rev2) Patchwork
2022-09-21  8:23 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2022-09-21  9:57 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.