All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support
@ 2022-11-29  7:23 Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 01/14] lib/i915: memory region gtt_alignment support Niranjana Vishwanathapura
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

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 tests to validate the VM_BIND, VM_UNBIND and execbuf3 ioctls and
various scenarios involving persistent mappings.

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,
  [PATCH v8 00/22] drm/i915/vm_bind: Add VM_BIND functionality

v2: Address various review comments
v3: Add gem_exec3_basic and gem_exec3_balancer tests,
    add gem_lmem_swapping@vm_bind subtest and some fixes.
v4: Add and use i915_vm_bind library functions,
    add lmem test if lmem region is present instead of skipping,
    remove helpers to create vm_private objects, instead use
    gem_create_ext() function.
v5: Use memory region's gtt_alignment, use non-recoverable faults,
    fix review comments.
v6: Rebased, add sanity tests for added reserved uapi fields,
    add gem_shrink@vm_bind* subtests.
v7: Pull in uapi changes and address review comments
v8: Rebased, add capture test

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

Niranjana Vishwanathapura (14):
  lib/i915: memory region gtt_alignment support
  lib/vm_bind: import uapi definitions
  lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls
  lib/vm_bind: Add vm_bind mode support for VM
  lib/vm_bind: Add vm_bind specific library functions
  lib/vm_bind: Add __prime_handle_to_fd()
  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
  tests/i915/vm_bind: Add gem_exec3_basic test
  tests/i915/vm_bind: Add gem_exec3_balancer test
  tests/i915/vm_bind: Add gem_lmem_swapping@vm_bind sub test
  tests/i915/vm_bind: Add gem_shrink@vm_bind* subtests
  tests/i915/vm_bind: Test capture of persistent mappings

 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/i915_drm_local.h             | 300 +++++++++++++
 lib/i915/i915_vm_bind.c               |  62 +++
 lib/i915/i915_vm_bind.h               |  16 +
 lib/i915/intel_memory_region.c        |   6 +
 lib/i915/intel_memory_region.h        |   1 +
 lib/intel_chipset.h                   |   2 +
 lib/ioctl_wrappers.c                  | 117 ++++-
 lib/ioctl_wrappers.h                  |   7 +
 lib/meson.build                       |   1 +
 tests/i915/gem_exec3_balancer.c       | 470 ++++++++++++++++++++
 tests/i915/gem_exec3_basic.c          | 139 ++++++
 tests/i915/gem_lmem_swapping.c        | 134 +++++-
 tests/i915/gem_pwrite.c               |  16 +-
 tests/i915/gem_shrink.c               |  70 ++-
 tests/i915/i915_vm_bind_basic.c       | 606 ++++++++++++++++++++++++++
 tests/i915/i915_vm_bind_capture.c     | 445 +++++++++++++++++++
 tests/i915/i915_vm_bind_sanity.c      | 357 +++++++++++++++
 tests/intel-ci/blacklist.txt          |   2 +-
 tests/intel-ci/fast-feedback.testlist |   3 +
 tests/meson.build                     |  11 +
 tests/prime_mmap.c                    |  26 +-
 25 files changed, 2799 insertions(+), 53 deletions(-)
 create mode 100644 lib/i915/i915_vm_bind.c
 create mode 100644 lib/i915/i915_vm_bind.h
 create mode 100644 tests/i915/gem_exec3_balancer.c
 create mode 100644 tests/i915/gem_exec3_basic.c
 create mode 100644 tests/i915/i915_vm_bind_basic.c
 create mode 100644 tests/i915/i915_vm_bind_capture.c
 create mode 100644 tests/i915/i915_vm_bind_sanity.c

-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 01/14] lib/i915: memory region gtt_alignment support
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 02/14] lib/vm_bind: import uapi definitions Niranjana Vishwanathapura
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Update library to include gtt_alignment field to support
platforms with 64K device memory pages.

v2: Do not pull in gtt_alignment uapi

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/i915/intel_memory_region.c | 6 ++++++
 lib/i915/intel_memory_region.h | 1 +
 lib/intel_chipset.h            | 2 ++
 3 files changed, 9 insertions(+)

diff --git a/lib/i915/intel_memory_region.c b/lib/i915/intel_memory_region.c
index 84e1bceb3..964962ebb 100644
--- a/lib/i915/intel_memory_region.c
+++ b/lib/i915/intel_memory_region.c
@@ -948,6 +948,12 @@ struct gem_memory_region *__gem_get_memory_regions(int i915)
 		if (r->size == -1ull)
 			r->size = igt_get_avail_ram_mb() << 20;
 
+		if (HAS_64K_PAGES(intel_get_drm_devid(i915)) &&
+		    r->ci.memory_class == I915_MEMORY_CLASS_DEVICE)
+			r->gtt_alignment = 16 * PAGE_SIZE;
+		else
+			r->gtt_alignment = PAGE_SIZE;
+
 		asprintf(&r->name, "%s%d",
 			 region_repr(&r->ci), r->ci.memory_instance);
 
diff --git a/lib/i915/intel_memory_region.h b/lib/i915/intel_memory_region.h
index 425bda0ec..84abb95b1 100644
--- a/lib/i915/intel_memory_region.h
+++ b/lib/i915/intel_memory_region.h
@@ -174,6 +174,7 @@ struct gem_memory_region {
 	char *name;
 
 	struct drm_i915_gem_memory_class_instance ci;
+	uint64_t gtt_alignment;
 	uint64_t size;
 	uint64_t cpu_size;
 };
diff --git a/lib/intel_chipset.h b/lib/intel_chipset.h
index 9b39472ad..0d825d42c 100644
--- a/lib/intel_chipset.h
+++ b/lib/intel_chipset.h
@@ -227,4 +227,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 */
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 02/14] lib/vm_bind: import uapi definitions
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 01/14] lib/i915: memory region gtt_alignment support Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 03/14] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls Niranjana Vishwanathapura
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Import required VM_BIND kernel uapi definitions.

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.

v2: Move vm_bind uapi definitions to i915_drm-local.h
    Define HAS_64K_PAGES()
    Pull in uapi updates
v3: Remove HAS_64K_PAGES()
v4: Import reserved field changes in vm_bind/unbind structures.
v5: Import I915_GEM_VM_BIND_CAPTURE

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/i915/i915_drm_local.h | 300 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 300 insertions(+)

diff --git a/lib/i915/i915_drm_local.h b/lib/i915/i915_drm_local.h
index 9a2273c4e..ed35be041 100644
--- a/lib/i915/i915_drm_local.h
+++ b/lib/i915/i915_drm_local.h
@@ -23,6 +23,306 @@ extern "C" {
 
 #define DRM_I915_QUERY_GEOMETRY_SUBSLICES      6
 
+/*
+ * Signal to the kernel that the object will need to be accessed via
+ * the CPU.
+ *
+ * Only valid when placing objects in I915_MEMORY_CLASS_DEVICE, and only
+ * strictly required on platforms where only some of the device memory
+ * is directly visible or mappable through the CPU, like on DG2+.
+ *
+ * One of the placements MUST also be I915_MEMORY_CLASS_SYSTEM, to
+ * ensure we can always spill the allocation to system memory, if we
+ * can't place the object in the mappable part of
+ * I915_MEMORY_CLASS_DEVICE.
+ *
+ * Without this hint, the kernel will assume that non-mappable
+ * I915_MEMORY_CLASS_DEVICE is preferred for this object. Note that the
+ * kernel can still migrate the object to the mappable part, as a last
+ * resort, if userspace ever CPU faults this object, but this might be
+ * expensive, and so ideally should be avoided.
+ */
+#define I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS (1 << 0)
+
+#define DRM_I915_GEM_VM_BIND		0x3d
+#define DRM_I915_GEM_VM_UNBIND		0x3e
+#define DRM_I915_GEM_EXECBUFFER3	0x3f
+
+#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)
+
+/*
+ * 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.
+ *
+ * See struct drm_i915_gem_vm_bind and struct drm_i915_gem_vm_unbind.
+ */
+#define I915_PARAM_VM_BIND_VERSION	58
+
+#define DRM_I915_GEM_EXECBUFFER3_EXT_TIMELINE_FENCES 0
+
+/**
+ * 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 (~0ull)
+
+	/** @fence_count: Number of fences in @timeline_fences array. */
+	__u64 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;
+
+	/** @rsvd: Reserved, MBZ */
+	__u64 rsvd;
+
+	/**
+	 * @extensions: Zero-terminated chain of extensions.
+	 *
+	 * For future extensions. See struct i915_user_extension.
+	 */
+	__u64 extensions;
+};
+
+/*
+ * If I915_VM_CREATE_FLAGS_USE_VM_BIND flag is set, VM created will work in
+ * VM_BIND mode
+ */
+#define I915_VM_CREATE_FLAGS_USE_VM_BIND	(1u << 0)
+
+/*
+ * For I915_GEM_CREATE_EXT_VM_PRIVATE usage see
+ * struct drm_i915_gem_create_ext_vm_private.
+ */
+#define I915_GEM_CREATE_EXT_VM_PRIVATE 2
+
+/**
+ * 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;
+
+	/** @rsvd: Reserved, MBZ */
+	__u32 rsvd;
+};
+
+/**
+ * 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.
+ *
+ * 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;
+#define I915_GEM_VM_BIND_CAPTURE           (1 << 0)
+#define __I915_GEM_VM_BIND_UNKNOWN_FLAGS   (-(I915_GEM_VM_BIND_CAPTURE << 1))
+
+	/** @rsvd: Reserved, MBZ */
+	__u64 rsvd[2];
+
+	/**
+	 * @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.
+ */
+struct drm_i915_gem_vm_unbind {
+	/** @vm_id: VM (address space) id to bind */
+	__u32 vm_id;
+
+	/** @pad: padding, MBZ */
+	__u32 pad;
+
+	/** @start: Virtual Address start to unbind */
+	__u64 start;
+
+	/** @length: Length of mapping to unbind */
+	__u64 length;
+
+	/** @flags: Currently reserved, MBZ. */
+	__u64 flags;
+#define __I915_GEM_VM_UNBIND_UNKNOWN_FLAGS (~0ull)
+
+	/** @rsvd: Reserved, MBZ */
+	__u64 rsvd[2];
+
+	/**
+	 * @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] 19+ messages in thread

* [igt-dev] [PATCH i-g-t v8 03/14] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 01/14] lib/i915: memory region gtt_alignment support Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 02/14] lib/vm_bind: import uapi definitions Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 04/14] lib/vm_bind: Add vm_bind mode support for VM Niranjana Vishwanathapura
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

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

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/ioctl_wrappers.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
 lib/ioctl_wrappers.h |  6 ++++
 2 files changed, 84 insertions(+)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 09eb3ce7b..ac37b6bb4 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 9a897fec2..223cd9160 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] 19+ messages in thread

* [igt-dev] [PATCH i-g-t v8 04/14] lib/vm_bind: Add vm_bind mode support for VM
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (2 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 03/14] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 05/14] lib/vm_bind: Add vm_bind specific library functions Niranjana Vishwanathapura
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

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

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
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 fe989a8d1..2d06b4198 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 505d55724..2a2247fe1 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 9a022a56c..ee3c65d06 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 acbb663e6..6cf46d887 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] 19+ messages in thread

* [igt-dev] [PATCH i-g-t v8 05/14] lib/vm_bind: Add vm_bind specific library functions
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (3 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 04/14] lib/vm_bind: Add vm_bind mode support for VM Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 06/14] lib/vm_bind: Add __prime_handle_to_fd() Niranjana Vishwanathapura
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Add vm_bind specific library interfaces.

v2: Add flags field

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/i915/i915_vm_bind.c | 62 +++++++++++++++++++++++++++++++++++++++++
 lib/i915/i915_vm_bind.h | 16 +++++++++++
 lib/meson.build         |  1 +
 3 files changed, 79 insertions(+)
 create mode 100644 lib/i915/i915_vm_bind.c
 create mode 100644 lib/i915/i915_vm_bind.h

diff --git a/lib/i915/i915_vm_bind.c b/lib/i915/i915_vm_bind.c
new file mode 100644
index 000000000..201912b49
--- /dev/null
+++ b/lib/i915/i915_vm_bind.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "ioctl_wrappers.h"
+#include "i915_drm.h"
+#include "i915_drm_local.h"
+#include "i915_vm_bind.h"
+
+void i915_vm_bind(int i915, uint32_t vm_id, uint64_t va, uint32_t handle,
+		  uint64_t offset, uint64_t length, uint64_t flags,
+		  uint32_t syncobj, uint64_t fence_value)
+{
+	struct drm_i915_gem_vm_bind bind;
+
+	memset(&bind, 0, sizeof(bind));
+	bind.vm_id = vm_id;
+	bind.handle = handle;
+	bind.start = va;
+	bind.offset = offset;
+	bind.length = length;
+	bind.flags = flags;
+	if (syncobj) {
+		bind.fence.handle = syncobj;
+		bind.fence.value = fence_value;
+		bind.fence.flags = I915_TIMELINE_FENCE_SIGNAL;
+	}
+
+	gem_vm_bind(i915, &bind);
+}
+
+void i915_vm_unbind(int i915, uint32_t vm_id, uint64_t va, uint64_t length)
+{
+	struct drm_i915_gem_vm_unbind unbind;
+
+	memset(&unbind, 0, sizeof(unbind));
+	unbind.vm_id = vm_id;
+	unbind.start = va;
+	unbind.length = length;
+
+	gem_vm_unbind(i915, &unbind);
+}
+
+int i915_vm_bind_version(int i915)
+{
+	struct drm_i915_getparam gp;
+	int value = 0;
+
+	memset(&gp, 0, sizeof(gp));
+	gp.param = I915_PARAM_VM_BIND_VERSION;
+	gp.value = &value;
+
+	ioctl(i915, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
+	errno = 0;
+
+	return value;
+}
diff --git a/lib/i915/i915_vm_bind.h b/lib/i915/i915_vm_bind.h
new file mode 100644
index 000000000..b11142cc8
--- /dev/null
+++ b/lib/i915/i915_vm_bind.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+#ifndef _I915_VM_BIND_H_
+#define _I915_VM_BIND_H_
+
+#include <stdint.h>
+
+void i915_vm_bind(int i915, uint32_t vm_id, uint64_t va, uint32_t handle,
+		  uint64_t offset, uint64_t length, uint64_t flags,
+		  uint32_t syncobj, uint64_t fence_value);
+void i915_vm_unbind(int i915, uint32_t vm_id, uint64_t va, uint64_t length);
+int i915_vm_bind_version(int i915);
+
+#endif /* _I915_VM_BIND_ */
diff --git a/lib/meson.build b/lib/meson.build
index cef2d0ff3..4cb74e85c 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -14,6 +14,7 @@ lib_sources = [
 	'i915/intel_mocs.c',
 	'i915/i915_blt.c',
 	'i915/i915_crc.c',
+	'i915/i915_vm_bind.c',
 	'igt_collection.c',
 	'igt_color_encoding.c',
 	'igt_crc.c',
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 06/14] lib/vm_bind: Add __prime_handle_to_fd()
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (4 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 05/14] lib/vm_bind: Add vm_bind specific library functions Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 07/14] tests/i915/vm_bind: Add vm_bind sanity test Niranjana Vishwanathapura
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

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

v2: Rename prime_handle_to_fd_no_assert() to __prime_handle_to_fd()

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 lib/ioctl_wrappers.c    | 39 +++++++++++++++++++++++++++++++++------
 lib/ioctl_wrappers.h    |  1 +
 tests/i915/gem_pwrite.c | 16 +---------------
 tests/prime_mmap.c      | 26 ++++----------------------
 4 files changed, 39 insertions(+), 43 deletions(-)

diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index ac37b6bb4..db9cbb724 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:
  * @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 success, 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(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(fd, handle, DRM_CLOEXEC, &dmabuf), 0);
+
+	return dmabuf;
 }
 
 /**
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index 223cd9160..66faa2755 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(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/i915/gem_pwrite.c b/tests/i915/gem_pwrite.c
index 6e3f833cd..f4fe069ca 100644
--- a/tests/i915/gem_pwrite.c
+++ b/tests/i915/gem_pwrite.c
@@ -293,19 +293,6 @@ struct ufd_thread {
 	int err;
 };
 
-static int __prime_handle_to_fd(int fd, uint32_t handle)
-{
-	struct drm_prime_handle args;
-
-	memset(&args, 0, sizeof(args));
-	args.handle = handle;
-	args.flags = DRM_CLOEXEC;
-	args.fd = -1;
-
-	ioctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
-	return args.fd;
-}
-
 static uint32_t dmabuf_create_handle(int i915, int vgem)
 {
 	struct vgem_bo scratch;
@@ -317,8 +304,7 @@ static uint32_t dmabuf_create_handle(int i915, int vgem)
 	scratch.bpp = 32;
 	vgem_create(vgem, &scratch);
 
-	dmabuf = __prime_handle_to_fd(vgem, scratch.handle);
-	if (dmabuf < 0)
+	if (__prime_handle_to_fd(vgem, scratch.handle, DRM_CLOEXEC, &dmabuf))
 		return 0;
 
 	handle = prime_fd_to_handle(i915, dmabuf);
diff --git a/tests/prime_mmap.c b/tests/prime_mmap.c
index bc19f68c9..432e85763 100644
--- a/tests/prime_mmap.c
+++ b/tests/prime_mmap.c
@@ -298,24 +298,6 @@ test_dup(uint32_t region, uint64_t 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, uint64_t 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(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, uint64_t size)
 	/* Test for invalid flags */
 	igt_assert(__gem_create_in_memory_regions(fd, &handle, &size, region) == 0);
 	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(fd, handle, invalid_flags[i], &dma_buf_fd);
 		igt_assert_eq(errno, EINVAL);
 		errno = 0;
 	}
@@ -386,7 +368,7 @@ test_errors(uint32_t region, uint64_t size)
 	igt_assert(__gem_create_in_memory_regions(fd, &handle, &size, region) == 0);
 	fill_bo(handle, size);
 	gem_close(fd, handle);
-	prime_handle_to_fd_no_assert(handle, DRM_CLOEXEC, &dma_buf_fd);
+	__prime_handle_to_fd(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] 19+ messages in thread

* [igt-dev] [PATCH i-g-t v8 07/14] tests/i915/vm_bind: Add vm_bind sanity test
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (5 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 06/14] lib/vm_bind: Add __prime_handle_to_fd() Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 08/14] tests/i915/vm_bind: Add basic VM_BIND test support Niranjana Vishwanathapura
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

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

v2: Add more input validity tests
    Add sanity test to fast-feedback.testlist
v3: Add only basic-smem subtest to fast-feedback.testlist
v4: Use gem_create_ext to create vm private objects,
    Ensure vm private objects are only allowed in vm_bind mode,
    Use library routine i915_vm_bind_version()
v5: Add execbuf3 sanity tests, use mr->gtt_alignment,
    add non-recoverable context sanity test
v6: Add more execbuf3 sanity tests
v7: Port as per uapi reserved field changes
v8: Validate partial binding

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_vm_bind_sanity.c      | 357 ++++++++++++++++++++++++++
 tests/intel-ci/fast-feedback.testlist |   1 +
 tests/meson.build                     |   1 +
 3 files changed, 359 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 000000000..361fdeb12
--- /dev/null
+++ b/tests/i915/i915_vm_bind_sanity.c
@@ -0,0 +1,357 @@
+// 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 <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+
+#include "i915/gem.h"
+#include "i915/gem_create.h"
+#include "i915/gem_vm.h"
+#include "i915/i915_vm_bind.h"
+#include "intel_allocator.h"
+#include "igt.h"
+#include "igt_syncobj.h"
+
+#define PAGE_SIZE   4096
+#define SZ_64K      (16 * PAGE_SIZE)
+#define SZ_2M       (512 * PAGE_SIZE)
+
+IGT_TEST_DESCRIPTION("Sanity test vm_bind related interfaces");
+
+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
+__vm_bind(int fd, uint32_t vm_id, uint32_t handle, uint64_t start, uint64_t offset,
+	  uint64_t length, uint64_t flags, uint64_t rsvd_0, uint64_t rsvd_1,
+	  struct drm_i915_gem_timeline_fence *fence, uint64_t extensions)
+{
+	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;
+	bind.rsvd[0] = rsvd_0;
+	bind.rsvd[1] = rsvd_1;
+	bind.extensions = extensions;
+	if (fence)
+		bind.fence = *fence;
+
+	return __gem_vm_bind(fd, &bind);
+}
+
+static inline void
+vm_bind(int fd, uint32_t vm_id, uint32_t handle, uint64_t start,
+	uint64_t offset, uint64_t length,
+	struct drm_i915_gem_timeline_fence *fence)
+{
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, start, offset,
+				length, 0, 0, 0, fence, 0), 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
+__vm_unbind(int fd, uint32_t vm_id, uint64_t start, uint64_t length, uint32_t pad,
+	    uint64_t flags, uint64_t rsvd_0, uint64_t rsvd_1, uint64_t extensions)
+{
+	struct drm_i915_gem_vm_unbind unbind;
+
+	memset(&unbind, 0, sizeof(unbind));
+	unbind.vm_id = vm_id;
+	unbind.pad = pad;
+	unbind.flags = flags;
+	unbind.rsvd[0] = rsvd_0;
+	unbind.rsvd[1] = rsvd_1;
+	unbind.start = start;
+	unbind.length = length;
+	unbind.extensions = extensions;
+
+	return __gem_vm_unbind(fd, &unbind);
+}
+
+static inline void
+vm_unbind(int fd, uint32_t vm_id, uint64_t start, uint64_t length, uint64_t flags)
+{
+	igt_assert_eq(__vm_unbind(fd, vm_id, start, length, 0, 0, 0, 0, 0), 0);
+}
+
+static inline int
+__execbuf3(int fd, uint32_t ctx_id, uint32_t engine_idx, uint64_t batch_addresses,
+	   uint64_t flags, uint64_t fence_count, uint64_t fences, uint64_t rsvd,
+	   uint64_t extensions)
+{
+	struct drm_i915_gem_execbuffer3 execbuf3;
+
+	memset(&execbuf3, 0, sizeof(execbuf3));
+	execbuf3.ctx_id = ctx_id;
+	execbuf3.engine_idx = engine_idx;
+	execbuf3.batch_address = batch_addresses;
+	execbuf3.flags = flags;
+	execbuf3.fence_count = fence_count;
+	execbuf3.timeline_fences = fences;
+	execbuf3.rsvd = rsvd;
+	execbuf3.extensions = extensions;
+
+	return __gem_execbuf3(fd, &execbuf3);
+}
+
+static void basic(int fd, const struct gem_memory_region *mr)
+{
+	uint32_t vm_id, vm_id2, vm_id_exec_mode, handle;
+	struct drm_i915_gem_create_ext_memory_regions setparam_region = {
+		.base = { .name = I915_GEM_CREATE_EXT_MEMORY_REGIONS },
+		.regions = to_user_pointer(&mr->ci),
+		.num_regions = 1,
+	};
+	struct drm_i915_gem_timeline_fence fence = {
+		.handle = syncobj_create(fd, 0),
+		.flags = I915_TIMELINE_FENCE_SIGNAL,
+		.value = 0,
+	};
+	struct drm_i915_gem_timeline_fence exec_fence = {
+		.handle = syncobj_create(fd, 0),
+		.flags = I915_TIMELINE_FENCE_SIGNAL,
+		.value = 0,
+	};
+	struct drm_i915_gem_create_ext_vm_private vm_priv = {
+		.base = { .name = I915_GEM_CREATE_EXT_VM_PRIVATE },
+	};
+	struct drm_i915_gem_context_param param = {
+		.param = I915_CONTEXT_PARAM_RECOVERABLE,
+		.value = 0,
+	};
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	const struct intel_execution_engine2 *e;
+	struct drm_i915_gem_exec_object2 obj;
+	uint64_t pg_size = mr->gtt_alignment;
+	uint64_t ahnd, va, size = pg_size * 4;
+	const intel_ctx_t *ctx;
+	int dmabuf;
+
+	ahnd = intel_allocator_open_full(fd, 1, 0, 0,
+					 INTEL_ALLOCATOR_RANDOM,
+					 ALLOC_STRATEGY_HIGH_TO_LOW,
+					 pg_size);
+
+	vm_id = gem_vm_create_in_vm_bind_mode(fd);
+	handle = gem_create_ext(fd, size, 0, &setparam_region.base);
+	va = CANONICAL(get_offset(ahnd, handle, size, 0));
+
+	/* Bind and unbind */
+	vm_bind(fd, vm_id, handle, va, 0, size, NULL);
+	vm_unbind(fd, vm_id, va, size, 0);
+
+	/* Partial binds */
+	vm_bind(fd, vm_id, handle, va, 0, size / 2, NULL);
+	vm_unbind(fd, vm_id, va, size / 2, 0);
+	vm_bind(fd, vm_id, handle, va, size / 2, size / 2, NULL);
+	vm_unbind(fd, vm_id, va, size / 2, 0);
+
+	/* Bind with out fence */
+	vm_bind(fd, vm_id, handle, va, 0, size, &fence);
+	vm_unbind(fd, vm_id, va, size, 0);
+
+	/* Aliasing bind and unbind */
+	vm_bind(fd, vm_id, handle, va, 0, size, NULL);
+	vm_bind(fd, vm_id, handle, va + SZ_2M, 0, size, NULL);
+	vm_unbind(fd, vm_id, va, size, 0);
+	vm_unbind(fd, vm_id, va + SZ_2M, size, 0);
+
+	/* MBZ fields are not 0 */
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0x10, 0, 0, NULL, 0), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0, 0x10, 0, NULL, 0), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0, 0, 0x10, NULL, 0), -EINVAL);
+	fence.flags |= I915_TIMELINE_FENCE_WAIT;
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0, 0, 0, &fence, 0), -EINVAL);
+	fence.flags |= 0x1000;
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0, 0, 0, &fence, 0), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0, 0, 0, NULL, to_user_pointer(&obj)), -EINVAL);
+	vm_bind(fd, vm_id, handle, va, 0, size, NULL);
+	igt_assert_eq(__vm_unbind(fd, vm_id, va, size, 0x10, 0, 0, 0, 0), -EINVAL);
+	igt_assert_eq(__vm_unbind(fd, vm_id, va, size, 0, 0x10, 0, 0, 0), -EINVAL);
+	igt_assert_eq(__vm_unbind(fd, vm_id, va, size, 0, 0, 0x10, 0, 0), -EINVAL);
+	igt_assert_eq(__vm_unbind(fd, vm_id, va, size, 0, 0, 0, 0x10, 0), -EINVAL);
+	igt_assert_eq(__vm_unbind(fd, vm_id, va, size, 0, 0, 0, 0, to_user_pointer(&obj)), -EINVAL);
+	vm_unbind(fd, vm_id, va, size, 0);
+
+	/* Invalid handle */
+	igt_assert_eq(__vm_bind(fd, vm_id, handle + 10, va, 0, size, 0, 0, 0, NULL, 0), -ENOENT);
+
+	/* Invalid mapping range */
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, 0, 0, 0, 0, NULL, 0), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, pg_size, size, 0, 0, 0, NULL, 0), -EINVAL);
+
+	/* Unaligned binds */
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va + 0x10, 0, size, 0, 0, 0, NULL, 0), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, pg_size / 2, pg_size, 0, 0, 0, NULL, 0), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, pg_size / 2, 0, 0, 0, NULL, 0), -EINVAL);
+
+	/* range overflow binds */
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, pg_size, -pg_size, 0, 0, 0, NULL, 0), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, pg_size * 2, -pg_size, 0, 0, 0, NULL, 0), -EINVAL);
+
+	/* re-bind VA range without unbinding */
+	vm_bind(fd, vm_id, handle, va, 0, size, NULL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0, 0, 0, NULL, 0), -EEXIST);
+	vm_unbind(fd, vm_id, va, size, 0);
+
+	/* unbind a non-existing mapping */
+	igt_assert_eq(__vm_bind(fd, vm_id, 0, va + SZ_2M, 0, size, 0, 0, 0, NULL, 0), -ENOENT);
+
+	/* unbind with length mismatch */
+	vm_bind(fd, vm_id, handle, va, 0, size, NULL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size * 2, 0, 0, 0, NULL, 0), -EINVAL);
+	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(__vm_bind(fd, vm_id_exec_mode, handle, va, 0, size, 0, 0, 0, NULL, 0), -EOPNOTSUPP);
+
+	/* vm_bind mode with the default recoverable context */
+	ctx = intel_ctx_create_all_physical(fd);
+	gem_context_set_vm(fd, ctx->id, vm_id);
+	param.ctx_id = ctx->id;
+	igt_assert_eq(__gem_context_get_param(fd, &param), -EINVAL);
+	intel_ctx_destroy(fd, ctx);
+
+	/* create context, make it non-recoverable and assign vm_bind vm */
+	ctx = intel_ctx_create_all_physical(fd);
+	param.ctx_id = ctx->id;
+	gem_context_set_param(fd, &param);
+	gem_context_set_vm(fd, ctx->id, vm_id);
+	(void)gem_context_get_vm(fd, ctx->id);
+
+	/* vm_bind mode with legacy execbuf */
+	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);
+
+	/* vm_bind mode with execbuf3 */
+	gem_write(fd, handle, 0, &bbe, sizeof(bbe));
+	vm_bind(fd, vm_id, handle, va, 0, size, NULL);
+	/* grab any engine */
+	for_each_ctx_engine(fd, ctx, e)
+		break;
+
+	igt_assert_eq(__execbuf3(fd, ctx->id, e->flags, va, 0, 0, 0, 0, 0), 0);
+	igt_assert_eq(__execbuf3(fd, ctx->id, e->flags, va, 0, 1, to_user_pointer(&exec_fence), 0, 0), 0);
+	igt_assert(syncobj_timeline_wait(fd, &exec_fence.handle, (uint64_t *)&exec_fence.value, 1,
+					 gettime_ns() + (2 * NSEC_PER_SEC),
+					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+
+	/* execbuf3 with non-vm_bind mode */
+	igt_assert_eq(__execbuf3(fd, 0, e->flags, va, 0, 0, 0, 0, 0), -EOPNOTSUPP);
+
+	/* execbuf3 MBZ fields are not 0 */
+	igt_assert_eq(__execbuf3(fd, ctx->id, e->flags, va, 0x10, 0, 0, 0, 0), -EINVAL);
+	igt_assert_eq(__execbuf3(fd, ctx->id, e->flags, va, 0, 0, 0, 0x10, 0), -EINVAL);
+	igt_assert_eq(__execbuf3(fd, ctx->id, e->flags, va, 0, 0, 0, 0, 0x10), -EINVAL);
+	exec_fence.flags |= 0x100;
+	igt_assert_eq(__execbuf3(fd, ctx->id, e->flags, va, 0, 1, to_user_pointer(&exec_fence), 0, 0), -EINVAL);
+
+	vm_unbind(fd, vm_id, va, size, 0);
+	intel_ctx_destroy(fd, ctx);
+	gem_vm_destroy(fd, vm_id_exec_mode);
+	gem_close(fd, handle);
+
+	/* validate VM private objects */
+	setparam_region.base.next_extension = to_user_pointer(&vm_priv);
+	igt_assert_eq(__gem_create_ext(fd, &size, 0, &handle,
+				       &setparam_region.base), -ENOENT);
+	vm_priv.rsvd = 0x10;
+	igt_assert_eq(__gem_create_ext(fd, &size, 0, &handle,
+				       &setparam_region.base), -EINVAL);
+	vm_id2 = gem_vm_create(fd);
+	vm_priv.rsvd = 0;
+	vm_priv.vm_id = vm_id2;
+	igt_assert_eq(__gem_create_ext(fd, &size, 0, &handle,
+				       &setparam_region.base), -EINVAL);
+	gem_vm_destroy(fd, vm_id2);
+
+	vm_id2 = gem_vm_create_in_vm_bind_mode(fd);
+	vm_priv.vm_id = vm_id2;
+	handle = gem_create_ext(fd, size, 0, &setparam_region.base);
+
+	igt_assert_eq(__prime_handle_to_fd(fd, handle, DRM_CLOEXEC, &dmabuf), -EINVAL);
+	igt_assert_eq(__vm_bind(fd, vm_id, handle, va, 0, size, 0, 0, 0, NULL, 0), -EINVAL);
+	vm_bind(fd, vm_id2, handle, va, 0, size, NULL);
+	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);
+	syncobj_destroy(fd, exec_fence.handle);
+	intel_allocator_close(ahnd);
+}
+
+igt_main
+{
+	int fd;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		igt_require(i915_vm_bind_version(fd) == 1);
+	}
+
+	igt_describe("Basic vm_bind sanity test");
+	igt_subtest_with_dynamic("basic") {
+		for_each_memory_region(r, fd) {
+			if (r->ci.memory_instance)
+				continue;
+
+			igt_dynamic_f("%s", r->name)
+				basic(fd, r);
+		}
+	}
+
+	igt_fixture {
+		close(fd);
+	}
+
+	igt_exit();
+}
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index f57f8ff3b..3ae32422a 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -54,6 +54,7 @@ igt@i915_getparams_basic@basic-eu-total
 igt@i915_getparams_basic@basic-subslice-total
 igt@i915_hangman@error-state-basic
 igt@i915_pciid
+igt@i915_vm_bind_sanity@basic
 igt@kms_addfb_basic@addfb25-bad-modifier
 igt@kms_addfb_basic@addfb25-framebuffer-vs-set-tiling
 igt@kms_addfb_basic@addfb25-modifier-no-flag
diff --git a/tests/meson.build b/tests/meson.build
index 5c052e733..77f6f92ba 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -226,6 +226,7 @@ i915_progs = [
 	'i915_query',
 	'i915_selftest',
 	'i915_suspend',
+	'i915_vm_bind_sanity',
 	'kms_big_fb',
 	'kms_big_joiner' ,
 	'kms_busy',
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 08/14] tests/i915/vm_bind: Add basic VM_BIND test support
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (6 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 07/14] tests/i915/vm_bind: Add vm_bind sanity test Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 09/14] tests/i915/vm_bind: Add userptr subtest Niranjana Vishwanathapura
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

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.

v2: Add basic test to fast-feedback.testlist
v3: Run all tests for different memory types,
    pass VA instead of an array for batch_address
v4: Iterate for memory region types instead of hardcoding,
    use i915_vm_bind library functions
v5: Validate synchronous vm_bind, require blt engine,
    use mr->gtt_alignment instead of HAS_64K_PAGES,
    change info to debug messages, remove igt_collection usage,
    fix dg2 alignment issue
v6: Port as per uapi reserved field changes

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_vm_bind_basic.c       | 561 ++++++++++++++++++++++++++
 tests/intel-ci/fast-feedback.testlist |   1 +
 tests/meson.build                     |   1 +
 3 files changed, 563 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 000000000..a7016c4b9
--- /dev/null
+++ b/tests/i915/i915_vm_bind_basic.c
@@ -0,0 +1,561 @@
+// 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 "i915/i915_vm_bind.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 EXEC_FENCE   0
+#define BATCH_FENCE  1
+#define SRC_FENCE    2
+#define DST_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_SKIP_UNBIND      BIT(0)
+#define TEST_SHARE_VM         BIT(1)
+#define TEST_SYNC_BIND        BIT(2)
+
+#define do_unbind(cfg)      (!((cfg)->flags & TEST_SKIP_UNBIND))
+#define do_share_vm(cfg)    ((cfg)->flags & TEST_SHARE_VM)
+#define do_sync_bind(cfg)   ((cfg)->flags & TEST_SYNC_BIND)
+
+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 vm_bind(int fd, uint32_t vm_id, struct mapping *m,
+			   struct drm_i915_gem_timeline_fence *fence)
+{
+	uint32_t syncobj = 0;
+
+	if (fence) {
+		syncobj = syncobj_create(fd, 0);
+
+		fence->handle = syncobj;
+		fence->flags = I915_TIMELINE_FENCE_WAIT;
+		fence->value = 0;
+	}
+
+	igt_debug("VM_BIND vm:0x%x h:0x%x v:0x%lx o:0x%lx l:0x%lx f:0x%lx\n",
+		  vm_id, m->obj, m->va, m->offset, m->length, m->flags);
+	i915_vm_bind(fd, vm_id, m->va, m->obj, m->offset, m->length, m->flags, syncobj, 0);
+}
+
+static inline void vm_unbind(int fd, uint32_t vm_id, struct mapping *m)
+{
+	/* Object handle is not required during unbind */
+	igt_debug("VM_UNBIND vm:0x%x v:0x%lx l:0x%lx\n", vm_id, m->va, m->length);
+	i915_vm_unbind(fd, vm_id, m->va, m->length);
+}
+
+static void debug_dump_buffer(void *buf, uint32_t size,
+			      const char *str, bool full)
+{
+	uint32_t i = 0;
+
+	igt_debug("Printing %s size 0x%x\n", str, 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;
+
+	*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);
+	*cmd++ = upper_32_bits(dst);
+	*cmd++ = 0;
+	*cmd++ = PAGE_SIZE;
+	*cmd++ = lower_32_bits(src);
+	*cmd++ = upper_32_bits(src);
+
+	*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 size,
+		       uint32_t ctx_id, void *batch_addr, unsigned int eb_flags,
+		       struct drm_i915_gem_timeline_fence *fence,
+		       uint64_t fence_count)
+{
+	uint32_t len, buf[MAX_BATCH_DWORD] = { 0 };
+	struct drm_i915_gem_execbuffer3 execbuf;
+
+	len = gem_linear_fast_blt(buf, src, dst, size);
+
+	memcpy(batch_addr, (void *)buf, len);
+	debug_dump_buffer(buf, len, "batch", true);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.ctx_id = ctx_id;
+	execbuf.batch_address = to_user_pointer(batch_addr);
+	execbuf.engine_idx = eb_flags;
+	execbuf.fence_count = fence_count;
+	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 va_delta,
+			  uint32_t delta, 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],
+			  uint64_t fence_count)
+{
+	uint32_t i;
+
+	for (i = 0; i < num_ctxts; i++) {
+		igt_debug("Issuing gem copy on ctx 0x%x\n", ctx[i]->id);
+		__gem_copy(fd, src + (i * va_delta), dst + (i * va_delta), delta,
+			   ctx[i]->id, batch_addr[i], eb_flags, fence[i],  fence_count);
+	}
+}
+
+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_debug("gem copy completed on ctx 0x%x\n", ctx[i]->id);
+	}
+}
+
+static uint32_t create_obj(int fd, struct gem_memory_region *mr, uint32_t size, void **addr)
+{
+	uint32_t handle;
+
+	handle = gem_create_in_memory_region_list(fd, size, 0, &mr->ci, 1);
+	*addr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
+
+	return handle;
+}
+
+static void destroy_obj(int fd, uint32_t handle, uint32_t size, void *addr)
+{
+	igt_assert(gem_munmap(addr, size) == 0);
+	gem_close(fd, handle);
+}
+
+static void create_src_objs(int fd, struct gem_memory_region *mr, uint32_t src[],
+			    uint32_t size, uint32_t num_cmds, void *src_addr[])
+{
+	int i = 0;
+
+	if (!num_cmds)
+		return;
+
+	/* Create first src object always in memory region 'mr' */
+	src[i] = create_obj(fd, mr, size, &src_addr[i]);
+	igt_debug("Src (%s) obj 0x%x created\n", mr->name, src[i]);
+	num_cmds--;
+	i++;
+
+	if (!num_cmds)
+		return;
+
+	/* Create one src object in all other memory regions */
+	for_each_memory_region(r, fd) {
+		if (mr &&
+		    r->ci.memory_class == mr->ci.memory_class &&
+		    r->ci.memory_instance == mr->ci.memory_instance)
+			continue;
+
+		src[i] = create_obj(fd, r, size, &src_addr[i]);
+		igt_debug("Src (%s) obj 0x%x created\n", r->name, src[i]);
+		num_cmds--;
+		i++;
+	}
+
+	/* Create rest of the src objects in memory region 'mr' */
+	while (num_cmds) {
+		src[i] = create_obj(fd, mr, size, &src_addr[i]);
+		igt_debug("Src (%s) obj 0x%x created\n", mr->name, src[i]);
+		num_cmds--;
+		i++;
+	}
+}
+
+static void destroy_src_objs(int fd, struct gem_memory_region *mr, uint32_t src[],
+			     uint32_t size, uint32_t num_cmds, void *src_addr[])
+{
+	int i;
+
+	for (i = 0; i < num_cmds; i++) {
+		igt_debug("Closing src object 0x%x\n", src[i]);
+		destroy_obj(fd, src[i], size, src_addr[i]);
+	}
+}
+
+static uint32_t create_dst_obj(int fd, struct gem_memory_region *mr, uint32_t size, void **dst_addr)
+{
+	uint32_t dst = create_obj(fd, mr, size, dst_addr);
+
+	igt_debug("Dst (%s) obj 0x%x created\n", mr->name, dst);
+	return dst;
+}
+
+static void destroy_dst_obj(int fd, struct gem_memory_region *mr, uint32_t dst,
+			    uint32_t size, void *dst_addr)
+{
+	igt_debug("Closing dst object 0x%x\n", dst);
+	destroy_obj(fd, dst, size, dst_addr);
+}
+
+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,
+		     struct gem_memory_region *mr, uint32_t alignment,
+		     const struct intel_execution_engine2 *e)
+{
+	struct drm_i915_gem_timeline_fence exec_fence[MAX_CTXTS][NUM_FENCES] = { };
+	void *src_addr[MAX_CMDS] = { 0 }, *dst_addr = NULL;
+	uint32_t src[MAX_CMDS], dst, i, size = cfg->size;
+	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];
+	uint64_t src_va, dst_va, ahnd = 0;
+	bool share_vm = do_share_vm(cfg);
+	uint32_t delta, va_delta = SZ_2M;
+	void *batch_addr[MAX_CTXTS];
+	uint32_t batch[MAX_CTXTS];
+
+	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++) {
+		struct drm_i915_gem_context_param param = {
+			.param = I915_CONTEXT_PARAM_RECOVERABLE,
+			.value = 0,
+		};
+		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);
+		param.ctx_id = ctx[i]->id;
+		gem_context_set_param(fd, &param);
+		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, mr, src, size, num_cmds, src_addr);
+	dst = create_dst_obj(fd, mr, size, &dst_addr);
+
+	/*
+	 * mmap'ed addresses are PAGE_SIZE aligned. On platforms requiring
+	 * other alignment, use static addresses.
+	 */
+	if (num_cmds && (alignment == PAGE_SIZE)) {
+		src_va = to_user_pointer(src_addr[0]);
+		dst_va = to_user_pointer(dst_addr);
+	} else {
+		ahnd = intel_allocator_open_full(fd, 1, 0, 0,
+						 INTEL_ALLOCATOR_RANDOM,
+						 ALLOC_STRATEGY_HIGH_TO_LOW,
+						 alignment);
+		dst_va = CANONICAL(get_offset(ahnd, dst, size, 0));
+		if (num_cmds)
+			src_va = CANONICAL(get_offset(ahnd, src[0], size * num_cmds, 0));
+	}
+
+	pattern_fill_buf(src_addr, size, num_cmds, npages);
+
+	if (num_cmds)
+		debug_dump_buffer(src_addr[num_cmds - 1], size, "src_obj", false);
+
+	for (i = 0; i < num_ctxts; i++) {
+		batch[i] = gem_create_in_memory_regions(fd, PAGE_SIZE, REGION_SMEM);
+		igt_debug("Batch obj 0x%x created in region 0x%x:0x%x\n", batch[i],
+			  MEMORY_TYPE_FROM_REGION(REGION_SMEM), MEMORY_INSTANCE_FROM_REGION(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 va_offset = i * va_delta;
+		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 + va_offset, offset, delta, 0);
+		SET_MAP(map[i][DST_MAP], dst, dst_va + va_offset, offset, delta, 0);
+		SET_MAP(map[i][BATCH_MAP], batch[i], to_user_pointer(batch_addr[i]), 0, PAGE_SIZE, 0);
+	}
+
+	/* Bind the buffers to device page table */
+	for (i = 0; i < num_ctxts; i++) {
+		vm_bind(fd, vm_id[i], &map[i][BATCH_MAP],
+			do_sync_bind(cfg) ? NULL : &exec_fence[i][BATCH_FENCE]);
+		vm_bind(fd, vm_id[i], &map[i][DST_MAP],
+			do_sync_bind(cfg) ? NULL : &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++)
+			vm_bind(fd, vm_id[j], &map[j][SRC_MAP + i],
+				do_sync_bind(cfg) ? NULL : &exec_fence[j][SRC_FENCE]);
+
+		i915_gem_copy(fd, src_va, dst_va, va_delta, delta, size, ctx,
+			      num_ctxts, batch_addr, e->flags, exec_fence,
+			      do_sync_bind(cfg) ? 1 : NUM_FENCES);
+
+		i915_gem_sync(fd, ctx, num_ctxts, exec_fence);
+
+		for (j = 0; j < num_ctxts; j++) {
+			if (!do_sync_bind(cfg))
+				syncobj_destroy(fd, exec_fence[j][SRC_FENCE].handle);
+			if (do_unbind(cfg))
+				vm_unbind(fd, vm_id[j], &map[j][SRC_MAP + i]);
+		}
+	}
+	put_ahnd(ahnd);
+
+	/*
+	 * Unbind buffers from device page table.
+	 * If not, it should get unbound while freeing the buffer.
+	 */
+	for (i = 0; i < num_ctxts; i++) {
+		if (!do_sync_bind(cfg)) {
+			syncobj_destroy(fd, exec_fence[i][BATCH_FENCE].handle);
+			syncobj_destroy(fd, exec_fence[i][DST_FENCE].handle);
+		}
+		if (do_unbind(cfg)) {
+			vm_unbind(fd, vm_id[i], &map[i][BATCH_MAP]);
+			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]);
+	}
+
+	if (num_cmds)
+		debug_dump_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, mr, src, size, num_cmds, src_addr);
+	destroy_dst_obj(fd, mr, 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);
+}
+
+igt_main
+{
+	struct test_cfg *t, tests[] = {
+		{"basic", DEFAULT_BUFF_SIZE, 1, 1, 0},
+		{"multi_cmds", DEFAULT_BUFF_SIZE, MAX_CMDS, 1, 0},
+		{"skip_copy", DEFAULT_BUFF_SIZE, 0, 1, 0},
+		{"skip_unbind", DEFAULT_BUFF_SIZE, 1, 1, TEST_SKIP_UNBIND},
+		{"multi_ctxts", DEFAULT_BUFF_SIZE, 1, MAX_CTXTS, 0},
+		{"share_vm", DEFAULT_BUFF_SIZE, 1, MAX_CTXTS, TEST_SHARE_VM},
+		{"64K", SZ_64K, 1, 1, 0},
+		{"2M", SZ_2M, 1, 1, 0},
+		{"2M_sync_bind", SZ_2M, 1, 1, TEST_SYNC_BIND},
+		{ }
+	};
+	int fd;
+	struct intel_execution_engine2 *e;
+	const intel_ctx_t *ctx;
+	uint32_t alignment = 0;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		igt_require(gem_has_blt(fd));
+		igt_require(i915_vm_bind_version(fd) == 1);
+		ctx = intel_ctx_create_all_physical(fd);
+
+		/* Get max alignment required */
+		for_each_memory_region(r, fd)
+			alignment = max_t(uint32_t, alignment, r->gtt_alignment);
+
+		/* Get copy engine */
+		for_each_ctx_engine(fd, ctx, e)
+			if (e->class == I915_ENGINE_CLASS_COPY)
+				break;
+	}
+
+	for (t = tests; t->name; t++) {
+		igt_describe_f("VM_BIND %s", t->name);
+		igt_subtest_with_dynamic(t->name) {
+			for_each_memory_region(r, fd) {
+				struct test_cfg cfg = *t;
+
+				if (r->ci.memory_instance)
+					continue;
+
+				cfg.size = ALIGN(cfg.size, alignment);
+				cfg.size *= cfg.num_ctxts;
+				igt_dynamic_f("%s", r->name)
+					run_test(fd, ctx, &cfg, r, alignment, e);
+			}
+		}
+	}
+
+	igt_fixture {
+		intel_ctx_destroy(fd, ctx);
+		close(fd);
+	}
+
+	igt_exit();
+}
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index 3ae32422a..bdfde4b78 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -54,6 +54,7 @@ igt@i915_getparams_basic@basic-eu-total
 igt@i915_getparams_basic@basic-subslice-total
 igt@i915_hangman@error-state-basic
 igt@i915_pciid
+igt@i915_vm_bind_basic@basic-smem
 igt@i915_vm_bind_sanity@basic
 igt@kms_addfb_basic@addfb25-bad-modifier
 igt@kms_addfb_basic@addfb25-framebuffer-vs-set-tiling
diff --git a/tests/meson.build b/tests/meson.build
index 77f6f92ba..d1e07976f 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -226,6 +226,7 @@ i915_progs = [
 	'i915_query',
 	'i915_selftest',
 	'i915_suspend',
+	'i915_vm_bind_basic',
 	'i915_vm_bind_sanity',
 	'kms_big_fb',
 	'kms_big_joiner' ,
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 09/14] tests/i915/vm_bind: Add userptr subtest
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (7 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 08/14] tests/i915/vm_bind: Add basic VM_BIND test support Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 10/14] tests/i915/vm_bind: Add gem_exec3_basic test Niranjana Vishwanathapura
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Add userptr object type to vm_bind_basic test.

v2: Run all tests for userptr type
v3: Change info to debug messages, remove igt_collection usage
v4: only munmap non-userptr objects

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_vm_bind_basic.c | 59 +++++++++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 7 deletions(-)

diff --git a/tests/i915/i915_vm_bind_basic.c b/tests/i915/i915_vm_bind_basic.c
index a7016c4b9..cc5b65235 100644
--- a/tests/i915/i915_vm_bind_basic.c
+++ b/tests/i915/i915_vm_bind_basic.c
@@ -235,16 +235,26 @@ static uint32_t create_obj(int fd, struct gem_memory_region *mr, uint32_t size,
 {
 	uint32_t handle;
 
-	handle = gem_create_in_memory_region_list(fd, size, 0, &mr->ci, 1);
-	*addr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
+	if (!mr) {
+		igt_assert(posix_memalign(addr, SZ_2M * MAX_CTXTS, size) == 0);
+		gem_userptr(fd, *addr, size, 0, 0, &handle);
+	} else {
+		handle = gem_create_in_memory_region_list(fd, size, 0, &mr->ci, 1);
+		*addr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
+	}
 
 	return handle;
 }
 
-static void destroy_obj(int fd, uint32_t handle, uint32_t size, void *addr)
+static void destroy_obj(int fd, uint32_t handle, uint32_t size, void *addr, bool is_userptr)
 {
-	igt_assert(gem_munmap(addr, size) == 0);
+	if (!is_userptr)
+		igt_assert(gem_munmap(addr, size) == 0);
+
 	gem_close(fd, handle);
+
+	if (is_userptr)
+		free(addr);
 }
 
 static void create_src_objs(int fd, struct gem_memory_region *mr, uint32_t src[],
@@ -255,6 +265,14 @@ static void create_src_objs(int fd, struct gem_memory_region *mr, uint32_t src[]
 	if (!num_cmds)
 		return;
 
+	if (!mr) {
+		for (i = 0; i < num_cmds; i++) {
+			src[i] = create_obj(fd, NULL, size, &src_addr[i]);
+			igt_debug("Src (userptr) obj 0x%x created\n", src[i]);
+		}
+		return;
+	}
+
 	/* Create first src object always in memory region 'mr' */
 	src[i] = create_obj(fd, mr, size, &src_addr[i]);
 	igt_debug("Src (%s) obj 0x%x created\n", mr->name, src[i]);
@@ -293,7 +311,7 @@ static void destroy_src_objs(int fd, struct gem_memory_region *mr, uint32_t src[
 
 	for (i = 0; i < num_cmds; i++) {
 		igt_debug("Closing src object 0x%x\n", src[i]);
-		destroy_obj(fd, src[i], size, src_addr[i]);
+		destroy_obj(fd, src[i], size, src_addr[i], !mr);
 	}
 }
 
@@ -301,7 +319,7 @@ static uint32_t create_dst_obj(int fd, struct gem_memory_region *mr, uint32_t si
 {
 	uint32_t dst = create_obj(fd, mr, size, dst_addr);
 
-	igt_debug("Dst (%s) obj 0x%x created\n", mr->name, dst);
+	igt_debug("Dst (%s) obj 0x%x created\n", mr ? mr->name : "userptr", dst);
 	return dst;
 }
 
@@ -309,7 +327,7 @@ static void destroy_dst_obj(int fd, struct gem_memory_region *mr, uint32_t dst,
 			    uint32_t size, void *dst_addr)
 {
 	igt_debug("Closing dst object 0x%x\n", dst);
-	destroy_obj(fd, dst, size, dst_addr);
+	destroy_obj(fd, dst, size, dst_addr, !mr);
 }
 
 static void pattern_fill_buf(void *src_addr[], uint32_t size, uint32_t num_cmds, uint32_t npages)
@@ -499,6 +517,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;
+}
+
 igt_main
 {
 	struct test_cfg *t, tests[] = {
@@ -549,6 +586,14 @@ igt_main
 				igt_dynamic_f("%s", r->name)
 					run_test(fd, ctx, &cfg, r, alignment, e);
 			}
+
+			if (has_userptr(fd)) {
+				struct test_cfg cfg = *t;
+
+				/* Use NULL memory region for userptr */
+				igt_dynamic("userptr")
+					run_test(fd, ctx, &cfg, NULL, PAGE_SIZE, e);
+			}
 		}
 	}
 
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 10/14] tests/i915/vm_bind: Add gem_exec3_basic test
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (8 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 09/14] tests/i915/vm_bind: Add userptr subtest Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 11/14] tests/i915/vm_bind: Add gem_exec3_balancer test Niranjana Vishwanathapura
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Port gem_exec_basic to a new gem_exec3_basic test which
uses the newer execbuf3 ioctl.

v2: use i915_vm_bind library functions

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/gem_exec3_basic.c          | 139 ++++++++++++++++++++++++++
 tests/intel-ci/fast-feedback.testlist |   1 +
 tests/meson.build                     |   1 +
 3 files changed, 141 insertions(+)
 create mode 100644 tests/i915/gem_exec3_basic.c

diff --git a/tests/i915/gem_exec3_basic.c b/tests/i915/gem_exec3_basic.c
new file mode 100644
index 000000000..f3a7c7ad1
--- /dev/null
+++ b/tests/i915/gem_exec3_basic.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/** @file gem_exec3_basic.c
+ *
+ * Basic execbuf3 test.
+ * Ported from gem_exec_basic and made to work with
+ * vm_bind and execbuf3.
+ *
+ */
+
+#include "i915/gem.h"
+#include "i915/i915_vm_bind.h"
+#include "igt.h"
+#include "igt_collection.h"
+#include "igt_syncobj.h"
+
+#include "i915/gem_create.h"
+#include "i915/gem_vm.h"
+
+IGT_TEST_DESCRIPTION("Basic sanity check of execbuf3-ioctl rings.");
+
+#define BATCH_VA	0xa0000000
+#define PAGE_SIZE	4096
+
+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 uint32_t batch_create(int fd, uint64_t *batch_size, uint32_t region)
+{
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	uint32_t handle;
+
+	igt_assert(__gem_create_in_memory_regions(fd, &handle, batch_size, region) == 0);
+	gem_write(fd, handle, 0, &bbe, sizeof(bbe));
+
+	return handle;
+}
+
+igt_main
+{
+	const struct intel_execution_engine2 *e;
+	struct drm_i915_query_memory_regions *query_info;
+	struct igt_collection *regions, *set;
+	const intel_ctx_t *base_ctx, *ctx;
+	struct drm_i915_gem_context_param param = {
+		.param = I915_CONTEXT_PARAM_RECOVERABLE,
+		.value = 0,
+	};
+	uint32_t vm_id;
+	int fd = -1;
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		base_ctx = intel_ctx_create_all_physical(fd);
+
+		igt_require_gem(fd);
+		igt_require(i915_vm_bind_version(fd) == 1);
+		igt_fork_hang_detector(fd);
+
+		vm_id = gem_vm_create_in_vm_bind_mode(fd);
+		ctx  = intel_ctx_create(fd, &base_ctx->cfg);
+		param.ctx_id = ctx->id;
+		gem_context_set_param(fd, &param);
+		gem_context_set_vm(fd, ctx->id, vm_id);
+
+		query_info = gem_get_query_memory_regions(fd);
+		igt_assert(query_info);
+
+		set = get_memory_region_set(query_info,
+					    I915_SYSTEM_MEMORY,
+					    I915_DEVICE_MEMORY);
+	}
+
+	igt_describe("Check basic functionality of GEM_EXECBUFFER3 ioctl on every"
+		     " ring and iterating over memory regions.");
+	igt_subtest_with_dynamic("basic") {
+		for_each_combination(regions, 1, set) {
+			struct drm_i915_gem_timeline_fence exec_fence[GEM_MAX_ENGINES][2] = { };
+			char *sub_name = memregion_dynamic_subtest_name(regions);
+			uint32_t region = igt_collection_get_value(regions, 0);
+			uint32_t bind_syncobj, exec_syncobj[GEM_MAX_ENGINES];
+			uint64_t fence_value[GEM_MAX_ENGINES] = { };
+			uint64_t batch_size = PAGE_SIZE;
+			uint32_t handle, idx = 0;
+
+			handle = batch_create(fd, &batch_size, region);
+			bind_syncobj = syncobj_create(fd, 0);
+			i915_vm_bind(fd, vm_id, BATCH_VA, handle, 0, batch_size, 0, bind_syncobj, 0);
+
+			for_each_ctx_engine(fd, ctx, e) {
+				igt_dynamic_f("%s-%s", e->name, sub_name) {
+					struct drm_i915_gem_execbuffer3 execbuf = {
+						.ctx_id = ctx->id,
+						.batch_address = BATCH_VA,
+						.engine_idx = e->flags,
+						.fence_count = 2,
+						.timeline_fences = to_user_pointer(&exec_fence[idx]),
+					};
+
+					exec_syncobj[idx] = syncobj_create(fd, 0);
+					exec_fence[idx][0].handle = bind_syncobj;
+					exec_fence[idx][0].flags = I915_TIMELINE_FENCE_WAIT;
+					exec_fence[idx][1].handle = exec_syncobj[idx];
+					exec_fence[idx][1].flags = I915_TIMELINE_FENCE_SIGNAL;
+					idx++;
+
+					gem_execbuf3(fd, &execbuf);
+				}
+			}
+
+			igt_assert(syncobj_timeline_wait(fd, exec_syncobj, fence_value, idx,
+							 gettime_ns() + (2 * NSEC_PER_SEC),
+							 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+			while (idx)
+				syncobj_destroy(fd, exec_syncobj[--idx]);
+			syncobj_destroy(fd, bind_syncobj);
+			i915_vm_unbind(fd, vm_id, BATCH_VA, batch_size);
+			gem_close(fd, handle);
+			free(sub_name);
+		}
+	}
+
+	igt_fixture {
+		intel_ctx_destroy(fd, ctx);
+		gem_vm_destroy(fd, vm_id);
+		free(query_info);
+		igt_collection_destroy(set);
+		igt_stop_hang_detector();
+		intel_ctx_destroy(fd, base_ctx);
+		close(fd);
+	}
+}
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index bdfde4b78..8380834c1 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -28,6 +28,7 @@ igt@gem_exec_fence@nb-await
 igt@gem_exec_gttfill@basic
 igt@gem_exec_parallel@engines
 igt@gem_exec_store@basic
+igt@gem_exec3_basic@basic
 igt@gem_flink_basic@bad-flink
 igt@gem_flink_basic@bad-open
 igt@gem_flink_basic@basic
diff --git a/tests/meson.build b/tests/meson.build
index d1e07976f..6c1564e85 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -148,6 +148,7 @@ i915_progs = [
 	'gem_exec_store',
 	'gem_exec_suspend',
 	'gem_exec_whisper',
+	'gem_exec3_basic',
 	'gem_fd_exhaustion',
 	'gem_fence_thrash',
 	'gem_fence_upload',
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 11/14] tests/i915/vm_bind: Add gem_exec3_balancer test
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (9 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 10/14] tests/i915/vm_bind: Add gem_exec3_basic test Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 12/14] tests/i915/vm_bind: Add gem_lmem_swapping@vm_bind sub test Niranjana Vishwanathapura
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

To test parallel submissions support in execbuf3, port the subtest
gem_exec_balancer@parallel-ordering to a new gem_exec3_balancer test
and switch to execbuf3 ioctl.

v2: use i915_vm_bind library functions
v3: Remove unwanted gem_set_domain()
v4: Require guc submission

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/gem_exec3_balancer.c | 470 ++++++++++++++++++++++++++++++++
 tests/meson.build               |   7 +
 2 files changed, 477 insertions(+)
 create mode 100644 tests/i915/gem_exec3_balancer.c

diff --git a/tests/i915/gem_exec3_balancer.c b/tests/i915/gem_exec3_balancer.c
new file mode 100644
index 000000000..8ec05d902
--- /dev/null
+++ b/tests/i915/gem_exec3_balancer.c
@@ -0,0 +1,470 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/** @file gem_exec3_balancer.c
+ *
+ * Load balancer tests with execbuf3.
+ * Ported from gem_exec_balancer and made to work with
+ * vm_bind and execbuf3.
+ *
+ */
+
+#include <poll.h>
+
+#include "i915/gem.h"
+#include "i915/i915_vm_bind.h"
+#include "i915/gem_engine_topology.h"
+#include "i915/gem_create.h"
+#include "i915/gem_vm.h"
+#include "igt.h"
+#include "igt_gt.h"
+#include "igt_perf.h"
+#include "igt_syncobj.h"
+
+IGT_TEST_DESCRIPTION("Exercise in-kernel load-balancing with execbuf3");
+
+#define INSTANCE_COUNT (1 << I915_PMU_SAMPLE_INSTANCE_BITS)
+
+static bool has_class_instance(int i915, uint16_t class, uint16_t instance)
+{
+	int fd;
+
+	fd = perf_i915_open(i915, I915_PMU_ENGINE_BUSY(class, instance));
+	if (fd >= 0) {
+		close(fd);
+		return true;
+	}
+
+	return false;
+}
+
+static struct i915_engine_class_instance *
+list_engines(int i915, uint32_t class_mask, unsigned int *out)
+{
+	unsigned int count = 0, size = 64;
+	struct i915_engine_class_instance *engines;
+
+	engines = malloc(size * sizeof(*engines));
+	igt_assert(engines);
+
+	for (enum drm_i915_gem_engine_class class = I915_ENGINE_CLASS_RENDER;
+	     class_mask;
+	     class++, class_mask >>= 1) {
+		if (!(class_mask & 1))
+			continue;
+
+		for (unsigned int instance = 0;
+		     instance < INSTANCE_COUNT;
+		     instance++) {
+			if (!has_class_instance(i915, class, instance))
+				continue;
+
+			if (count == size) {
+				size *= 2;
+				engines = realloc(engines,
+						  size * sizeof(*engines));
+				igt_assert(engines);
+			}
+
+			engines[count++] = (struct i915_engine_class_instance){
+				.engine_class = class,
+				.engine_instance = instance,
+			};
+		}
+	}
+
+	if (!count) {
+		free(engines);
+		engines = NULL;
+	}
+
+	*out = count;
+	return engines;
+}
+
+static bool has_perf_engines(int i915)
+{
+	return i915_perf_type_id(i915);
+}
+
+static intel_ctx_cfg_t
+ctx_cfg_for_engines(const struct i915_engine_class_instance *ci,
+		    unsigned int count)
+{
+	intel_ctx_cfg_t cfg = { };
+	unsigned int i;
+
+	for (i = 0; i < count; i++)
+		cfg.engines[i] = ci[i];
+	cfg.num_engines = count;
+
+	return cfg;
+}
+
+static const intel_ctx_t *
+ctx_create_engines(int i915, const struct i915_engine_class_instance *ci,
+		   unsigned int count)
+{
+	intel_ctx_cfg_t cfg = ctx_cfg_for_engines(ci, count);
+	return intel_ctx_create(i915, &cfg);
+}
+
+static void check_bo(int i915, uint32_t handle, unsigned int expected)
+{
+	uint32_t *map;
+
+	map = gem_mmap__cpu(i915, handle, 0, 4096, PROT_READ);
+	igt_assert_eq(map[0], expected);
+	munmap(map, 4096);
+}
+
+static struct drm_i915_query_engine_info *query_engine_info(int i915)
+{
+	struct drm_i915_query_engine_info *engines;
+
+#define QUERY_SIZE	0x4000
+	engines = malloc(QUERY_SIZE);
+	igt_assert(engines);
+	memset(engines, 0, QUERY_SIZE);
+	igt_assert(!__gem_query_engines(i915, engines, QUERY_SIZE));
+#undef QUERY_SIZE
+
+	return engines;
+}
+
+/* This function only works if siblings contains all instances of a class */
+static void logical_sort_siblings(int i915,
+				  struct i915_engine_class_instance *siblings,
+				  unsigned int count)
+{
+	struct i915_engine_class_instance *sorted;
+	struct drm_i915_query_engine_info *engines;
+	unsigned int i, j;
+
+	sorted = calloc(count, sizeof(*sorted));
+	igt_assert(sorted);
+
+	engines = query_engine_info(i915);
+
+	for (j = 0; j < count; ++j) {
+		for (i = 0; i < engines->num_engines; ++i) {
+			if (siblings[j].engine_class ==
+			    engines->engines[i].engine.engine_class &&
+			    siblings[j].engine_instance ==
+			    engines->engines[i].engine.engine_instance) {
+				uint16_t logical_instance =
+					engines->engines[i].logical_instance;
+
+				igt_assert(logical_instance < count);
+				igt_assert(!sorted[logical_instance].engine_class);
+				igt_assert(!sorted[logical_instance].engine_instance);
+
+				sorted[logical_instance] = siblings[j];
+				break;
+			}
+		}
+		igt_assert(i != engines->num_engines);
+	}
+
+	memcpy(siblings, sorted, sizeof(*sorted) * count);
+	free(sorted);
+	free(engines);
+}
+
+static bool fence_busy(int fence)
+{
+	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
+}
+
+/*
+ * Always reading from engine instance 0, with GuC submission the values are the
+ * same across all instances. Execlists they may differ but quite unlikely they
+ * would be and if they are we can live with this.
+ */
+static unsigned int get_timeslice(int i915,
+				  struct i915_engine_class_instance engine)
+{
+	unsigned int val;
+
+	switch (engine.engine_class) {
+	case I915_ENGINE_CLASS_RENDER:
+		gem_engine_property_scanf(i915, "rcs0", "timeslice_duration_ms",
+					  "%d", &val);
+		break;
+	case I915_ENGINE_CLASS_COPY:
+		gem_engine_property_scanf(i915, "bcs0", "timeslice_duration_ms",
+					  "%d", &val);
+		break;
+	case I915_ENGINE_CLASS_VIDEO:
+		gem_engine_property_scanf(i915, "vcs0", "timeslice_duration_ms",
+					  "%d", &val);
+		break;
+	case I915_ENGINE_CLASS_VIDEO_ENHANCE:
+		gem_engine_property_scanf(i915, "vecs0", "timeslice_duration_ms",
+					  "%d", &val);
+		break;
+	}
+
+	return val;
+}
+
+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 i915, uint32_t handle)
+{
+	bool result;
+	int sf;
+
+	sf = syncobj_handle_to_fd(i915, handle,
+				  DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE);
+	result = poll(&(struct pollfd){sf, POLLIN}, 1, 0) == 0;
+	close(sf);
+
+	return result;
+}
+
+/*
+ * Ensure a parallel submit actually runs on HW in parallel by putting on a
+ * spinner on 1 engine, doing a parallel submit, and parallel submit is blocked
+ * behind spinner.
+ */
+static void parallel_ordering(int i915, unsigned int flags)
+{
+	uint32_t vm_id;
+	int class;
+
+	vm_id = gem_vm_create_in_vm_bind_mode(i915);
+
+	for (class = 0; class < 32; class++) {
+		struct drm_i915_gem_timeline_fence exec_fence = { };
+		const intel_ctx_t *ctx = NULL, *spin_ctx = NULL;
+		uint64_t fence_value = 0, batch_addr[32] = { };
+		struct i915_engine_class_instance *siblings;
+		uint32_t batch[16], obj[32], exec_syncobj;
+		struct drm_i915_gem_execbuffer3 execbuf;
+		struct drm_i915_gem_context_param param = {
+			.param = I915_CONTEXT_PARAM_RECOVERABLE,
+			.value = 0,
+		};
+		intel_ctx_cfg_t cfg;
+		unsigned int count;
+		igt_spin_t *spin;
+		uint64_t ahnd;
+		int i = 0;
+
+		siblings = list_engines(i915, 1u << class, &count);
+		if (!siblings)
+			continue;
+
+		if (count < 2) {
+			free(siblings);
+			continue;
+		}
+
+		logical_sort_siblings(i915, siblings, count);
+
+		memset(&cfg, 0, sizeof(cfg));
+		cfg.parallel = true;
+		cfg.num_engines = 1;
+		cfg.width = count;
+		memcpy(cfg.engines, siblings, sizeof(*siblings) * count);
+
+		if (__intel_ctx_create(i915, &cfg, &ctx)) {
+			free(siblings);
+			continue;
+		}
+		param.ctx_id = ctx->id;
+		gem_context_set_param(i915, &param);
+		gem_context_set_vm(i915, ctx->id, vm_id);
+
+		batch[i] = MI_ATOMIC | MI_ATOMIC_INC;
+#define TARGET_BO_OFFSET	(0x1 << 16)
+		batch[++i] = TARGET_BO_OFFSET;
+		batch[++i] = 0;
+		batch[++i] = MI_BATCH_BUFFER_END;
+
+		obj[0] = gem_create(i915, 4096);
+		i915_vm_bind(i915, vm_id, TARGET_BO_OFFSET, obj[0], 0, 4096, 0, 0, 0);
+
+		for (i = 1; i < count + 1; ++i) {
+			obj[i] = gem_create(i915, 4096);
+			gem_write(i915, obj[i], 0, batch, sizeof(batch));
+
+			batch_addr[i - 1] = TARGET_BO_OFFSET * (i + 1);
+			i915_vm_bind(i915, vm_id, batch_addr[i - 1], obj[i], 0, 4096, 0, 0, 0);
+		}
+
+		exec_syncobj = syncobj_create(i915, 0);
+		exec_fence.handle = exec_syncobj;
+		exec_fence.flags = I915_TIMELINE_FENCE_SIGNAL;
+
+		memset(&execbuf, 0, sizeof(execbuf));
+		execbuf.ctx_id = ctx->id;
+		execbuf.batch_address = to_user_pointer(batch_addr);
+		execbuf.fence_count = 1;
+		execbuf.timeline_fences = to_user_pointer(&exec_fence);
+
+		/* Block parallel submission */
+		spin_ctx = ctx_create_engines(i915, siblings, count);
+		ahnd = get_simple_ahnd(i915, spin_ctx->id);
+		spin = __igt_spin_new(i915,
+				      .ahnd = ahnd,
+				      .ctx = spin_ctx,
+				      .engine = 0,
+				      .flags = IGT_SPIN_FENCE_OUT |
+				      IGT_SPIN_NO_PREEMPTION);
+
+		/* Wait for spinners to start */
+		usleep(5 * 10000);
+		igt_assert(fence_busy(spin->out_fence));
+
+		/* Submit parallel execbuf */
+		gem_execbuf3(i915, &execbuf);
+
+		/*
+		 * Wait long enough for timeslcing to kick in but not
+		 * preemption. Spinner + parallel execbuf should be
+		 * active. Assuming default timeslice / preemption values, if
+		 * these are changed it is possible for the test to fail.
+		 */
+		usleep(get_timeslice(i915, siblings[0]) * 2);
+		igt_assert(fence_busy(spin->out_fence));
+		igt_assert(syncobj_busy(i915, exec_syncobj));
+		check_bo(i915, obj[0], 0);
+
+		/*
+		 * End spinner and wait for spinner + parallel execbuf
+		 * to compelte.
+		 */
+		igt_spin_end(spin);
+		igt_assert(syncobj_timeline_wait(i915, &exec_syncobj, &fence_value, 1,
+						 gettime_ns() + (2 * NSEC_PER_SEC),
+						 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+		igt_assert(!syncobj_busy(i915, exec_syncobj));
+		syncobj_destroy(i915, exec_syncobj);
+		check_bo(i915, obj[0], count);
+
+		/* Clean up */
+		intel_ctx_destroy(i915, ctx);
+		intel_ctx_destroy(i915, spin_ctx);
+		i915_vm_unbind(i915, vm_id, TARGET_BO_OFFSET, 4096);
+		for (i = 1; i < count + 1; ++i)
+			i915_vm_unbind(i915, vm_id, batch_addr[i - 1], 4096);
+
+		for (i = 0; i < count + 1; ++i)
+			gem_close(i915, obj[i]);
+		free(siblings);
+		igt_spin_free(i915, spin);
+		put_ahnd(ahnd);
+	}
+
+	gem_vm_destroy(i915, vm_id);
+}
+
+static bool has_load_balancer(int i915)
+{
+	const intel_ctx_cfg_t cfg = {
+		.load_balance = true,
+		.num_engines = 1,
+	};
+	const intel_ctx_t *ctx = NULL;
+	int err;
+
+	err = __intel_ctx_create(i915, &cfg, &ctx);
+	intel_ctx_destroy(i915, ctx);
+
+	return err == 0;
+}
+
+static bool has_logical_mapping(int i915)
+{
+	struct drm_i915_query_engine_info *engines;
+	unsigned int i;
+
+	engines = query_engine_info(i915);
+
+	for (i = 0; i < engines->num_engines; ++i)
+		if (!(engines->engines[i].flags &
+		     I915_ENGINE_INFO_HAS_LOGICAL_INSTANCE)) {
+			free(engines);
+			return false;
+		}
+
+	free(engines);
+	return true;
+}
+
+static bool has_parallel_execbuf(int i915)
+{
+	intel_ctx_cfg_t cfg = {
+		.parallel = true,
+		.num_engines = 1,
+	};
+	const intel_ctx_t *ctx = NULL;
+	int err;
+
+	/* Currently, parallel submission is only working with guc */
+	if (!gem_using_guc_submission(i915))
+		return false;
+
+	for (int class = 0; class < 32; class++) {
+		struct i915_engine_class_instance *siblings;
+		unsigned int count;
+
+		siblings = list_engines(i915, 1u << class, &count);
+		if (!siblings)
+			continue;
+
+		if (count < 2) {
+			free(siblings);
+			continue;
+		}
+
+		logical_sort_siblings(i915, siblings, count);
+
+		cfg.width = count;
+		memcpy(cfg.engines, siblings, sizeof(*siblings) * count);
+		free(siblings);
+
+		err = __intel_ctx_create(i915, &cfg, &ctx);
+		intel_ctx_destroy(i915, ctx);
+
+		return err == 0;
+	}
+
+	return false;
+}
+
+igt_main
+{
+	int i915 = -1;
+
+	igt_fixture {
+		i915 = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(i915);
+
+		gem_require_contexts(i915);
+		igt_require(i915_vm_bind_version(i915) == 1);
+		igt_require(gem_has_engine_topology(i915));
+		igt_require(has_load_balancer(i915));
+		igt_require(has_perf_engines(i915));
+	}
+
+	igt_subtest_group {
+		igt_fixture {
+			igt_require(has_logical_mapping(i915));
+			igt_require(has_parallel_execbuf(i915));
+		}
+
+		igt_describe("Ensure a parallel submit actually runs in parallel");
+		igt_subtest("parallel-ordering")
+			parallel_ordering(i915, 0);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 6c1564e85..395c88a7d 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -376,6 +376,13 @@ test_executables += executable('gem_exec_balancer', 'i915/gem_exec_balancer.c',
 	   install : true)
 test_list += 'gem_exec_balancer'
 
+test_executables += executable('gem_exec3_balancer', 'i915/gem_exec3_balancer.c',
+	   dependencies : test_deps + [ lib_igt_perf ],
+	   install_dir : libexecdir,
+	   install_rpath : libexecdir_rpathdir,
+	   install : true)
+test_list += 'gem_exec3_balancer'
+
 test_executables += executable('gem_mmap_offset',
 	   join_paths('i915', 'gem_mmap_offset.c'),
 	   dependencies : test_deps + [ libatomic ],
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 12/14] tests/i915/vm_bind: Add gem_lmem_swapping@vm_bind sub test
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (10 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 11/14] tests/i915/vm_bind: Add gem_exec3_balancer test Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 13/14] tests/i915/vm_bind: Add gem_shrink@vm_bind* subtests Niranjana Vishwanathapura
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Validate eviction of objects with persistent mappings and
check persistent mappings are properly rebound upon subsequent
execbuf3 call.

TODO: Add a new swapping test with just vm_bind mode
      (without legacy execbuf).

v2: use i915_vm_bind library functions
v3: fix dg2 alignment issue

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/gem_lmem_swapping.c | 134 ++++++++++++++++++++++++++++++++-
 1 file changed, 133 insertions(+), 1 deletion(-)

diff --git a/tests/i915/gem_lmem_swapping.c b/tests/i915/gem_lmem_swapping.c
index 969fb9080..7d009c853 100644
--- a/tests/i915/gem_lmem_swapping.c
+++ b/tests/i915/gem_lmem_swapping.c
@@ -3,12 +3,16 @@
  * Copyright © 2021 Intel Corporation
  */
 
+#include <poll.h>
+
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "i915/gem_vm.h"
 #include "i915/intel_memory_region.h"
+#include "i915/i915_vm_bind.h"
 #include "igt.h"
 #include "igt_kmod.h"
+#include "igt_syncobj.h"
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -54,6 +58,7 @@ struct params {
 		uint64_t max;
 	} size;
 	unsigned int count;
+	unsigned int vm_bind_count;
 	unsigned int loops;
 	unsigned int mem_limit;
 #define TEST_VERIFY	(1 << 0)
@@ -64,15 +69,18 @@ struct params {
 #define TEST_MULTI	(1 << 5)
 #define TEST_CCS	(1 << 6)
 #define TEST_MASSIVE	(1 << 7)
+#define TEST_VM_BIND	(1 << 8)
 	unsigned int flags;
 	unsigned int seed;
 	bool oom_test;
+	uint64_t va;
 };
 
 struct object {
 	uint64_t size;
 	uint32_t seed;
 	uint32_t handle;
+	uint64_t va;
 	struct blt_copy_object *blt_obj;
 };
 
@@ -278,6 +286,86 @@ verify_object_ccs(int i915, const struct object *obj,
 	free(cmd);
 }
 
+#define BATCH_VA       0xa00000
+
+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 void vm_bind(int i915, struct object *list, unsigned int num, uint64_t *va,
+		    uint32_t batch, uint64_t batch_size, uint32_t vm_id)
+{
+	uint32_t *bind_syncobj;
+	uint64_t *fence_value;
+	unsigned int i;
+
+	bind_syncobj = calloc(num + 1, sizeof(*bind_syncobj));
+	igt_assert(bind_syncobj);
+
+	fence_value = calloc(num + 1, sizeof(*fence_value));
+	igt_assert(fence_value);
+
+	for (i = 0; i < num; i++) {
+		list[i].va = *va;
+		bind_syncobj[i] = syncobj_create(i915, 0);
+		i915_vm_bind(i915, vm_id, *va, list[i].handle, 0, list[i].size, 0, bind_syncobj[i], 0);
+		*va += list[i].size;
+	}
+	bind_syncobj[i] = syncobj_create(i915, 0);
+	i915_vm_bind(i915, vm_id, BATCH_VA, batch, 0, batch_size, 0, bind_syncobj[i], 0);
+
+	igt_assert(syncobj_timeline_wait(i915, bind_syncobj, fence_value, num + 1,
+					 gettime_ns() + (2 * NSEC_PER_SEC),
+					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+	for (i = 0; i <= num; i++)
+		syncobj_destroy(i915, bind_syncobj[i]);
+}
+
+static void vm_unbind(int i915, struct object *list, unsigned int num,
+		      uint64_t batch_size, uint32_t vm_id)
+{
+	unsigned int i;
+
+	i915_vm_unbind(i915, vm_id, BATCH_VA, batch_size);
+	for (i = 0; i < num; i++)
+		i915_vm_unbind(i915, vm_id, list[i].va, list[i].size);
+}
+
+static void move_to_lmem_execbuf3(int i915,
+				  const intel_ctx_t *ctx,
+				  unsigned int engine,
+				  bool do_oom_test)
+{
+	uint32_t exec_syncobj = syncobj_create(i915, 0);
+	struct drm_i915_gem_timeline_fence exec_fence = {
+		.handle = exec_syncobj,
+		.flags = I915_TIMELINE_FENCE_SIGNAL
+	};
+	struct drm_i915_gem_execbuffer3 eb = {
+		.ctx_id = ctx->id,
+		.batch_address = BATCH_VA,
+		.engine_idx = engine,
+		.fence_count = 1,
+		.timeline_fences = to_user_pointer(&exec_fence),
+	};
+	uint64_t fence_value = 0;
+	int ret;
+
+retry:
+	ret = __gem_execbuf3(i915, &eb);
+	if (do_oom_test && (ret == -ENOMEM || ret == -ENXIO))
+		goto retry;
+	igt_assert_eq(ret, 0);
+
+	igt_assert(syncobj_timeline_wait(i915, &exec_syncobj, &fence_value, 1,
+					 gettime_ns() + (2 * NSEC_PER_SEC),
+					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+	syncobj_destroy(i915, exec_syncobj);
+}
+
 static void move_to_lmem(int i915,
 			 const intel_ctx_t *ctx,
 			 struct object *list,
@@ -325,14 +413,16 @@ static void __do_evict(int i915,
 	uint32_t region_id = INTEL_MEMORY_REGION_ID(region->memory_class,
 						    region->memory_instance);
 	const unsigned int max_swap_in = params->count / 100 + 1;
+	uint64_t size, ahnd, batch_size = SZ_64K;
 	struct object *objects, *obj, *list;
 	const uint32_t bpp = 32;
 	uint32_t width, height, stride;
+	const intel_ctx_t *vm_bind_ctx;
 	const intel_ctx_t *blt_ctx;
 	struct blt_copy_object *tmp;
 	unsigned int engine = 0;
+	uint32_t batch, vm_id;
 	unsigned int i, l;
-	uint64_t size, ahnd;
 	struct timespec t = {};
 	unsigned int num;
 
@@ -416,6 +506,26 @@ static void __do_evict(int i915,
 		  readable_size(params->size.max), readable_unit(params->size.max),
 		  params->count, seed);
 
+	/* VM_BIND the specified subset of objects (as persistent mappings) */
+	if (params->flags & TEST_VM_BIND) {
+		const uint32_t bbe = MI_BATCH_BUFFER_END;
+		struct drm_i915_gem_context_param param = {
+			.param = I915_CONTEXT_PARAM_RECOVERABLE,
+			.value = 0,
+		};
+
+		batch = gem_create_from_pool(i915, &batch_size, region_id);
+		gem_write(i915, batch, 0, &bbe, sizeof(bbe));
+
+		vm_id = gem_vm_create_in_vm_bind_mode(i915);
+		vm_bind_ctx = intel_ctx_create(i915, &ctx->cfg);
+		param.ctx_id = vm_bind_ctx->id;
+		gem_context_set_param(i915, &param);
+		gem_context_set_vm(i915, vm_bind_ctx->id, vm_id);
+		vm_bind(i915, objects, params->vm_bind_count, &params->va,
+			batch, batch_size, vm_id);
+	}
+
 	/*
 	 * Move random objects back into lmem.
 	 * For TEST_MULTI runs, make each object counts a loop to
@@ -454,6 +564,15 @@ static void __do_evict(int i915,
 		}
 	}
 
+	/* Rebind persistent mappings to ensure they are swapped back in */
+	if (params->flags & TEST_VM_BIND) {
+		move_to_lmem_execbuf3(i915, vm_bind_ctx, engine, params->oom_test);
+
+		vm_unbind(i915, objects, params->vm_bind_count, batch_size, vm_id);
+		intel_ctx_destroy(i915, vm_bind_ctx);
+		gem_vm_destroy(i915, vm_id);
+	}
+
 	for (i = 0; i < params->count; i++) {
 		gem_close(i915, objects[i].handle);
 		free(objects[i].blt_obj);
@@ -553,6 +672,15 @@ static void fill_params(int i915, struct params *params,
 	if (flags & TEST_HEAVY)
 		params->loops = params->loops / 2 + 1;
 
+	/*
+	 * Set vm_bind_count and ensure it doesn't over-subscribe LMEM.
+	 * Set va range to ensure it is big enough for all bindings in a VM.
+	 */
+	if (flags & TEST_VM_BIND) {
+		params->vm_bind_count = params->count / 3;
+		params->va = (uint64_t)params->vm_bind_count * size * 4;
+	}
+
 	params->flags = flags;
 	params->oom_test = do_oom_test;
 
@@ -583,6 +711,9 @@ static void test_evict(int i915,
 	if (flags & TEST_CCS)
 		igt_require(IS_DG2(intel_get_drm_devid(i915)));
 
+	if (flags & TEST_VM_BIND)
+		igt_require(i915_vm_bind_version(i915) == 1);
+
 	fill_params(i915, &params, region, flags, nproc, false);
 
 	if (flags & TEST_PARALLEL) {
@@ -764,6 +895,7 @@ igt_main_args("", long_options, help_str, opt_handler, NULL)
 		{ "heavy-verify-random-ccs", TEST_CCS | TEST_RANDOM | TEST_HEAVY },
 		{ "heavy-verify-multi-ccs", TEST_CCS | TEST_RANDOM | TEST_HEAVY | TEST_ENGINES | TEST_MULTI },
 		{ "parallel-random-verify-ccs", TEST_PARALLEL | TEST_RANDOM | TEST_CCS },
+		{ "vm_bind", TEST_VM_BIND },
 		{ }
 	};
 	const intel_ctx_t *ctx;
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 13/14] tests/i915/vm_bind: Add gem_shrink@vm_bind* subtests
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (11 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 12/14] tests/i915/vm_bind: Add gem_lmem_swapping@vm_bind sub test Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 14/14] tests/i915/vm_bind: Test capture of persistent mappings Niranjana Vishwanathapura
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Add VM_BIND shrinker subtests.

v2: Do not blacklist vm_bind tests, add vm_bind_version assert

Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/gem_shrink.c      | 70 ++++++++++++++++++++++++++++++++++--
 tests/intel-ci/blacklist.txt |  2 +-
 2 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/tests/i915/gem_shrink.c b/tests/i915/gem_shrink.c
index 380d2c846..4fa341d8f 100644
--- a/tests/i915/gem_shrink.c
+++ b/tests/i915/gem_shrink.c
@@ -29,10 +29,13 @@
 
 #include "i915/gem.h"
 #include "i915/gem_create.h"
+#include "i915/gem_vm.h"
+#include "i915/i915_vm_bind.h"
 #include "igt.h"
 #include "igt_gt.h"
 #include "igt_debugfs.h"
 #include "igt_sysfs.h"
+#include "igt_syncobj.h"
 
 #ifndef MADV_FREE
 #define MADV_FREE 8
@@ -229,6 +232,62 @@ static void hang(int fd, uint64_t alloc)
 	munmap(obj, obj_size);
 }
 
+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;
+}
+
+#define BATCH_VA	0xc0000000
+static void vm_bind(int fd, uint64_t alloc)
+{
+	struct drm_i915_gem_timeline_fence exec_fence = { };
+	struct drm_i915_gem_context_param param = {
+		.param = I915_CONTEXT_PARAM_RECOVERABLE,
+		.value = 0,
+	};
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_execbuffer3 execbuf3;
+	uint32_t vm_id, handle, exec_syncobj;
+	struct intel_engine_data engines;
+	const intel_ctx_t *ctx;
+	uint64_t fence_value = 0;
+
+	vm_id = gem_vm_create_in_vm_bind_mode(fd);
+	ctx = intel_ctx_create_all_physical(fd);
+	param.ctx_id = ctx->id;
+	gem_context_set_param(fd, &param);
+	gem_context_set_vm(fd, ctx->id, vm_id);
+	(void)gem_context_get_vm(fd, ctx->id);
+	engines = intel_engine_list_for_ctx_cfg(fd, &ctx->cfg);
+
+	handle = gem_create(fd, alloc);
+	gem_write(fd, handle, 0, &bbe, sizeof(bbe));
+	i915_vm_bind(fd, vm_id, BATCH_VA, handle, 0, alloc, 0, 0, 0);
+
+	exec_syncobj = syncobj_create(fd, 0);
+	exec_fence.handle = exec_syncobj;
+	exec_fence.flags = I915_TIMELINE_FENCE_SIGNAL;
+
+	memset(&execbuf3, 0, sizeof(execbuf3));
+	execbuf3.ctx_id = ctx->id;
+	execbuf3.engine_idx = engines.engines[0].flags;
+	execbuf3.batch_address = BATCH_VA;
+	execbuf3.fence_count = 1;
+	execbuf3.timeline_fences = to_user_pointer(&exec_fence);
+
+	gem_execbuf3(fd, &execbuf3);
+
+	igt_assert(syncobj_timeline_wait(fd, &exec_syncobj, &fence_value, 1,
+					 gettime_ns() + (2 * NSEC_PER_SEC),
+					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+	gem_madvise(fd, handle, I915_MADV_DONTNEED);
+
+	syncobj_destroy(fd, exec_syncobj);
+	intel_ctx_destroy(fd, ctx);
+}
+
 static void userptr(int fd, uint64_t alloc, unsigned int flags)
 #define UDIRTY (1 << 0)
 {
@@ -418,6 +477,7 @@ igt_main
 		{ "execbufN", execbufN },
 		{ "execbufX", execbufX },
 		{ "hang", hang },
+		{ "vm_bind", vm_bind },
 		{ NULL },
 	};
 	const struct mode {
@@ -433,11 +493,11 @@ igt_main
 	};
 	uint64_t alloc_size = 0;
 	int num_processes = 0;
+	int fd;
 
 	igt_fixture {
 		const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
 		uint64_t mem_size = igt_get_total_ram_mb();
-		int fd;
 
 		fd = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(fd);
@@ -456,7 +516,6 @@ igt_main
 			 num_processes, alloc_size);
 
 		alloc_size <<= 20;
-		close(fd);
 	}
 
 	igt_subtest("reclaim")
@@ -467,9 +526,16 @@ igt_main
 			igt_subtest_f("%s%s", t->name, m->suffix) {
 				igt_require_memory(num_processes, alloc_size,
 						   CHECK_SWAP | CHECK_RAM);
+				if (!strcmp(t->name, "vm_bind"))
+					igt_require(i915_vm_bind_version(fd) == 1);
+
 				run_test(num_processes, alloc_size,
 					 t->func, m->flags);
 			}
 		}
 	}
+
+	igt_fixture {
+		close(fd);
+	}
 }
diff --git a/tests/intel-ci/blacklist.txt b/tests/intel-ci/blacklist.txt
index 0d3077301..080a49957 100644
--- a/tests/intel-ci/blacklist.txt
+++ b/tests/intel-ci/blacklist.txt
@@ -47,7 +47,7 @@ igt@gem_render_linear_blits@(?!.*basic).*
 igt@gem_render_tiled_blits@(?!.*basic).*
 igt@gem_reset_stats(@.*)?
 igt@gem_ringfill@(?!.*basic).*
-igt@gem_shrink@(?!reclaim$).*
+igt@gem_shrink@(get|pwrite|pread|mmap|execbuf|hang|vm_bind-oom)*.*
 igt@gem_softpin@.*(hang|S4).*
 igt@gem_streaming_writes(@.*)?
 igt@gem_sync@(?!.*basic).*
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] [PATCH i-g-t v8 14/14] tests/i915/vm_bind: Test capture of persistent mappings
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (12 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 13/14] tests/i915/vm_bind: Add gem_shrink@vm_bind* subtests Niranjana Vishwanathapura
@ 2022-11-29  7:23 ` Niranjana Vishwanathapura
  2022-12-06 17:34   ` Matthew Auld
  2022-11-29  8:14 ` [igt-dev] ✓ Fi.CI.BAT: success for vm_bind: Add VM_BIND validation support (rev12) Patchwork
  2022-11-29 10:26 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  15 siblings, 1 reply; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-11-29  7:23 UTC (permalink / raw)
  To: igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, matthew.auld, daniel.vetter,
	petri.latvala

Add i915_vm_bind_capture to validate dump capture of persistent
mappings including partial binding.

Signed-off-by: Brian Welty <brian.welty@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 tests/i915/i915_vm_bind_capture.c | 445 ++++++++++++++++++++++++++++++
 tests/meson.build                 |   1 +
 2 files changed, 446 insertions(+)
 create mode 100644 tests/i915/i915_vm_bind_capture.c

diff --git a/tests/i915/i915_vm_bind_capture.c b/tests/i915/i915_vm_bind_capture.c
new file mode 100644
index 000000000..f82f53b96
--- /dev/null
+++ b/tests/i915/i915_vm_bind_capture.c
@@ -0,0 +1,445 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2022 Intel Corporation. All rights reserved.
+ */
+
+/** @file gem_vm_bind_capture.c
+ *
+ * This is the test for dump capture of VM_BIND mappings.
+ *
+ * The goal is to simply ensure that capture of persistent mappings
+ * works. This test in part is derived from gem_exec_capture.c
+ */
+
+#include <sys/poll.h>
+#include <zlib.h>
+#include <sched.h>
+
+#include "i915/gem.h"
+#include "i915/gem_create.h"
+#include "i915/gem_vm.h"
+#include "i915/i915_vm_bind.h"
+#include "igt.h"
+#include "igt_device.h"
+#include "igt_syncobj.h"
+#include "igt_sysfs.h"
+#include "igt_types.h"
+#include "intel_ctx.h"
+
+
+#define PAGE_SIZE   4096
+
+#define NUM_OBJS  3
+#define NUM_MAPS  4
+#define BATCH_VA  0x8000000
+
+IGT_TEST_DESCRIPTION("Check that we capture the user specified persistent mappings on a hang");
+
+struct mappings {
+	uint32_t  obj;
+	uint64_t  va;
+	uint64_t  offset;
+	uint64_t  length;
+
+	uint32_t  idx;
+	uint32_t  expect;
+	bool      found;
+};
+
+static unsigned long zlib_inflate(uint32_t **ptr, unsigned long len)
+{
+	struct z_stream_s zstream;
+	void *out;
+
+	memset(&zstream, 0, sizeof(zstream));
+
+	zstream.next_in = (unsigned char *)*ptr;
+	zstream.avail_in = 4*len;
+
+	if (inflateInit(&zstream) != Z_OK)
+		return 0;
+
+	out = malloc(128*4096); /* approximate obj size */
+	zstream.next_out = out;
+	zstream.avail_out = 128*4096;
+
+	do {
+		switch (inflate(&zstream, Z_SYNC_FLUSH)) {
+		case Z_STREAM_END:
+			goto end;
+		case Z_OK:
+			break;
+		default:
+			inflateEnd(&zstream);
+			return 0;
+		}
+
+		if (zstream.avail_out)
+			break;
+
+		out = realloc(out, 2*zstream.total_out);
+		if (out == NULL) {
+			inflateEnd(&zstream);
+			return 0;
+		}
+
+		zstream.next_out = (unsigned char *)out + zstream.total_out;
+		zstream.avail_out = zstream.total_out;
+	} while (1);
+end:
+	inflateEnd(&zstream);
+	free(*ptr);
+	*ptr = out;
+	return zstream.total_out / 4;
+}
+
+static unsigned long
+ascii85_decode(char *in, uint32_t **out, bool inflate, char **end)
+{
+	unsigned long len = 0, size = 1024;
+
+	*out = realloc(*out, sizeof(uint32_t)*size);
+	if (*out == NULL)
+		return 0;
+
+	while (*in >= '!' && *in <= 'z') {
+		uint32_t v = 0;
+
+		if (len == size) {
+			size *= 2;
+			*out = realloc(*out, sizeof(uint32_t)*size);
+			if (*out == NULL)
+				return 0;
+		}
+
+		if (*in == 'z') {
+			in++;
+		} else {
+			v += in[0] - 33; v *= 85;
+			v += in[1] - 33; v *= 85;
+			v += in[2] - 33; v *= 85;
+			v += in[3] - 33; v *= 85;
+			v += in[4] - 33;
+			in += 5;
+		}
+		(*out)[len++] = v;
+	}
+	*end = in;
+
+	if (!inflate)
+		return len;
+
+	return zlib_inflate(out, len);
+}
+
+static int check_error_state(int dir, struct mappings *map, uint32_t num_maps)
+{
+	char *error, *str;
+	int blobs = 0;
+
+	errno = 0;
+	error = igt_sysfs_get(dir, "error");
+	igt_sysfs_set(dir, "error", "Begone!");
+	igt_assert(error);
+	igt_assert(errno != ENOMEM);
+	igt_debug("%s\n", error);
+
+	/* render ring --- user = 0x00000000 ffffd000 */
+	for (str = error; (str = strstr(str, "--- user = ")); ) {
+		uint32_t *data = NULL;
+		uint64_t addr;
+		unsigned long i, j, sz;
+		unsigned long start;
+		unsigned long end;
+
+		if (strncmp(str, "--- user = 0x", 13))
+			break;
+		str += 13;
+		addr = strtoul(str, &str, 16);
+		addr <<= 32;
+		addr |= strtoul(str + 1, &str, 16);
+		igt_assert(*str++ == '\n');
+
+		start = 0;
+		end = num_maps;
+		while (end > start) {
+			i = (end - start) / 2 + start;
+			if (map[i].va < addr)
+				start = i + 1;
+			else if (map[i].va > addr)
+				end = i;
+			else
+				break;
+		}
+
+		igt_assert(map[i].va == addr);
+		igt_assert(!map[i].found);
+		map[i].found = true;
+		igt_debug("offset:%"PRIx64", index:%d\n",
+			  addr, map[i].idx);
+
+		/* gtt_page_sizes = 0x00010000 */
+		if (strncmp(str, "gtt_page_sizes = 0x", 19) == 0) {
+			str += 19 + 8;
+			igt_assert(*str++ == '\n');
+		}
+
+		if (!(*str == ':' || *str == '~'))
+			continue;
+
+		igt_debug("blob:%.64s\n", str);
+		sz = ascii85_decode(str + 1, &data, *str == ':', &str);
+		igt_debug("Found addr 0x%lx sz 0x%lx\n", addr, sz);
+		igt_assert_eq(4 * sz, map[i].length);
+		igt_assert(*str++ == '\n');
+		str = strchr(str, '-');
+
+		for (j = 0; j < sz; j++)
+			igt_assert_eq(data[j], map[i].expect + j);
+
+		blobs++;
+		free(data);
+	}
+
+	free(error);
+	return blobs;
+}
+
+static int gem_recurse(uint32_t *batch, uint64_t batch_va)
+{
+	*batch++ = MI_BATCH_BUFFER_START | 1 << 8 | 1;
+	*batch++ = lower_32_bits(batch_va);
+	*batch++ = upper_32_bits(batch_va);
+	*batch = 0;
+
+	return 4 * sizeof(uint32_t);
+}
+
+static struct gem_engine_properties
+configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctx_id)
+{
+	struct gem_engine_properties props;
+
+	/* Ensure fast hang detection */
+	props.engine = e;
+	props.preempt_timeout = 250;
+	props.heartbeat_interval = 500;
+	gem_engine_properties_configure(fd, &props);
+
+	/* Allow engine based resets and disable banning */
+	igt_allow_hang(fd, ctx_id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
+
+	return props;
+}
+
+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 void gem_reset(int fd, int dir, uint32_t ctx_id, uint32_t batch,
+		      uint64_t batch_va, struct intel_execution_engine2 *e)
+{
+	struct drm_i915_gem_timeline_fence exec_fence = { };
+	struct drm_i915_gem_execbuffer3 execbuf = { };
+	uint64_t fence_value = 0;
+	uint32_t exec_syncobj;
+	uint32_t buf[20], len;
+
+	len = gem_recurse(buf, batch_va);
+	gem_write(fd, batch, 0, buf, len);
+
+	execbuf.ctx_id = ctx_id;
+	execbuf.batch_address = batch_va;
+	execbuf.engine_idx = e->flags;
+	execbuf.fence_count = 1;
+	execbuf.timeline_fences = to_user_pointer(&exec_fence);
+
+	exec_syncobj = syncobj_create(fd, 0);
+	exec_fence.handle = exec_syncobj;
+	exec_fence.flags = I915_TIMELINE_FENCE_SIGNAL;
+
+	gem_execbuf3(fd, &execbuf);
+
+	igt_assert(syncobj_timeline_wait(fd, &exec_syncobj, &fence_value, 1,
+					 gettime_ns() + (2 * NSEC_PER_SEC),
+					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+	syncobj_destroy(fd, exec_syncobj);
+}
+
+static void set_map(struct mappings *m, uint32_t idx, uint32_t obj, uint64_t va,
+		    uint64_t offset, uint64_t length, uint32_t expect)
+{
+	m->idx = idx;
+	m->obj = obj;
+	m->va = va;
+	m->offset = offset;
+	m->length = length;
+	m->expect = expect;
+	igt_debug("Created mapping:0x%x - va 0x%lx handle %d offset 0x%lx length 0x%lx\n",
+		  m->idx, m->va, m->obj, m->offset, m->length);
+}
+
+static uint32_t create_obj(int fd, struct gem_memory_region *mr, uint32_t size, void **addr)
+{
+	uint32_t handle;
+
+	if (!mr) {
+		igt_assert(posix_memalign(addr, PAGE_SIZE, size) == 0);
+		gem_userptr(fd, *addr, size, 0, 0, &handle);
+	} else {
+		handle = gem_create_in_memory_region_list(fd, size, 0, &mr->ci, 1);
+		*addr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
+	}
+
+	return handle;
+}
+
+static void destroy_obj(int fd, uint32_t handle, uint32_t size, void *addr, bool is_userptr)
+{
+	if (!is_userptr)
+		igt_assert(gem_munmap(addr, size) == 0);
+
+	gem_close(fd, handle);
+
+	if (is_userptr)
+		free(addr);
+}
+
+static void run_vm_bind_capture(int fd, int dir, const intel_ctx_t *base_ctx,
+				struct gem_memory_region *mr,
+				struct intel_execution_engine2 *e)
+{
+	uint64_t obj_size = (mr ? mr->gtt_alignment : PAGE_SIZE) * 4;
+	struct mappings *m, map[NUM_MAPS * NUM_OBJS + 1] = { };
+	struct drm_i915_gem_context_param param = {
+		.param = I915_CONTEXT_PARAM_RECOVERABLE,
+		.value = 0,
+	};
+	struct gem_engine_properties saved_engine;
+	uint32_t i, obj[NUM_OBJS];
+	uint32_t *addr[NUM_OBJS];
+	const intel_ctx_t *ctx;
+	uint32_t vm_id, batch;
+
+	ctx = intel_ctx_create(fd, &base_ctx->cfg);
+	param.ctx_id = ctx->id;
+	gem_context_set_param(fd, &param);
+	vm_id = gem_vm_create_in_vm_bind_mode(fd);
+	gem_context_set_vm(fd, ctx->id, vm_id);
+
+	saved_engine = configure_hangs(fd, e, ctx->id);
+
+	/* Create objects and mappings */
+	batch = gem_create(fd, PAGE_SIZE);
+	for (i = 0, m = map; i < NUM_OBJS; i++) {
+		obj[i] = create_obj(fd, mr, obj_size, (void **)&addr[i]);
+
+		for (unsigned int n = 0; n < obj_size / sizeof(*addr[0]); n++)
+			addr[i][n] = (i << 24) + n;
+
+		/* Full bind */
+		set_map(m++, 0 + (i * NUM_MAPS), obj[i], 0xa000000 << i, 0, obj_size, (i << 24));
+		/* Full bind with alias VA */
+		set_map(m++, 1 + (i * NUM_MAPS), obj[i], 0xb000000 << i, 0, obj_size, (i << 24));
+		/* Partial bind */
+		set_map(m++, 2 + (i * NUM_MAPS), obj[i], 0xc000000 << i, 0, obj_size / 2, (i << 24));
+		/* Partial bind with offset */
+		set_map(m++, 3 + (i * NUM_MAPS), obj[i], 0xd000000 << i, obj_size / 2, obj_size / 2,
+			(i << 24) + (obj_size / 2) / sizeof(*addr[0]));
+	}
+	m->length = 0;
+
+	i915_vm_bind(fd, vm_id, BATCH_VA, batch, 0, PAGE_SIZE, 0, 0, 0);
+	/* Bind mappings with capture request */
+	for (m = map; m->length; m++)
+		i915_vm_bind(fd, vm_id, m->va, m->obj, m->offset, m->length,
+			     I915_GEM_VM_BIND_CAPTURE, 0, 0);
+
+	/* Cause reset and check the dump */
+	gem_reset(fd, dir, ctx->id, batch, BATCH_VA, e);
+	igt_assert_eq(check_error_state(dir, map, NUM_OBJS * NUM_MAPS), NUM_OBJS * NUM_MAPS);
+
+	for (m = map; m->length; m++)
+		i915_vm_unbind(fd, vm_id, m->va, m->length);
+	i915_vm_unbind(fd, vm_id, BATCH_VA, PAGE_SIZE);
+
+	gem_close(fd, batch);
+	for (i = 0; i < NUM_OBJS; i++)
+		destroy_obj(fd, obj[i], obj_size, (void *)addr[i], !mr);
+
+	gem_engine_properties_restore(fd, &saved_engine);
+
+	gem_vm_destroy(fd, vm_id);
+	intel_ctx_destroy(fd, ctx);
+}
+
+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 size_t safer_strlen(const char *s)
+{
+	return s ? strlen(s) : 0;
+}
+
+igt_main
+{
+	struct intel_execution_engine2 *e;
+	const intel_ctx_t *ctx = NULL;
+	igt_fd_t(dir);
+	igt_fd_t(fd);
+
+	igt_fixture {
+		fd = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(fd);
+		igt_allow_hang(fd, 0, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
+
+		dir = igt_sysfs_open(fd);
+		igt_require(igt_sysfs_set(dir, "error", "Begone!"));
+		igt_require(safer_strlen(igt_sysfs_get(dir, "error")) > 0);
+		ctx = intel_ctx_create_all_physical(fd);
+	}
+
+	igt_describe("Basic vm_bind capture test");
+	igt_subtest_with_dynamic("basic") {
+		for_each_ctx_engine(fd, ctx, e) {
+
+			for_each_memory_region(r, fd) {
+				if (r->ci.memory_instance)
+					continue;
+
+				igt_dynamic_f("%s-%s", e->name, r->name)
+					run_vm_bind_capture(fd, dir, ctx, r, e);
+			}
+
+			if (has_userptr(fd)) {
+				/* Use NULL memory region for userptr */
+				igt_dynamic_f("%s-userptr", e->name)
+					run_vm_bind_capture(fd, dir, ctx, NULL, e);
+			}
+		}
+	}
+
+	igt_fixture {
+		intel_ctx_destroy(fd, ctx);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 395c88a7d..ea282654c 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -229,6 +229,7 @@ i915_progs = [
 	'i915_suspend',
 	'i915_vm_bind_basic',
 	'i915_vm_bind_sanity',
+        'i915_vm_bind_capture',
 	'kms_big_fb',
 	'kms_big_joiner' ,
 	'kms_busy',
-- 
2.21.0.rc0.32.g243a4c7e27

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

* [igt-dev] ✓ Fi.CI.BAT: success for vm_bind: Add VM_BIND validation support (rev12)
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (13 preceding siblings ...)
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 14/14] tests/i915/vm_bind: Test capture of persistent mappings Niranjana Vishwanathapura
@ 2022-11-29  8:14 ` Patchwork
  2022-11-29 10:26 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  15 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2022-11-29  8:14 UTC (permalink / raw)
  To: Niranjana Vishwanathapura; +Cc: igt-dev

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

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_12441 -> IGTPW_8164
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

Participating hosts (35 -> 34)
------------------------------

  Missing    (1): bat-dg2-11 

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

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

### IGT changes ###

#### Possible regressions ####

  * {igt@gem_exec3_basic@basic} (NEW):
    - {bat-dg1-7}:        NOTRUN -> [SKIP][1] +2 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-dg1-7/igt@gem_exec3_basic@basic.html

  * {igt@i915_vm_bind_basic@basic-smem} (NEW):
    - {bat-adln-1}:       NOTRUN -> [SKIP][2] +2 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-adln-1/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-adlm-1}:       NOTRUN -> [SKIP][3] +2 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-adlm-1/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-rplp-1}:       NOTRUN -> [SKIP][4] +2 similar issues
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-rplp-1/igt@i915_vm_bind_basic@basic-smem.html
    - fi-rkl-11600:       NOTRUN -> [SKIP][5] +2 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-rkl-11600/igt@i915_vm_bind_basic@basic-smem.html
    - fi-adl-ddr5:        NOTRUN -> [SKIP][6] +2 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-adl-ddr5/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-dg2-9}:        NOTRUN -> [SKIP][7] +2 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-dg2-9/igt@i915_vm_bind_basic@basic-smem.html
    - bat-adlp-4:         NOTRUN -> [SKIP][8] +2 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-adlp-4/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-dg2-8}:        NOTRUN -> [SKIP][9] +2 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-dg2-8/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-rpls-1}:       NOTRUN -> [SKIP][10] +2 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-rpls-1/igt@i915_vm_bind_basic@basic-smem.html
    - {fi-ehl-2}:         NOTRUN -> [SKIP][11] +2 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-ehl-2/igt@i915_vm_bind_basic@basic-smem.html

  * {igt@i915_vm_bind_sanity@basic} (NEW):
    - {bat-rpls-2}:       NOTRUN -> [SKIP][12] +2 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-rpls-2/igt@i915_vm_bind_sanity@basic.html
    - fi-rkl-guc:         NOTRUN -> [SKIP][13] +2 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-rkl-guc/igt@i915_vm_bind_sanity@basic.html
    - bat-dg1-6:          NOTRUN -> [SKIP][14] +2 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-dg1-6/igt@i915_vm_bind_sanity@basic.html
    - {bat-adlp-6}:       NOTRUN -> [SKIP][15] +2 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-adlp-6/igt@i915_vm_bind_sanity@basic.html
    - fi-icl-u2:          NOTRUN -> [SKIP][16] +2 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-icl-u2/igt@i915_vm_bind_sanity@basic.html
    - bat-dg1-5:          NOTRUN -> [SKIP][17] +2 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-dg1-5/igt@i915_vm_bind_sanity@basic.html
    - {bat-jsl-3}:        NOTRUN -> [SKIP][18] +1 similar issue
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-jsl-3/igt@i915_vm_bind_sanity@basic.html
    - {bat-jsl-1}:        NOTRUN -> [SKIP][19] +1 similar issue
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-jsl-1/igt@i915_vm_bind_sanity@basic.html
    - {fi-jsl-1}:         NOTRUN -> [SKIP][20] +1 similar issue
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-jsl-1/igt@i915_vm_bind_sanity@basic.html

  
New tests
---------

  New tests have been introduced between CI_DRM_12441 and IGTPW_8164:

### New IGT tests (3) ###

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

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

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

  

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

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

### IGT changes ###

#### Issues hit ####

  * {igt@gem_exec3_basic@basic} (NEW):
    - fi-bdw-gvtdvm:      NOTRUN -> [SKIP][21] ([fdo#109271]) +2 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-bdw-gvtdvm/igt@gem_exec3_basic@basic.html
    - fi-pnv-d510:        NOTRUN -> [SKIP][22] ([fdo#109271]) +2 similar issues
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-pnv-d510/igt@gem_exec3_basic@basic.html
    - fi-skl-6700k2:      NOTRUN -> [SKIP][23] ([fdo#109271]) +2 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-skl-6700k2/igt@gem_exec3_basic@basic.html

  * igt@i915_selftest@live@gt_heartbeat:
    - fi-apl-guc:         [PASS][24] -> [DMESG-FAIL][25] ([i915#5334])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/fi-apl-guc/igt@i915_selftest@live@gt_heartbeat.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-apl-guc/igt@i915_selftest@live@gt_heartbeat.html

  * {igt@i915_vm_bind_basic@basic-smem} (NEW):
    - fi-cfl-8700k:       NOTRUN -> [SKIP][26] ([fdo#109271]) +2 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-cfl-8700k/igt@i915_vm_bind_basic@basic-smem.html
    - fi-elk-e7500:       NOTRUN -> [SKIP][27] ([fdo#109271]) +2 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-elk-e7500/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-kbl-2}:        NOTRUN -> [SKIP][28] ([fdo#109271]) +2 similar issues
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-kbl-2/igt@i915_vm_bind_basic@basic-smem.html
    - fi-bsw-kefka:       NOTRUN -> [SKIP][29] ([fdo#109271]) +2 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-bsw-kefka/igt@i915_vm_bind_basic@basic-smem.html
    - fi-cfl-guc:         NOTRUN -> [SKIP][30] ([fdo#109271]) +2 similar issues
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-cfl-guc/igt@i915_vm_bind_basic@basic-smem.html
    - fi-cfl-8109u:       NOTRUN -> [SKIP][31] ([fdo#109271]) +2 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-cfl-8109u/igt@i915_vm_bind_basic@basic-smem.html
    - fi-ivb-3770:        NOTRUN -> [SKIP][32] ([fdo#109271]) +2 similar issues
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-ivb-3770/igt@i915_vm_bind_basic@basic-smem.html
    - fi-ilk-650:         NOTRUN -> [SKIP][33] ([fdo#109271]) +2 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-ilk-650/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-jsl-1}:        NOTRUN -> [SKIP][34] ([fdo#112080])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-jsl-1/igt@i915_vm_bind_basic@basic-smem.html
    - {fi-jsl-1}:         NOTRUN -> [SKIP][35] ([fdo#112080])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-jsl-1/igt@i915_vm_bind_basic@basic-smem.html
    - {bat-jsl-3}:        NOTRUN -> [SKIP][36] ([fdo#112080])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-jsl-3/igt@i915_vm_bind_basic@basic-smem.html

  * {igt@i915_vm_bind_sanity@basic} (NEW):
    - fi-skl-guc:         NOTRUN -> [SKIP][37] ([fdo#109271]) +2 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-skl-guc/igt@i915_vm_bind_sanity@basic.html
    - fi-blb-e6850:       NOTRUN -> [SKIP][38] ([fdo#109271]) +2 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-blb-e6850/igt@i915_vm_bind_sanity@basic.html
    - fi-apl-guc:         NOTRUN -> [SKIP][39] ([fdo#109271]) +2 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-apl-guc/igt@i915_vm_bind_sanity@basic.html

  * igt@kms_chamelium@common-hpd-after-suspend:
    - bat-adlp-4:         NOTRUN -> [SKIP][40] ([fdo#111827])
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-adlp-4/igt@kms_chamelium@common-hpd-after-suspend.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions:
    - fi-bsw-kefka:       [PASS][41] -> [FAIL][42] ([i915#6298])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor@atomic-transitions.html

  * igt@kms_pipe_crc_basic@suspend-read-crc:
    - bat-adlp-4:         NOTRUN -> [SKIP][43] ([i915#3546])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-adlp-4/igt@kms_pipe_crc_basic@suspend-read-crc.html

  
#### Possible fixes ####

  * igt@gem_exec_gttfill@basic:
    - fi-pnv-d510:        [FAIL][44] ([i915#7229]) -> [PASS][45]
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/fi-pnv-d510/igt@gem_exec_gttfill@basic.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-pnv-d510/igt@gem_exec_gttfill@basic.html

  * igt@gem_exec_suspend@basic-s3@smem:
    - {bat-rplp-1}:       [DMESG-WARN][46] ([i915#2867]) -> [PASS][47]
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/bat-rplp-1/igt@gem_exec_suspend@basic-s3@smem.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-rplp-1/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@i915_selftest@live@hangcheck:
    - fi-icl-u2:          [DMESG-FAIL][48] ([i915#5591]) -> [PASS][49]
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/fi-icl-u2/igt@i915_selftest@live@hangcheck.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/fi-icl-u2/igt@i915_selftest@live@hangcheck.html

  * igt@i915_selftest@live@hugepages:
    - {bat-rpls-2}:       [DMESG-WARN][50] ([i915#5278]) -> [PASS][51]
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/bat-rpls-2/igt@i915_selftest@live@hugepages.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-rpls-2/igt@i915_selftest@live@hugepages.html

  * igt@i915_selftest@live@migrate:
    - bat-adlp-4:         [INCOMPLETE][52] ([i915#7308] / [i915#7348]) -> [PASS][53]
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/bat-adlp-4/igt@i915_selftest@live@migrate.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/bat-adlp-4/igt@i915_selftest@live@migrate.html

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

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [fdo#112080]: https://bugs.freedesktop.org/show_bug.cgi?id=112080
  [i915#1845]: https://gitlab.freedesktop.org/drm/intel/issues/1845
  [i915#1849]: https://gitlab.freedesktop.org/drm/intel/issues/1849
  [i915#2582]: https://gitlab.freedesktop.org/drm/intel/issues/2582
  [i915#2867]: https://gitlab.freedesktop.org/drm/intel/issues/2867
  [i915#3546]: https://gitlab.freedesktop.org/drm/intel/issues/3546
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4258]: https://gitlab.freedesktop.org/drm/intel/issues/4258
  [i915#5278]: https://gitlab.freedesktop.org/drm/intel/issues/5278
  [i915#5334]: https://gitlab.freedesktop.org/drm/intel/issues/5334
  [i915#5591]: https://gitlab.freedesktop.org/drm/intel/issues/5591
  [i915#6298]: https://gitlab.freedesktop.org/drm/intel/issues/6298
  [i915#7229]: https://gitlab.freedesktop.org/drm/intel/issues/7229
  [i915#7308]: https://gitlab.freedesktop.org/drm/intel/issues/7308
  [i915#7348]: https://gitlab.freedesktop.org/drm/intel/issues/7348


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

  * CI: CI-20190529 -> None
  * IGT: IGT_7074 -> IGTPW_8164

  CI-20190529: 20190529
  CI_DRM_12441: 72fca6c11d0f5c628a6251f7bc420838c89d6acc @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_8164: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/index.html
  IGT_7074: a7403583f1baee0548d86d1f2c9bb078384f997a @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git


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

+igt@gem_exec3_balancer@parallel-ordering
+igt@gem_exec3_basic@basic
+igt@gem_lmem_swapping@vm_bind
+igt@gem_shrink@vm_bind
+igt@gem_shrink@vm_bind-oom
+igt@gem_shrink@vm_bind-sanitycheck
+igt@gem_shrink@vm_bind-userptr
+igt@gem_shrink@vm_bind-userptr-dirty
+igt@i915_vm_bind_basic@2m
+igt@i915_vm_bind_basic@2m_sync_bind
+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_capture@basic
+igt@i915_vm_bind_sanity@basic

== Logs ==

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

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

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

* [igt-dev] ✓ Fi.CI.IGT: success for vm_bind: Add VM_BIND validation support (rev12)
  2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
                   ` (14 preceding siblings ...)
  2022-11-29  8:14 ` [igt-dev] ✓ Fi.CI.BAT: success for vm_bind: Add VM_BIND validation support (rev12) Patchwork
@ 2022-11-29 10:26 ` Patchwork
  15 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2022-11-29 10:26 UTC (permalink / raw)
  To: Niranjana Vishwanathapura; +Cc: igt-dev

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

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_12441_full -> IGTPW_8164_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

Participating hosts (10 -> 8)
------------------------------

  Missing    (2): pig-skl-6260u pig-glk-j5005 

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

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

### IGT changes ###

#### Possible regressions ####

  * {igt@gem_lmem_swapping@vm_bind} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][1] +12 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@gem_lmem_swapping@vm_bind.html

  * {igt@i915_vm_bind_basic@2m} (NEW):
    - {shard-dg1}:        NOTRUN -> [SKIP][2] +7 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-dg1-13/igt@i915_vm_bind_basic@2m.html

  * {igt@i915_vm_bind_basic@multi_ctxts} (NEW):
    - {shard-rkl}:        NOTRUN -> [SKIP][3] +8 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-1/igt@i915_vm_bind_basic@multi_ctxts.html

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

  * {igt@i915_vm_bind_capture@basic@bcs0-smem0} (NEW):
    - shard-iclb:         NOTRUN -> [FAIL][5] +7 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb6/igt@i915_vm_bind_capture@basic@bcs0-smem0.html

  * {igt@i915_vm_bind_capture@basic@bcs0-userptr} (NEW):
    - {shard-rkl}:        NOTRUN -> [FAIL][6] +7 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@i915_vm_bind_capture@basic@bcs0-userptr.html

  * {igt@i915_vm_bind_capture@basic@rcs0-userptr} (NEW):
    - shard-apl:          NOTRUN -> [FAIL][7] +7 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl8/igt@i915_vm_bind_capture@basic@rcs0-userptr.html

  * {igt@i915_vm_bind_capture@basic@vcs0-smem0} (NEW):
    - shard-tglb:         NOTRUN -> [FAIL][8] +9 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb8/igt@i915_vm_bind_capture@basic@vcs0-smem0.html

  * {igt@i915_vm_bind_capture@basic@vcs1-userptr} (NEW):
    - {shard-dg1}:        NOTRUN -> [FAIL][9] +14 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-dg1-17/igt@i915_vm_bind_capture@basic@vcs1-userptr.html

  
New tests
---------

  New tests have been introduced between CI_DRM_12441_full and IGTPW_8164_full:

### New IGT tests (29) ###

  * igt@gem_exec3_balancer@parallel-ordering:
    - Statuses : 3 skip(s)
    - Exec time: [0.0] s

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

  * igt@gem_lmem_swapping@vm_bind:
    - Statuses : 3 skip(s)
    - Exec time: [0.0] s

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

  * igt@i915_vm_bind_basic@2m_sync_bind:
    - 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 : 3 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 : 3 skip(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic:
    - Statuses :
    - Exec time: [None] s

  * igt@i915_vm_bind_capture@basic@bcs0-lmem0:
    - Statuses : 1 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@bcs0-smem0:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@bcs0-userptr:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@rcs0-lmem0:
    - Statuses : 1 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@rcs0-smem0:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@rcs0-userptr:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vcs0-lmem0:
    - Statuses : 1 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vcs0-smem0:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vcs0-userptr:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vcs1-lmem0:
    - Statuses : 1 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vcs1-smem0:
    - Statuses : 2 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vcs1-userptr:
    - Statuses : 2 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vecs0-lmem0:
    - Statuses : 1 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vecs0-smem0:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

  * igt@i915_vm_bind_capture@basic@vecs0-userptr:
    - Statuses : 5 fail(s)
    - Exec time: [0.0] s

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

  

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

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

### IGT changes ###

#### Issues hit ####

  * igt@feature_discovery@display-3x:
    - shard-tglb:         NOTRUN -> [SKIP][10] ([i915#1839])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb6/igt@feature_discovery@display-3x.html

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

  * igt@gem_exec_balancer@parallel-ordering:
    - shard-tglb:         NOTRUN -> [FAIL][12] ([i915#6117])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@gem_exec_balancer@parallel-ordering.html

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

  * igt@gem_exec_params@secure-non-root:
    - shard-tglb:         NOTRUN -> [SKIP][15] ([fdo#112283])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb8/igt@gem_exec_params@secure-non-root.html

  * igt@gem_pxp@create-valid-protected-context:
    - shard-iclb:         NOTRUN -> [SKIP][16] ([i915#4270])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb5/igt@gem_pxp@create-valid-protected-context.html

  * igt@gem_pxp@protected-raw-src-copy-not-readible:
    - shard-tglb:         NOTRUN -> [SKIP][17] ([i915#4270]) +1 similar issue
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@gem_pxp@protected-raw-src-copy-not-readible.html

  * igt@gem_render_copy@y-tiled-to-vebox-yf-tiled:
    - shard-iclb:         NOTRUN -> [SKIP][18] ([i915#768])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb3/igt@gem_render_copy@y-tiled-to-vebox-yf-tiled.html

  * igt@gem_softpin@evict-snoop-interruptible:
    - shard-tglb:         NOTRUN -> [SKIP][19] ([fdo#109312])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb3/igt@gem_softpin@evict-snoop-interruptible.html

  * igt@gem_userptr_blits@coherency-unsync:
    - shard-iclb:         NOTRUN -> [SKIP][20] ([i915#3297]) +1 similar issue
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb5/igt@gem_userptr_blits@coherency-unsync.html

  * igt@gem_userptr_blits@unsync-unmap-cycles:
    - shard-tglb:         NOTRUN -> [SKIP][21] ([i915#3297]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb6/igt@gem_userptr_blits@unsync-unmap-cycles.html

  * igt@gen7_exec_parse@batch-without-end:
    - shard-tglb:         NOTRUN -> [SKIP][22] ([fdo#109289])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@gen7_exec_parse@batch-without-end.html

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

  * igt@gen9_exec_parse@cmd-crossing-page:
    - shard-iclb:         NOTRUN -> [SKIP][24] ([i915#2856]) +1 similar issue
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb5/igt@gen9_exec_parse@cmd-crossing-page.html

  * igt@i915_module_load@load:
    - shard-tglb:         NOTRUN -> [SKIP][25] ([i915#6227])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb1/igt@i915_module_load@load.html
    - shard-iclb:         NOTRUN -> [SKIP][26] ([i915#6227])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb3/igt@i915_module_load@load.html

  * igt@i915_module_load@reload-no-display:
    - shard-iclb:         [PASS][27] -> [DMESG-WARN][28] ([i915#2867])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb1/igt@i915_module_load@reload-no-display.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb3/igt@i915_module_load@reload-no-display.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-tglb:         NOTRUN -> [FAIL][29] ([i915#3989] / [i915#454])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_pm_dc@dc6-psr:
    - shard-iclb:         [PASS][30] -> [FAIL][31] ([i915#3989] / [i915#454])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb5/igt@i915_pm_dc@dc6-psr.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb3/igt@i915_pm_dc@dc6-psr.html

  * igt@i915_pm_rc6_residency@rc6-fence:
    - shard-tglb:         NOTRUN -> [WARN][32] ([i915#2681])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@i915_pm_rc6_residency@rc6-fence.html

  * igt@kms_atomic_transition@plane-all-modeset-transition-fencing:
    - shard-tglb:         NOTRUN -> [SKIP][33] ([i915#1769])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@kms_atomic_transition@plane-all-modeset-transition-fencing.html

  * igt@kms_big_fb@4-tiled-16bpp-rotate-180:
    - shard-tglb:         NOTRUN -> [SKIP][34] ([i915#5286]) +1 similar issue
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb1/igt@kms_big_fb@4-tiled-16bpp-rotate-180.html

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

  * igt@kms_big_fb@x-tiled-16bpp-rotate-270:
    - shard-tglb:         NOTRUN -> [SKIP][36] ([fdo#111614]) +2 similar issues
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb6/igt@kms_big_fb@x-tiled-16bpp-rotate-270.html
    - shard-iclb:         NOTRUN -> [SKIP][37] ([fdo#110725] / [fdo#111614])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb1/igt@kms_big_fb@x-tiled-16bpp-rotate-270.html

  * igt@kms_big_fb@yf-tiled-addfb-size-offset-overflow:
    - shard-tglb:         NOTRUN -> [SKIP][38] ([fdo#111615]) +3 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@kms_big_fb@yf-tiled-addfb-size-offset-overflow.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-hflip:
    - shard-iclb:         NOTRUN -> [SKIP][39] ([fdo#110723]) +1 similar issue
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb8/igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-hflip.html

  * igt@kms_ccs@pipe-a-crc-sprite-planes-basic-y_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][40] ([i915#3689]) +1 similar issue
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@kms_ccs@pipe-a-crc-sprite-planes-basic-y_tiled_ccs.html

  * igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_gen12_rc_ccs_cc:
    - shard-apl:          NOTRUN -> [SKIP][41] ([fdo#109271] / [i915#3886]) +3 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl6/igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-random-ccs-data-4_tiled_dg2_rc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][42] ([i915#3689] / [i915#6095]) +2 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@kms_ccs@pipe-b-random-ccs-data-4_tiled_dg2_rc_ccs.html

  * igt@kms_ccs@pipe-b-random-ccs-data-y_tiled_gen12_mc_ccs:
    - shard-iclb:         NOTRUN -> [SKIP][43] ([fdo#109278] / [i915#3886]) +4 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb7/igt@kms_ccs@pipe-b-random-ccs-data-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-c-ccs-on-another-bo-y_tiled_gen12_rc_ccs:
    - shard-iclb:         NOTRUN -> [SKIP][44] ([fdo#109278]) +12 similar issues
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb8/igt@kms_ccs@pipe-c-ccs-on-another-bo-y_tiled_gen12_rc_ccs.html

  * igt@kms_ccs@pipe-c-ccs-on-another-bo-yf_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][45] ([fdo#111615] / [i915#3689]) +5 similar issues
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb6/igt@kms_ccs@pipe-c-ccs-on-another-bo-yf_tiled_ccs.html

  * igt@kms_ccs@pipe-c-crc-sprite-planes-basic-y_tiled_gen12_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][46] ([i915#3689] / [i915#3886]) +2 similar issues
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@kms_ccs@pipe-c-crc-sprite-planes-basic-y_tiled_gen12_mc_ccs.html

  * igt@kms_chamelium@dp-hpd-fast:
    - shard-tglb:         NOTRUN -> [SKIP][47] ([fdo#109284] / [fdo#111827]) +2 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb8/igt@kms_chamelium@dp-hpd-fast.html
    - shard-iclb:         NOTRUN -> [SKIP][48] ([fdo#109284] / [fdo#111827]) +2 similar issues
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb5/igt@kms_chamelium@dp-hpd-fast.html

  * igt@kms_chamelium@vga-hpd-after-suspend:
    - shard-apl:          NOTRUN -> [SKIP][49] ([fdo#109271] / [fdo#111827]) +2 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl7/igt@kms_chamelium@vga-hpd-after-suspend.html

  * igt@kms_color@ctm-0-75@pipe-c-edp-1:
    - shard-tglb:         NOTRUN -> [FAIL][50] ([i915#315] / [i915#6946]) +3 similar issues
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb3/igt@kms_color@ctm-0-75@pipe-c-edp-1.html

  * igt@kms_content_protection@dp-mst-lic-type-1:
    - shard-iclb:         NOTRUN -> [SKIP][51] ([i915#3116])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb7/igt@kms_content_protection@dp-mst-lic-type-1.html

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

  * igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions:
    - shard-apl:          [PASS][53] -> [FAIL][54] ([i915#2346])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-apl7/igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl2/igt@kms_cursor_legacy@flip-vs-cursor@atomic-transitions.html

  * igt@kms_dp_aux_dev:
    - shard-iclb:         [PASS][55] -> [DMESG-WARN][56] ([i915#4391])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb1/igt@kms_dp_aux_dev.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb7/igt@kms_dp_aux_dev.html

  * igt@kms_fbcon_fbt@fbc:
    - shard-apl:          NOTRUN -> [FAIL][57] ([i915#4767])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl7/igt@kms_fbcon_fbt@fbc.html
    - shard-tglb:         NOTRUN -> [FAIL][58] ([i915#4767])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@kms_fbcon_fbt@fbc.html
    - shard-iclb:         NOTRUN -> [FAIL][59] ([i915#4767])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb7/igt@kms_fbcon_fbt@fbc.html

  * igt@kms_flip@2x-flip-vs-expired-vblank-interruptible:
    - shard-iclb:         NOTRUN -> [SKIP][60] ([fdo#109274]) +1 similar issue
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb8/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html

  * igt@kms_flip@2x-wf_vblank-ts-check-interruptible:
    - shard-tglb:         NOTRUN -> [SKIP][61] ([fdo#109274] / [fdo#111825] / [i915#3637]) +2 similar issues
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@kms_flip@2x-wf_vblank-ts-check-interruptible.html

  * igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-downscaling@pipe-a-valid-mode:
    - shard-iclb:         NOTRUN -> [SKIP][62] ([i915#2587] / [i915#2672]) +4 similar issues
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb7/igt@kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-downscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-32bpp-yftile-to-32bpp-yftileccs-upscaling@pipe-a-valid-mode:
    - shard-tglb:         NOTRUN -> [SKIP][63] ([i915#2587] / [i915#2672])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb8/igt@kms_flip_scaled_crc@flip-32bpp-yftile-to-32bpp-yftileccs-upscaling@pipe-a-valid-mode.html

  * igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-upscaling@pipe-a-default-mode:
    - shard-iclb:         NOTRUN -> [SKIP][64] ([i915#2672]) +5 similar issues
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb3/igt@kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-upscaling@pipe-a-default-mode.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-blt:
    - shard-tglb:         NOTRUN -> [SKIP][65] ([i915#6497]) +6 similar issues
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-blt:
    - shard-tglb:         NOTRUN -> [SKIP][66] ([fdo#109280] / [fdo#111825]) +15 similar issues
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-mmap-wc:
    - shard-iclb:         NOTRUN -> [SKIP][67] ([fdo#109280]) +12 similar issues
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb2/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-mmap-wc.html

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

  * igt@kms_plane_lowres@tiling-none@pipe-a-edp-1:
    - shard-iclb:         NOTRUN -> [SKIP][69] ([i915#3536]) +2 similar issues
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb8/igt@kms_plane_lowres@tiling-none@pipe-a-edp-1.html

  * igt@kms_plane_multiple@tiling-4:
    - shard-iclb:         NOTRUN -> [SKIP][70] ([i915#3555]) +2 similar issues
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb3/igt@kms_plane_multiple@tiling-4.html
    - shard-tglb:         NOTRUN -> [SKIP][71] ([i915#3555])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb8/igt@kms_plane_multiple@tiling-4.html

  * igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-b-edp-1:
    - shard-iclb:         NOTRUN -> [SKIP][72] ([i915#5176]) +1 similar issue
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb3/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats@pipe-b-edp-1.html

  * igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-edp-1:
    - shard-tglb:         NOTRUN -> [SKIP][73] ([i915#5235]) +3 similar issues
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@kms_plane_scaling@planes-downscale-factor-0-25@pipe-c-edp-1.html

  * igt@kms_psr2_su@page_flip-nv12:
    - shard-iclb:         NOTRUN -> [SKIP][74] ([fdo#109642] / [fdo#111068] / [i915#658])
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb1/igt@kms_psr2_su@page_flip-nv12.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-tglb:         NOTRUN -> [SKIP][75] ([i915#7037])
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb5/igt@kms_psr2_su@page_flip-p010.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-tglb:         NOTRUN -> [FAIL][76] ([i915#132] / [i915#3467]) +1 similar issue
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb1/igt@kms_psr@psr2_cursor_blt.html

  * igt@kms_psr@psr2_cursor_mmap_gtt:
    - shard-iclb:         [PASS][77] -> [SKIP][78] ([fdo#109441]) +2 similar issues
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_gtt.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb8/igt@kms_psr@psr2_cursor_mmap_gtt.html

  * igt@kms_psr_stress_test@invalidate-primary-flip-overlay:
    - shard-tglb:         [PASS][79] -> [SKIP][80] ([i915#5519])
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-tglb2/igt@kms_psr_stress_test@invalidate-primary-flip-overlay.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb7/igt@kms_psr_stress_test@invalidate-primary-flip-overlay.html
    - shard-iclb:         [PASS][81] -> [SKIP][82] ([i915#5519])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb3/igt@kms_psr_stress_test@invalidate-primary-flip-overlay.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb6/igt@kms_psr_stress_test@invalidate-primary-flip-overlay.html

  * igt@kms_writeback@writeback-invalid-parameters:
    - shard-iclb:         NOTRUN -> [SKIP][83] ([i915#2437])
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb5/igt@kms_writeback@writeback-invalid-parameters.html

  
#### Possible fixes ####

  * igt@api_intel_allocator@fork-simple-stress-signal:
    - shard-tglb:         [INCOMPLETE][84] ([i915#6453]) -> [PASS][85]
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-tglb8/igt@api_intel_allocator@fork-simple-stress-signal.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb8/igt@api_intel_allocator@fork-simple-stress-signal.html

  * igt@fbdev@unaligned-write:
    - {shard-rkl}:        [SKIP][86] ([i915#2582]) -> [PASS][87]
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-2/igt@fbdev@unaligned-write.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-5/igt@fbdev@unaligned-write.html

  * igt@gem_eio@kms:
    - {shard-dg1}:        [FAIL][88] ([i915#5784]) -> [PASS][89]
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-dg1-17/igt@gem_eio@kms.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-dg1-15/igt@gem_eio@kms.html

  * igt@gem_exec_balancer@parallel-bb-first:
    - shard-iclb:         [SKIP][90] ([i915#4525]) -> [PASS][91] +2 similar issues
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb7/igt@gem_exec_balancer@parallel-bb-first.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb2/igt@gem_exec_balancer@parallel-bb-first.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - {shard-rkl}:        [FAIL][92] ([i915#2842]) -> [PASS][93]
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-2/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-3/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace@bcs0:
    - shard-iclb:         [FAIL][94] ([i915#2842]) -> [PASS][95]
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb1/igt@gem_exec_fair@basic-pace@bcs0.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb7/igt@gem_exec_fair@basic-pace@bcs0.html

  * igt@gem_exec_reloc@basic-wc-read-noreloc:
    - {shard-rkl}:        [SKIP][96] ([i915#3281]) -> [PASS][97] +5 similar issues
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-6/igt@gem_exec_reloc@basic-wc-read-noreloc.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-5/igt@gem_exec_reloc@basic-wc-read-noreloc.html

  * igt@gem_tiled_partial_pwrite_pread@writes:
    - {shard-rkl}:        [SKIP][98] ([i915#3282]) -> [PASS][99] +4 similar issues
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-6/igt@gem_tiled_partial_pwrite_pread@writes.html
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-5/igt@gem_tiled_partial_pwrite_pread@writes.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-apl:          [DMESG-WARN][100] ([i915#5566] / [i915#716]) -> [PASS][101]
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-apl6/igt@gen9_exec_parse@allowed-all.html
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl7/igt@gen9_exec_parse@allowed-all.html

  * igt@gen9_exec_parse@bb-secure:
    - {shard-rkl}:        [SKIP][102] ([i915#2527]) -> [PASS][103]
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-2/igt@gen9_exec_parse@bb-secure.html
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-5/igt@gen9_exec_parse@bb-secure.html

  * igt@i915_pipe_stress@stress-xrgb8888-ytiled:
    - {shard-rkl}:        [SKIP][104] ([i915#4098]) -> [PASS][105]
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-5/igt@i915_pipe_stress@stress-xrgb8888-ytiled.html
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@i915_pipe_stress@stress-xrgb8888-ytiled.html

  * igt@i915_pm_rc6_residency@rc6-idle@vcs0:
    - {shard-dg1}:        [FAIL][106] ([i915#3591]) -> [PASS][107]
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-dg1-19/igt@i915_pm_rc6_residency@rc6-idle@vcs0.html
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-dg1-19/igt@i915_pm_rc6_residency@rc6-idle@vcs0.html

  * igt@i915_pm_rpm@cursor-dpms:
    - {shard-rkl}:        [SKIP][108] ([i915#1849]) -> [PASS][109]
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-5/igt@i915_pm_rpm@cursor-dpms.html
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@i915_pm_rpm@cursor-dpms.html

  * igt@i915_pm_rpm@pm-tiling:
    - {shard-rkl}:        [SKIP][110] ([fdo#109308]) -> [PASS][111]
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-1/igt@i915_pm_rpm@pm-tiling.html
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@i915_pm_rpm@pm-tiling.html

  * igt@kms_big_fb@linear-32bpp-rotate-0:
    - {shard-rkl}:        [SKIP][112] ([i915#1845] / [i915#4098]) -> [PASS][113] +14 similar issues
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-1/igt@kms_big_fb@linear-32bpp-rotate-0.html
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@kms_big_fb@linear-32bpp-rotate-0.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180:
    - shard-iclb:         [DMESG-WARN][114] ([i915#4391]) -> [PASS][115]
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb7/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180.html
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb6/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-plflip-blt:
    - {shard-rkl}:        [SKIP][116] ([i915#1849] / [i915#4098]) -> [PASS][117] +10 similar issues
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-1/igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-plflip-blt.html
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-plflip-blt.html

  * igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes:
    - {shard-rkl}:        [SKIP][118] ([i915#1849] / [i915#3558]) -> [PASS][119] +1 similar issue
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-2/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html

  * igt@kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-5@pipe-b-edp-1:
    - shard-iclb:         [SKIP][120] ([i915#5176]) -> [PASS][121] +2 similar issues
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb2/igt@kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-5@pipe-b-edp-1.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb6/igt@kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-5@pipe-b-edp-1.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-iclb:         [SKIP][122] ([fdo#109441]) -> [PASS][123] +2 similar issues
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb6/igt@kms_psr@psr2_cursor_blt.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb2/igt@kms_psr@psr2_cursor_blt.html

  * igt@kms_psr@suspend:
    - {shard-rkl}:        [SKIP][124] ([i915#1072]) -> [PASS][125]
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-1/igt@kms_psr@suspend.html
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-6/igt@kms_psr@suspend.html

  * igt@perf@gen12-unprivileged-single-ctx-counters:
    - {shard-rkl}:        [SKIP][126] ([fdo#109289]) -> [PASS][127]
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-rkl-5/igt@perf@gen12-unprivileged-single-ctx-counters.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-rkl-4/igt@perf@gen12-unprivileged-single-ctx-counters.html

  
#### Warnings ####

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-tglb:         [SKIP][128] ([i915#2848]) -> [FAIL][129] ([i915#2842])
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-tglb6/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb2/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_pread@exhaustion:
    - shard-tglb:         [WARN][130] ([i915#2658]) -> [INCOMPLETE][131] ([i915#7248]) +1 similar issue
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-tglb1/igt@gem_pread@exhaustion.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-tglb8/igt@gem_pread@exhaustion.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area:
    - shard-iclb:         [SKIP][132] ([fdo#111068] / [i915#658]) -> [SKIP][133] ([i915#2920])
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-iclb8/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-iclb2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area.html

  * igt@runner@aborted:
    - shard-apl:          ([FAIL][134], [FAIL][135], [FAIL][136], [FAIL][137]) ([fdo#109271] / [i915#3002] / [i915#4312]) -> ([FAIL][138], [FAIL][139], [FAIL][140]) ([i915#3002] / [i915#4312])
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-apl6/igt@runner@aborted.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-apl6/igt@runner@aborted.html
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-apl3/igt@runner@aborted.html
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12441/shard-apl7/igt@runner@aborted.html
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl3/igt@runner@aborted.html
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl3/igt@runner@aborted.html
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/shard-apl1/igt@runner@aborted.html

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

  [fdo#103375]: https://bugs.freedesktop.org/show_bug.cgi?id=103375
  [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#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295
  [fdo#109308]: https://bugs.freedesktop.org/show_bug.cgi?id=109308
  [fdo#109309]: https://bugs.freedesktop.org/show_bug.cgi?id=109309
  [fdo#109312]: https://bugs.freedesktop.org/show_bug.cgi?id=109312
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109506]: https://bugs.freedesktop.org/show_bug.cgi?id=109506
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110723]: https://bugs.freedesktop.org/show_bug.cgi?id=110723
  [fdo#110725]: https://bugs.freedesktop.org/show_bug.cgi?id=110725
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
  [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
  [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#132]: https://gitlab.freedesktop.org/drm/intel/issues/132
  [i915#1397]: https://gitlab.freedesktop.org/drm/intel/issues/1397
  [i915#1755]: https://gitlab.freedesktop.org/drm/intel/issues/1755
  [i915#1769]: https://gitlab.freedesktop.org/drm/intel/issues/1769
  [i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
  [i915#1839]: https://gitlab.freedesktop.org/drm/intel/issues/1839
  [i915#1845]: https://gitlab.freedesktop.org/drm/intel/issues/1845
  [i915#1849]: https://gitlab.freedesktop.org/drm/intel/issues/1849
  [i915#2232]: https://gitlab.freedesktop.org/drm/intel/issues/2232
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2434]: https://gitlab.freedesktop.org/drm/intel/issues/2434
  [i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
  [i915#2527]: https://gitlab.freedesktop.org/drm/intel/issues/2527
  [i915#2582]: https://gitlab.freedesktop.org/drm/intel/issues/2582
  [i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
  [i915#2658]: https://gitlab.freedesktop.org/drm/intel/issues/2658
  [i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
  [i915#2681]: https://gitlab.freedesktop.org/drm/intel/issues/2681
  [i915#2705]: https://gitlab.freedesktop.org/drm/intel/issues/2705
  [i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
  [i915#2846]: https://gitlab.freedesktop.org/drm/intel/issues/2846
  [i915#2848]: https://gitlab.freedesktop.org/drm/intel/issues/2848
  [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#3002]: https://gitlab.freedesktop.org/drm/intel/issues/3002
  [i915#3116]: https://gitlab.freedesktop.org/drm/intel/issues/3116
  [i915#315]: https://gitlab.freedesktop.org/drm/intel/issues/315
  [i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
  [i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
  [i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
  [i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
  [i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
  [i915#3467]: https://gitlab.freedesktop.org/drm/intel/issues/3467
  [i915#3469]: https://gitlab.freedesktop.org/drm/intel/issues/3469
  [i915#3536]: https://gitlab.freedesktop.org/drm/intel/issues/3536
  [i915#3539]: https://gitlab.freedesktop.org/drm/intel/issues/3539
  [i915#3546]: https://gitlab.freedesktop.org/drm/intel/issues/3546
  [i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
  [i915#3558]: https://gitlab.freedesktop.org/drm/intel/issues/3558
  [i915#3591]: https://gitlab.freedesktop.org/drm/intel/issues/3591
  [i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
  [i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
  [i915#3689]: https://gitlab.freedesktop.org/drm/intel/issues/3689
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#3734]: https://gitlab.freedesktop.org/drm/intel/issues/3734
  [i915#3742]: https://gitlab.freedesktop.org/drm/intel/issues/3742
  [i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
  [i915#3886]: https://gitlab.freedesktop.org/drm/intel/issues/3886
  [i915#3989]: https://gitlab.freedesktop.org/drm/intel/issues/3989
  [i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4098]: https://gitlab.freedesktop.org/drm/intel/issues/4098
  [i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4391]: https://gitlab.freedesktop.org/drm/intel/issues/4391
  [i915#4525]: https://gitlab.freedesktop.org/drm/intel/issues/4525
  [i915#4538]: https://gitlab.freedesktop.org/drm/intel/issues/4538
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#4565]: https://gitlab.freedesktop.org/drm/intel/issues/4565
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4767]: https://gitlab.freedesktop.org/drm/intel/issues/4767
  [i915#4771]: https://gitlab.freedesktop.org/drm/intel/issues/4771
  [i915#4833]: https://gitlab.freedesktop.org/drm/intel/issues/4833
  [i915#4852]: https://gitlab.freedesktop.org/drm/intel/issues/4852
  [i915#4855]: https://gitlab.freedesktop.org/drm/intel/issues/4855
  [i915#4859]: https://gitlab.freedesktop.org/drm/intel/issues/4859
  [i915#4860]: https://gitlab.freedesktop.org/drm/intel/issues/4860
  [i915#4885]: https://gitlab.freedesktop.org/drm/intel/issues/4885
  [i915#4958]: https://gitlab.freedesktop.org/drm/intel/issues/4958
  [i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
  [i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
  [i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
  [i915#5289]: https://gitlab.freedesktop.org/drm/intel/issues/5289
  [i915#5325]: https://gitlab.freedesktop.org/drm/intel/issues/5325
  [i915#5327]: https://gitlab.freedesktop.org/drm/intel/issues/5327
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533
  [i915#5439]: https://gitlab.freedesktop.org/drm/intel/issues/5439
  [i915#5519]: https://gitlab.freedesktop.org/drm/intel/issues/5519
  [i915#5563]: https://gitlab.freedesktop.org/drm/intel/issues/5563
  [i915#5566]: https://gitlab.freedesktop.org/drm/intel/issues/5566
  [i915#5723]: https://gitlab.freedesktop.org/drm/intel/issues/5723
  [i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
  [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#6248]: https://gitlab.freedesktop.org/drm/intel/issues/6248
  [i915#6252]: https://gitlab.freedesktop.org/drm/intel/issues/6252
  [i915#6268]: https://gitlab.freedesktop.org/drm/intel/issues/6268
  [i915#6355]: https://gitlab.freedesktop.org/drm/intel/issues/6355
  [i915#6453]: https://gitlab.freedesktop.org/drm/intel/issues/6453
  [i915#6463]: https://gitlab.freedesktop.org/drm/intel/issues/6463
  [i915#6493]: https://gitlab.freedesktop.org/drm/intel/issues/6493
  [i915#6497]: https://gitlab.freedesktop.org/drm/intel/issues/6497
  [i915#6524]: https://gitlab.freedesktop.org/drm/intel/issues/6524
  [i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
  [i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
  [i915#6768]: https://gitlab.freedesktop.org/drm/intel/issues/6768
  [i915#6946]: https://gitlab.freedesktop.org/drm/intel/issues/6946
  [i915#7037]: https://gitlab.freedesktop.org/drm/intel/issues/7037
  [i915#7116]: https://gitlab.freedesktop.org/drm/intel/issues/7116
  [i915#7118]: https://gitlab.freedesktop.org/drm/intel/issues/7118
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#7248]: https://gitlab.freedesktop.org/drm/intel/issues/7248
  [i915#7478]: https://gitlab.freedesktop.org/drm/intel/issues/7478
  [i915#7561]: https://gitlab.freedesktop.org/drm/intel/issues/7561
  [i915#768]: https://gitlab.freedesktop.org/drm/intel/issues/768


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

  * CI: CI-20190529 -> None
  * IGT: IGT_7074 -> IGTPW_8164
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_12441: 72fca6c11d0f5c628a6251f7bc420838c89d6acc @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_8164: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_8164/index.html
  IGT_7074: a7403583f1baee0548d86d1f2c9bb078384f997a @ 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_8164/index.html

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

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

* Re: [igt-dev] [PATCH i-g-t v8 14/14] tests/i915/vm_bind: Test capture of persistent mappings
  2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 14/14] tests/i915/vm_bind: Test capture of persistent mappings Niranjana Vishwanathapura
@ 2022-12-06 17:34   ` Matthew Auld
  2022-12-08 13:56     ` Niranjana Vishwanathapura
  0 siblings, 1 reply; 19+ messages in thread
From: Matthew Auld @ 2022-12-06 17:34 UTC (permalink / raw)
  To: Niranjana Vishwanathapura, igt-dev
  Cc: tvrtko.ursulin, thomas.hellstrom, daniel.vetter, petri.latvala

On 29/11/2022 07:23, Niranjana Vishwanathapura wrote:
> Add i915_vm_bind_capture to validate dump capture of persistent
> mappings including partial binding.
> 
> Signed-off-by: Brian Welty <brian.welty@intel.com>
> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
> ---
>   tests/i915/i915_vm_bind_capture.c | 445 ++++++++++++++++++++++++++++++
>   tests/meson.build                 |   1 +
>   2 files changed, 446 insertions(+)
>   create mode 100644 tests/i915/i915_vm_bind_capture.c
> 
> diff --git a/tests/i915/i915_vm_bind_capture.c b/tests/i915/i915_vm_bind_capture.c
> new file mode 100644
> index 000000000..f82f53b96
> --- /dev/null
> +++ b/tests/i915/i915_vm_bind_capture.c
> @@ -0,0 +1,445 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2022 Intel Corporation. All rights reserved.
> + */
> +
> +/** @file gem_vm_bind_capture.c
> + *
> + * This is the test for dump capture of VM_BIND mappings.
> + *
> + * The goal is to simply ensure that capture of persistent mappings
> + * works. This test in part is derived from gem_exec_capture.c
> + */
> +
> +#include <sys/poll.h>
> +#include <zlib.h>
> +#include <sched.h>
> +
> +#include "i915/gem.h"
> +#include "i915/gem_create.h"
> +#include "i915/gem_vm.h"
> +#include "i915/i915_vm_bind.h"
> +#include "igt.h"
> +#include "igt_device.h"
> +#include "igt_syncobj.h"
> +#include "igt_sysfs.h"
> +#include "igt_types.h"
> +#include "intel_ctx.h"
> +
> +
> +#define PAGE_SIZE   4096
> +
> +#define NUM_OBJS  3
> +#define NUM_MAPS  4
> +#define BATCH_VA  0x8000000
> +
> +IGT_TEST_DESCRIPTION("Check that we capture the user specified persistent mappings on a hang");
> +
> +struct mappings {
> +	uint32_t  obj;
> +	uint64_t  va;
> +	uint64_t  offset;
> +	uint64_t  length;
> +
> +	uint32_t  idx;
> +	uint32_t  expect;
> +	bool      found;
> +};
> +
> +static unsigned long zlib_inflate(uint32_t **ptr, unsigned long len)
> +{
> +	struct z_stream_s zstream;
> +	void *out;
> +
> +	memset(&zstream, 0, sizeof(zstream));
> +
> +	zstream.next_in = (unsigned char *)*ptr;
> +	zstream.avail_in = 4*len;
> +
> +	if (inflateInit(&zstream) != Z_OK)
> +		return 0;
> +
> +	out = malloc(128*4096); /* approximate obj size */
> +	zstream.next_out = out;
> +	zstream.avail_out = 128*4096;
> +
> +	do {
> +		switch (inflate(&zstream, Z_SYNC_FLUSH)) {
> +		case Z_STREAM_END:
> +			goto end;
> +		case Z_OK:
> +			break;
> +		default:
> +			inflateEnd(&zstream);
> +			return 0;
> +		}
> +
> +		if (zstream.avail_out)
> +			break;
> +
> +		out = realloc(out, 2*zstream.total_out);
> +		if (out == NULL) {
> +			inflateEnd(&zstream);
> +			return 0;
> +		}
> +
> +		zstream.next_out = (unsigned char *)out + zstream.total_out;
> +		zstream.avail_out = zstream.total_out;
> +	} while (1);
> +end:
> +	inflateEnd(&zstream);
> +	free(*ptr);
> +	*ptr = out;
> +	return zstream.total_out / 4;
> +}
> +
> +static unsigned long
> +ascii85_decode(char *in, uint32_t **out, bool inflate, char **end)
> +{
> +	unsigned long len = 0, size = 1024;
> +
> +	*out = realloc(*out, sizeof(uint32_t)*size);
> +	if (*out == NULL)
> +		return 0;
> +
> +	while (*in >= '!' && *in <= 'z') {
> +		uint32_t v = 0;
> +
> +		if (len == size) {
> +			size *= 2;
> +			*out = realloc(*out, sizeof(uint32_t)*size);
> +			if (*out == NULL)
> +				return 0;
> +		}
> +
> +		if (*in == 'z') {
> +			in++;
> +		} else {
> +			v += in[0] - 33; v *= 85;
> +			v += in[1] - 33; v *= 85;
> +			v += in[2] - 33; v *= 85;
> +			v += in[3] - 33; v *= 85;
> +			v += in[4] - 33;
> +			in += 5;
> +		}
> +		(*out)[len++] = v;
> +	}
> +	*end = in;
> +
> +	if (!inflate)
> +		return len;
> +
> +	return zlib_inflate(out, len);
> +}
> +
> +static int check_error_state(int dir, struct mappings *map, uint32_t num_maps)
> +{
> +	char *error, *str;
> +	int blobs = 0;
> +
> +	errno = 0;
> +	error = igt_sysfs_get(dir, "error");
> +	igt_sysfs_set(dir, "error", "Begone!");
> +	igt_assert(error);
> +	igt_assert(errno != ENOMEM);
> +	igt_debug("%s\n", error);
> +
> +	/* render ring --- user = 0x00000000 ffffd000 */
> +	for (str = error; (str = strstr(str, "--- user = ")); ) {
> +		uint32_t *data = NULL;
> +		uint64_t addr;
> +		unsigned long i, j, sz;
> +		unsigned long start;
> +		unsigned long end;
> +
> +		if (strncmp(str, "--- user = 0x", 13))
> +			break;
> +		str += 13;
> +		addr = strtoul(str, &str, 16);
> +		addr <<= 32;
> +		addr |= strtoul(str + 1, &str, 16);
> +		igt_assert(*str++ == '\n');
> +
> +		start = 0;
> +		end = num_maps;
> +		while (end > start) {
> +			i = (end - start) / 2 + start;
> +			if (map[i].va < addr)
> +				start = i + 1;
> +			else if (map[i].va > addr)
> +				end = i;
> +			else
> +				break;
> +		}
> +
> +		igt_assert(map[i].va == addr);
> +		igt_assert(!map[i].found);
> +		map[i].found = true;
> +		igt_debug("offset:%"PRIx64", index:%d\n",
> +			  addr, map[i].idx);
> +
> +		/* gtt_page_sizes = 0x00010000 */
> +		if (strncmp(str, "gtt_page_sizes = 0x", 19) == 0) {
> +			str += 19 + 8;
> +			igt_assert(*str++ == '\n');
> +		}
> +
> +		if (!(*str == ':' || *str == '~'))
> +			continue;
> +
> +		igt_debug("blob:%.64s\n", str);
> +		sz = ascii85_decode(str + 1, &data, *str == ':', &str);
> +		igt_debug("Found addr 0x%lx sz 0x%lx\n", addr, sz);
> +		igt_assert_eq(4 * sz, map[i].length);
> +		igt_assert(*str++ == '\n');
> +		str = strchr(str, '-');
> +
> +		for (j = 0; j < sz; j++)
> +			igt_assert_eq(data[j], map[i].expect + j);
> +
> +		blobs++;
> +		free(data);
> +	}
> +
> +	free(error);
> +	return blobs;
> +}

Is all of this copy-paste from another test? I didn't check, but if 
possible maybe consider moving into lib and re-use instead.

> +
> +static int gem_recurse(uint32_t *batch, uint64_t batch_va)
> +{
> +	*batch++ = MI_BATCH_BUFFER_START | 1 << 8 | 1;
> +	*batch++ = lower_32_bits(batch_va);
> +	*batch++ = upper_32_bits(batch_va);
> +	*batch = 0;
> +
> +	return 4 * sizeof(uint32_t);
> +}
> +
> +static struct gem_engine_properties
> +configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctx_id)
> +{
> +	struct gem_engine_properties props;
> +
> +	/* Ensure fast hang detection */
> +	props.engine = e;
> +	props.preempt_timeout = 250;
> +	props.heartbeat_interval = 500;
> +	gem_engine_properties_configure(fd, &props);
> +
> +	/* Allow engine based resets and disable banning */
> +	igt_allow_hang(fd, ctx_id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
> +
> +	return props;
> +}
> +
> +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 void gem_reset(int fd, int dir, uint32_t ctx_id, uint32_t batch,
> +		      uint64_t batch_va, struct intel_execution_engine2 *e)
> +{
> +	struct drm_i915_gem_timeline_fence exec_fence = { };
> +	struct drm_i915_gem_execbuffer3 execbuf = { };
> +	uint64_t fence_value = 0;
> +	uint32_t exec_syncobj;
> +	uint32_t buf[20], len;
> +
> +	len = gem_recurse(buf, batch_va);
> +	gem_write(fd, batch, 0, buf, len);
> +
> +	execbuf.ctx_id = ctx_id;
> +	execbuf.batch_address = batch_va;
> +	execbuf.engine_idx = e->flags;
> +	execbuf.fence_count = 1;
> +	execbuf.timeline_fences = to_user_pointer(&exec_fence);
> +
> +	exec_syncobj = syncobj_create(fd, 0);
> +	exec_fence.handle = exec_syncobj;
> +	exec_fence.flags = I915_TIMELINE_FENCE_SIGNAL;
> +
> +	gem_execbuf3(fd, &execbuf);
> +
> +	igt_assert(syncobj_timeline_wait(fd, &exec_syncobj, &fence_value, 1,
> +					 gettime_ns() + (2 * NSEC_PER_SEC),
> +					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
> +	syncobj_destroy(fd, exec_syncobj);
> +}
> +
> +static void set_map(struct mappings *m, uint32_t idx, uint32_t obj, uint64_t va,
> +		    uint64_t offset, uint64_t length, uint32_t expect)
> +{
> +	m->idx = idx;
> +	m->obj = obj;
> +	m->va = va;
> +	m->offset = offset;
> +	m->length = length;
> +	m->expect = expect;
> +	igt_debug("Created mapping:0x%x - va 0x%lx handle %d offset 0x%lx length 0x%lx\n",
> +		  m->idx, m->va, m->obj, m->offset, m->length);
> +}
> +
> +static uint32_t create_obj(int fd, struct gem_memory_region *mr, uint32_t size, void **addr)
> +{
> +	uint32_t handle;
> +
> +	if (!mr) {
> +		igt_assert(posix_memalign(addr, PAGE_SIZE, size) == 0);
> +		gem_userptr(fd, *addr, size, 0, 0, &handle);
> +	} else {
> +		handle = gem_create_in_memory_region_list(fd, size, 0, &mr->ci, 1);
> +		*addr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
> +	}
> +
> +	return handle;
> +}
> +
> +static void destroy_obj(int fd, uint32_t handle, uint32_t size, void *addr, bool is_userptr)
> +{
> +	if (!is_userptr)
> +		igt_assert(gem_munmap(addr, size) == 0);
> +
> +	gem_close(fd, handle);
> +
> +	if (is_userptr)
> +		free(addr);
> +}
> +
> +static void run_vm_bind_capture(int fd, int dir, const intel_ctx_t *base_ctx,
> +				struct gem_memory_region *mr,
> +				struct intel_execution_engine2 *e)
> +{
> +	uint64_t obj_size = (mr ? mr->gtt_alignment : PAGE_SIZE) * 4;
> +	struct mappings *m, map[NUM_MAPS * NUM_OBJS + 1] = { };
> +	struct drm_i915_gem_context_param param = {
> +		.param = I915_CONTEXT_PARAM_RECOVERABLE,
> +		.value = 0,
> +	};
> +	struct gem_engine_properties saved_engine;
> +	uint32_t i, obj[NUM_OBJS];
> +	uint32_t *addr[NUM_OBJS];
> +	const intel_ctx_t *ctx;
> +	uint32_t vm_id, batch;
> +
> +	ctx = intel_ctx_create(fd, &base_ctx->cfg);
> +	param.ctx_id = ctx->id;
> +	gem_context_set_param(fd, &param);
> +	vm_id = gem_vm_create_in_vm_bind_mode(fd);
> +	gem_context_set_vm(fd, ctx->id, vm_id);
> +
> +	saved_engine = configure_hangs(fd, e, ctx->id);
> +
> +	/* Create objects and mappings */
> +	batch = gem_create(fd, PAGE_SIZE);
> +	for (i = 0, m = map; i < NUM_OBJS; i++) {
> +		obj[i] = create_obj(fd, mr, obj_size, (void **)&addr[i]);
> +
> +		for (unsigned int n = 0; n < obj_size / sizeof(*addr[0]); n++)
> +			addr[i][n] = (i << 24) + n;
> +
> +		/* Full bind */
> +		set_map(m++, 0 + (i * NUM_MAPS), obj[i], 0xa000000 << i, 0, obj_size, (i << 24));
> +		/* Full bind with alias VA */
> +		set_map(m++, 1 + (i * NUM_MAPS), obj[i], 0xb000000 << i, 0, obj_size, (i << 24));
> +		/* Partial bind */
> +		set_map(m++, 2 + (i * NUM_MAPS), obj[i], 0xc000000 << i, 0, obj_size / 2, (i << 24));
> +		/* Partial bind with offset */
> +		set_map(m++, 3 + (i * NUM_MAPS), obj[i], 0xd000000 << i, obj_size / 2, obj_size / 2,
> +			(i << 24) + (obj_size / 2) / sizeof(*addr[0]));
> +	}
> +	m->length = 0;
> +
> +	i915_vm_bind(fd, vm_id, BATCH_VA, batch, 0, PAGE_SIZE, 0, 0, 0);
> +	/* Bind mappings with capture request */
> +	for (m = map; m->length; m++)
> +		i915_vm_bind(fd, vm_id, m->va, m->obj, m->offset, m->length,
> +			     I915_GEM_VM_BIND_CAPTURE, 0, 0);
> +
> +	/* Cause reset and check the dump */
> +	gem_reset(fd, dir, ctx->id, batch, BATCH_VA, e);
> +	igt_assert_eq(check_error_state(dir, map, NUM_OBJS * NUM_MAPS), NUM_OBJS * NUM_MAPS);
> +
> +	for (m = map; m->length; m++)
> +		i915_vm_unbind(fd, vm_id, m->va, m->length);
> +	i915_vm_unbind(fd, vm_id, BATCH_VA, PAGE_SIZE);
> +
> +	gem_close(fd, batch);
> +	for (i = 0; i < NUM_OBJS; i++)
> +		destroy_obj(fd, obj[i], obj_size, (void *)addr[i], !mr);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
> +
> +	gem_vm_destroy(fd, vm_id);
> +	intel_ctx_destroy(fd, ctx);
> +}
> +
> +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 size_t safer_strlen(const char *s)
> +{
> +	return s ? strlen(s) : 0;
> +}
> +
> +igt_main
> +{
> +	struct intel_execution_engine2 *e;
> +	const intel_ctx_t *ctx = NULL;
> +	igt_fd_t(dir);
> +	igt_fd_t(fd);
> +
> +	igt_fixture {
> +		fd = drm_open_driver(DRIVER_INTEL);
> +		igt_require_gem(fd);
> +		igt_allow_hang(fd, 0, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
> +
> +		dir = igt_sysfs_open(fd);
> +		igt_require(igt_sysfs_set(dir, "error", "Begone!"));
> +		igt_require(safer_strlen(igt_sysfs_get(dir, "error")) > 0);
> +		ctx = intel_ctx_create_all_physical(fd);
> +	}
> +
> +	igt_describe("Basic vm_bind capture test");
> +	igt_subtest_with_dynamic("basic") {
> +		for_each_ctx_engine(fd, ctx, e) {
> +
> +			for_each_memory_region(r, fd) {
> +				if (r->ci.memory_instance)
> +					continue;
> +
> +				igt_dynamic_f("%s-%s", e->name, r->name)
> +					run_vm_bind_capture(fd, dir, ctx, r, e);
> +			}
> +
> +			if (has_userptr(fd)) {
> +				/* Use NULL memory region for userptr */
> +				igt_dynamic_f("%s-userptr", e->name)
> +					run_vm_bind_capture(fd, dir, ctx, NULL, e);
> +			}
> +		}
> +	}
> +
> +	igt_fixture {
> +		intel_ctx_destroy(fd, ctx);
> +	}
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index 395c88a7d..ea282654c 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -229,6 +229,7 @@ i915_progs = [
>   	'i915_suspend',
>   	'i915_vm_bind_basic',
>   	'i915_vm_bind_sanity',
> +        'i915_vm_bind_capture',

Keep sorted. Also whitespapce formatting looks funny here?

Anyway,
Reviewed-by: Matthew Auld <matthew.auld@intel.com>

>   	'kms_big_fb',
>   	'kms_big_joiner' ,
>   	'kms_busy',

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

* Re: [igt-dev] [PATCH i-g-t v8 14/14] tests/i915/vm_bind: Test capture of persistent mappings
  2022-12-06 17:34   ` Matthew Auld
@ 2022-12-08 13:56     ` Niranjana Vishwanathapura
  0 siblings, 0 replies; 19+ messages in thread
From: Niranjana Vishwanathapura @ 2022-12-08 13:56 UTC (permalink / raw)
  To: Matthew Auld
  Cc: tvrtko.ursulin, igt-dev, thomas.hellstrom, daniel.vetter, petri.latvala

On Tue, Dec 06, 2022 at 05:34:59PM +0000, Matthew Auld wrote:
>On 29/11/2022 07:23, Niranjana Vishwanathapura wrote:
>>Add i915_vm_bind_capture to validate dump capture of persistent
>>mappings including partial binding.
>>
>>Signed-off-by: Brian Welty <brian.welty@intel.com>
>>Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
>>---
>>  tests/i915/i915_vm_bind_capture.c | 445 ++++++++++++++++++++++++++++++
>>  tests/meson.build                 |   1 +
>>  2 files changed, 446 insertions(+)
>>  create mode 100644 tests/i915/i915_vm_bind_capture.c
>>
>>diff --git a/tests/i915/i915_vm_bind_capture.c b/tests/i915/i915_vm_bind_capture.c
>>new file mode 100644
>>index 000000000..f82f53b96
>>--- /dev/null
>>+++ b/tests/i915/i915_vm_bind_capture.c
>>@@ -0,0 +1,445 @@
>>+// SPDX-License-Identifier: MIT
>>+/*
>>+ * Copyright(c) 2022 Intel Corporation. All rights reserved.
>>+ */
>>+
>>+/** @file gem_vm_bind_capture.c
>>+ *
>>+ * This is the test for dump capture of VM_BIND mappings.
>>+ *
>>+ * The goal is to simply ensure that capture of persistent mappings
>>+ * works. This test in part is derived from gem_exec_capture.c
>>+ */
>>+
>>+#include <sys/poll.h>
>>+#include <zlib.h>
>>+#include <sched.h>
>>+
>>+#include "i915/gem.h"
>>+#include "i915/gem_create.h"
>>+#include "i915/gem_vm.h"
>>+#include "i915/i915_vm_bind.h"
>>+#include "igt.h"
>>+#include "igt_device.h"
>>+#include "igt_syncobj.h"
>>+#include "igt_sysfs.h"
>>+#include "igt_types.h"
>>+#include "intel_ctx.h"
>>+
>>+
>>+#define PAGE_SIZE   4096
>>+
>>+#define NUM_OBJS  3
>>+#define NUM_MAPS  4
>>+#define BATCH_VA  0x8000000
>>+
>>+IGT_TEST_DESCRIPTION("Check that we capture the user specified persistent mappings on a hang");
>>+
>>+struct mappings {
>>+	uint32_t  obj;
>>+	uint64_t  va;
>>+	uint64_t  offset;
>>+	uint64_t  length;
>>+
>>+	uint32_t  idx;
>>+	uint32_t  expect;
>>+	bool      found;
>>+};
>>+
>>+static unsigned long zlib_inflate(uint32_t **ptr, unsigned long len)
>>+{
>>+	struct z_stream_s zstream;
>>+	void *out;
>>+
>>+	memset(&zstream, 0, sizeof(zstream));
>>+
>>+	zstream.next_in = (unsigned char *)*ptr;
>>+	zstream.avail_in = 4*len;
>>+
>>+	if (inflateInit(&zstream) != Z_OK)
>>+		return 0;
>>+
>>+	out = malloc(128*4096); /* approximate obj size */
>>+	zstream.next_out = out;
>>+	zstream.avail_out = 128*4096;
>>+
>>+	do {
>>+		switch (inflate(&zstream, Z_SYNC_FLUSH)) {
>>+		case Z_STREAM_END:
>>+			goto end;
>>+		case Z_OK:
>>+			break;
>>+		default:
>>+			inflateEnd(&zstream);
>>+			return 0;
>>+		}
>>+
>>+		if (zstream.avail_out)
>>+			break;
>>+
>>+		out = realloc(out, 2*zstream.total_out);
>>+		if (out == NULL) {
>>+			inflateEnd(&zstream);
>>+			return 0;
>>+		}
>>+
>>+		zstream.next_out = (unsigned char *)out + zstream.total_out;
>>+		zstream.avail_out = zstream.total_out;
>>+	} while (1);
>>+end:
>>+	inflateEnd(&zstream);
>>+	free(*ptr);
>>+	*ptr = out;
>>+	return zstream.total_out / 4;
>>+}
>>+
>>+static unsigned long
>>+ascii85_decode(char *in, uint32_t **out, bool inflate, char **end)
>>+{
>>+	unsigned long len = 0, size = 1024;
>>+
>>+	*out = realloc(*out, sizeof(uint32_t)*size);
>>+	if (*out == NULL)
>>+		return 0;
>>+
>>+	while (*in >= '!' && *in <= 'z') {
>>+		uint32_t v = 0;
>>+
>>+		if (len == size) {
>>+			size *= 2;
>>+			*out = realloc(*out, sizeof(uint32_t)*size);
>>+			if (*out == NULL)
>>+				return 0;
>>+		}
>>+
>>+		if (*in == 'z') {
>>+			in++;
>>+		} else {
>>+			v += in[0] - 33; v *= 85;
>>+			v += in[1] - 33; v *= 85;
>>+			v += in[2] - 33; v *= 85;
>>+			v += in[3] - 33; v *= 85;
>>+			v += in[4] - 33;
>>+			in += 5;
>>+		}
>>+		(*out)[len++] = v;
>>+	}
>>+	*end = in;
>>+
>>+	if (!inflate)
>>+		return len;
>>+
>>+	return zlib_inflate(out, len);
>>+}
>>+
>>+static int check_error_state(int dir, struct mappings *map, uint32_t num_maps)
>>+{
>>+	char *error, *str;
>>+	int blobs = 0;
>>+
>>+	errno = 0;
>>+	error = igt_sysfs_get(dir, "error");
>>+	igt_sysfs_set(dir, "error", "Begone!");
>>+	igt_assert(error);
>>+	igt_assert(errno != ENOMEM);
>>+	igt_debug("%s\n", error);
>>+
>>+	/* render ring --- user = 0x00000000 ffffd000 */
>>+	for (str = error; (str = strstr(str, "--- user = ")); ) {
>>+		uint32_t *data = NULL;
>>+		uint64_t addr;
>>+		unsigned long i, j, sz;
>>+		unsigned long start;
>>+		unsigned long end;
>>+
>>+		if (strncmp(str, "--- user = 0x", 13))
>>+			break;
>>+		str += 13;
>>+		addr = strtoul(str, &str, 16);
>>+		addr <<= 32;
>>+		addr |= strtoul(str + 1, &str, 16);
>>+		igt_assert(*str++ == '\n');
>>+
>>+		start = 0;
>>+		end = num_maps;
>>+		while (end > start) {
>>+			i = (end - start) / 2 + start;
>>+			if (map[i].va < addr)
>>+				start = i + 1;
>>+			else if (map[i].va > addr)
>>+				end = i;
>>+			else
>>+				break;
>>+		}
>>+
>>+		igt_assert(map[i].va == addr);
>>+		igt_assert(!map[i].found);
>>+		map[i].found = true;
>>+		igt_debug("offset:%"PRIx64", index:%d\n",
>>+			  addr, map[i].idx);
>>+
>>+		/* gtt_page_sizes = 0x00010000 */
>>+		if (strncmp(str, "gtt_page_sizes = 0x", 19) == 0) {
>>+			str += 19 + 8;
>>+			igt_assert(*str++ == '\n');
>>+		}
>>+
>>+		if (!(*str == ':' || *str == '~'))
>>+			continue;
>>+
>>+		igt_debug("blob:%.64s\n", str);
>>+		sz = ascii85_decode(str + 1, &data, *str == ':', &str);
>>+		igt_debug("Found addr 0x%lx sz 0x%lx\n", addr, sz);
>>+		igt_assert_eq(4 * sz, map[i].length);
>>+		igt_assert(*str++ == '\n');
>>+		str = strchr(str, '-');
>>+
>>+		for (j = 0; j < sz; j++)
>>+			igt_assert_eq(data[j], map[i].expect + j);
>>+
>>+		blobs++;
>>+		free(data);
>>+	}
>>+
>>+	free(error);
>>+	return blobs;
>>+}
>
>Is all of this copy-paste from another test? I didn't check, but if 
>possible maybe consider moving into lib and re-use instead.
>

Most of the above functions are copied from gem_exec_capture.
Sure, will try moving them into a lib.

>>+
>>+static int gem_recurse(uint32_t *batch, uint64_t batch_va)
>>+{
>>+	*batch++ = MI_BATCH_BUFFER_START | 1 << 8 | 1;
>>+	*batch++ = lower_32_bits(batch_va);
>>+	*batch++ = upper_32_bits(batch_va);
>>+	*batch = 0;
>>+
>>+	return 4 * sizeof(uint32_t);
>>+}
>>+
>>+static struct gem_engine_properties
>>+configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctx_id)
>>+{
>>+	struct gem_engine_properties props;
>>+
>>+	/* Ensure fast hang detection */
>>+	props.engine = e;
>>+	props.preempt_timeout = 250;
>>+	props.heartbeat_interval = 500;
>>+	gem_engine_properties_configure(fd, &props);
>>+
>>+	/* Allow engine based resets and disable banning */
>>+	igt_allow_hang(fd, ctx_id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
>>+
>>+	return props;
>>+}
>>+
>>+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 void gem_reset(int fd, int dir, uint32_t ctx_id, uint32_t batch,
>>+		      uint64_t batch_va, struct intel_execution_engine2 *e)
>>+{
>>+	struct drm_i915_gem_timeline_fence exec_fence = { };
>>+	struct drm_i915_gem_execbuffer3 execbuf = { };
>>+	uint64_t fence_value = 0;
>>+	uint32_t exec_syncobj;
>>+	uint32_t buf[20], len;
>>+
>>+	len = gem_recurse(buf, batch_va);
>>+	gem_write(fd, batch, 0, buf, len);
>>+
>>+	execbuf.ctx_id = ctx_id;
>>+	execbuf.batch_address = batch_va;
>>+	execbuf.engine_idx = e->flags;
>>+	execbuf.fence_count = 1;
>>+	execbuf.timeline_fences = to_user_pointer(&exec_fence);
>>+
>>+	exec_syncobj = syncobj_create(fd, 0);
>>+	exec_fence.handle = exec_syncobj;
>>+	exec_fence.flags = I915_TIMELINE_FENCE_SIGNAL;
>>+
>>+	gem_execbuf3(fd, &execbuf);
>>+
>>+	igt_assert(syncobj_timeline_wait(fd, &exec_syncobj, &fence_value, 1,
>>+					 gettime_ns() + (2 * NSEC_PER_SEC),
>>+					 DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
>>+	syncobj_destroy(fd, exec_syncobj);
>>+}
>>+
>>+static void set_map(struct mappings *m, uint32_t idx, uint32_t obj, uint64_t va,
>>+		    uint64_t offset, uint64_t length, uint32_t expect)
>>+{
>>+	m->idx = idx;
>>+	m->obj = obj;
>>+	m->va = va;
>>+	m->offset = offset;
>>+	m->length = length;
>>+	m->expect = expect;
>>+	igt_debug("Created mapping:0x%x - va 0x%lx handle %d offset 0x%lx length 0x%lx\n",
>>+		  m->idx, m->va, m->obj, m->offset, m->length);
>>+}
>>+
>>+static uint32_t create_obj(int fd, struct gem_memory_region *mr, uint32_t size, void **addr)
>>+{
>>+	uint32_t handle;
>>+
>>+	if (!mr) {
>>+		igt_assert(posix_memalign(addr, PAGE_SIZE, size) == 0);
>>+		gem_userptr(fd, *addr, size, 0, 0, &handle);
>>+	} else {
>>+		handle = gem_create_in_memory_region_list(fd, size, 0, &mr->ci, 1);
>>+		*addr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
>>+	}
>>+
>>+	return handle;
>>+}
>>+
>>+static void destroy_obj(int fd, uint32_t handle, uint32_t size, void *addr, bool is_userptr)
>>+{
>>+	if (!is_userptr)
>>+		igt_assert(gem_munmap(addr, size) == 0);
>>+
>>+	gem_close(fd, handle);
>>+
>>+	if (is_userptr)
>>+		free(addr);
>>+}
>>+
>>+static void run_vm_bind_capture(int fd, int dir, const intel_ctx_t *base_ctx,
>>+				struct gem_memory_region *mr,
>>+				struct intel_execution_engine2 *e)
>>+{
>>+	uint64_t obj_size = (mr ? mr->gtt_alignment : PAGE_SIZE) * 4;
>>+	struct mappings *m, map[NUM_MAPS * NUM_OBJS + 1] = { };
>>+	struct drm_i915_gem_context_param param = {
>>+		.param = I915_CONTEXT_PARAM_RECOVERABLE,
>>+		.value = 0,
>>+	};
>>+	struct gem_engine_properties saved_engine;
>>+	uint32_t i, obj[NUM_OBJS];
>>+	uint32_t *addr[NUM_OBJS];
>>+	const intel_ctx_t *ctx;
>>+	uint32_t vm_id, batch;
>>+
>>+	ctx = intel_ctx_create(fd, &base_ctx->cfg);
>>+	param.ctx_id = ctx->id;
>>+	gem_context_set_param(fd, &param);
>>+	vm_id = gem_vm_create_in_vm_bind_mode(fd);
>>+	gem_context_set_vm(fd, ctx->id, vm_id);
>>+
>>+	saved_engine = configure_hangs(fd, e, ctx->id);
>>+
>>+	/* Create objects and mappings */
>>+	batch = gem_create(fd, PAGE_SIZE);
>>+	for (i = 0, m = map; i < NUM_OBJS; i++) {
>>+		obj[i] = create_obj(fd, mr, obj_size, (void **)&addr[i]);
>>+
>>+		for (unsigned int n = 0; n < obj_size / sizeof(*addr[0]); n++)
>>+			addr[i][n] = (i << 24) + n;
>>+
>>+		/* Full bind */
>>+		set_map(m++, 0 + (i * NUM_MAPS), obj[i], 0xa000000 << i, 0, obj_size, (i << 24));
>>+		/* Full bind with alias VA */
>>+		set_map(m++, 1 + (i * NUM_MAPS), obj[i], 0xb000000 << i, 0, obj_size, (i << 24));
>>+		/* Partial bind */
>>+		set_map(m++, 2 + (i * NUM_MAPS), obj[i], 0xc000000 << i, 0, obj_size / 2, (i << 24));
>>+		/* Partial bind with offset */
>>+		set_map(m++, 3 + (i * NUM_MAPS), obj[i], 0xd000000 << i, obj_size / 2, obj_size / 2,
>>+			(i << 24) + (obj_size / 2) / sizeof(*addr[0]));
>>+	}
>>+	m->length = 0;
>>+
>>+	i915_vm_bind(fd, vm_id, BATCH_VA, batch, 0, PAGE_SIZE, 0, 0, 0);
>>+	/* Bind mappings with capture request */
>>+	for (m = map; m->length; m++)
>>+		i915_vm_bind(fd, vm_id, m->va, m->obj, m->offset, m->length,
>>+			     I915_GEM_VM_BIND_CAPTURE, 0, 0);
>>+
>>+	/* Cause reset and check the dump */
>>+	gem_reset(fd, dir, ctx->id, batch, BATCH_VA, e);
>>+	igt_assert_eq(check_error_state(dir, map, NUM_OBJS * NUM_MAPS), NUM_OBJS * NUM_MAPS);
>>+
>>+	for (m = map; m->length; m++)
>>+		i915_vm_unbind(fd, vm_id, m->va, m->length);
>>+	i915_vm_unbind(fd, vm_id, BATCH_VA, PAGE_SIZE);
>>+
>>+	gem_close(fd, batch);
>>+	for (i = 0; i < NUM_OBJS; i++)
>>+		destroy_obj(fd, obj[i], obj_size, (void *)addr[i], !mr);
>>+
>>+	gem_engine_properties_restore(fd, &saved_engine);
>>+
>>+	gem_vm_destroy(fd, vm_id);
>>+	intel_ctx_destroy(fd, ctx);
>>+}
>>+
>>+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 size_t safer_strlen(const char *s)
>>+{
>>+	return s ? strlen(s) : 0;
>>+}
>>+
>>+igt_main
>>+{
>>+	struct intel_execution_engine2 *e;
>>+	const intel_ctx_t *ctx = NULL;
>>+	igt_fd_t(dir);
>>+	igt_fd_t(fd);
>>+
>>+	igt_fixture {
>>+		fd = drm_open_driver(DRIVER_INTEL);
>>+		igt_require_gem(fd);
>>+		igt_allow_hang(fd, 0, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
>>+
>>+		dir = igt_sysfs_open(fd);
>>+		igt_require(igt_sysfs_set(dir, "error", "Begone!"));
>>+		igt_require(safer_strlen(igt_sysfs_get(dir, "error")) > 0);
>>+		ctx = intel_ctx_create_all_physical(fd);
>>+	}
>>+
>>+	igt_describe("Basic vm_bind capture test");
>>+	igt_subtest_with_dynamic("basic") {
>>+		for_each_ctx_engine(fd, ctx, e) {
>>+
>>+			for_each_memory_region(r, fd) {
>>+				if (r->ci.memory_instance)
>>+					continue;
>>+
>>+				igt_dynamic_f("%s-%s", e->name, r->name)
>>+					run_vm_bind_capture(fd, dir, ctx, r, e);
>>+			}
>>+
>>+			if (has_userptr(fd)) {
>>+				/* Use NULL memory region for userptr */
>>+				igt_dynamic_f("%s-userptr", e->name)
>>+					run_vm_bind_capture(fd, dir, ctx, NULL, e);
>>+			}
>>+		}
>>+	}
>>+
>>+	igt_fixture {
>>+		intel_ctx_destroy(fd, ctx);
>>+	}
>>+}
>>diff --git a/tests/meson.build b/tests/meson.build
>>index 395c88a7d..ea282654c 100644
>>--- a/tests/meson.build
>>+++ b/tests/meson.build
>>@@ -229,6 +229,7 @@ i915_progs = [
>>  	'i915_suspend',
>>  	'i915_vm_bind_basic',
>>  	'i915_vm_bind_sanity',
>>+        'i915_vm_bind_capture',
>
>Keep sorted. Also whitespapce formatting looks funny here?
>

Ok

>Anyway,
>Reviewed-by: Matthew Auld <matthew.auld@intel.com>

Thanks,
Niranjana

>
>>  	'kms_big_fb',
>>  	'kms_big_joiner' ,
>>  	'kms_busy',

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

end of thread, other threads:[~2022-12-08 13:57 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-29  7:23 [igt-dev] [PATCH i-g-t v8 00/14] vm_bind: Add VM_BIND validation support Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 01/14] lib/i915: memory region gtt_alignment support Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 02/14] lib/vm_bind: import uapi definitions Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 03/14] lib/vm_bind: Add vm_bind/unbind and execbuf3 ioctls Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 04/14] lib/vm_bind: Add vm_bind mode support for VM Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 05/14] lib/vm_bind: Add vm_bind specific library functions Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 06/14] lib/vm_bind: Add __prime_handle_to_fd() Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 07/14] tests/i915/vm_bind: Add vm_bind sanity test Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 08/14] tests/i915/vm_bind: Add basic VM_BIND test support Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 09/14] tests/i915/vm_bind: Add userptr subtest Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 10/14] tests/i915/vm_bind: Add gem_exec3_basic test Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 11/14] tests/i915/vm_bind: Add gem_exec3_balancer test Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 12/14] tests/i915/vm_bind: Add gem_lmem_swapping@vm_bind sub test Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 13/14] tests/i915/vm_bind: Add gem_shrink@vm_bind* subtests Niranjana Vishwanathapura
2022-11-29  7:23 ` [igt-dev] [PATCH i-g-t v8 14/14] tests/i915/vm_bind: Test capture of persistent mappings Niranjana Vishwanathapura
2022-12-06 17:34   ` Matthew Auld
2022-12-08 13:56     ` Niranjana Vishwanathapura
2022-11-29  8:14 ` [igt-dev] ✓ Fi.CI.BAT: success for vm_bind: Add VM_BIND validation support (rev12) Patchwork
2022-11-29 10:26 ` [igt-dev] ✓ Fi.CI.IGT: " 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.