]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/xe: Convert xe_bo_create_user() for exhaustive eviction
authorThomas Hellström <thomas.hellstrom@linux.intel.com>
Mon, 8 Sep 2025 10:12:36 +0000 (12:12 +0200)
committerThomas Hellström <thomas.hellstrom@linux.intel.com>
Wed, 10 Sep 2025 07:15:57 +0000 (09:15 +0200)
Use the xe_validation_guard() to convert xe_bo_create_user()
for exhaustive eviction.

v2:
- Adapt to argument changes of xe_validation_guard()

Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com> #v1
Link: https://lore.kernel.org/r/20250908101246.65025-4-thomas.hellstrom@linux.intel.com
drivers/gpu/drm/xe/tests/xe_bo.c
drivers/gpu/drm/xe/tests/xe_dma_buf.c
drivers/gpu/drm/xe/tests/xe_migrate.c
drivers/gpu/drm/xe/xe_bo.c
drivers/gpu/drm/xe/xe_bo.h
drivers/gpu/drm/xe/xe_device.c
drivers/gpu/drm/xe/xe_device_types.h
drivers/gpu/drm/xe/xe_vm.c
drivers/gpu/drm/xe/xe_vm.h

index 17366b60ee3195d48c60bdcd632a9334679cad08..2294cf89f3e119e6e0e40be0bfd0ee05aca55362 100644 (file)
@@ -139,8 +139,8 @@ static void ccs_test_run_tile(struct xe_device *xe, struct xe_tile *tile,
        else
                kunit_info(test, "Testing system memory\n");
 
-       bo = xe_bo_create_user(xe, NULL, NULL, SZ_1M, DRM_XE_GEM_CPU_CACHING_WC,
-                              bo_flags);
+       bo = xe_bo_create_user(xe, NULL, SZ_1M, DRM_XE_GEM_CPU_CACHING_WC,
+                              bo_flags, exec);
        if (IS_ERR(bo)) {
                KUNIT_FAIL(test, "Failed to create bo.\n");
                return;
@@ -220,18 +220,18 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
 
        for (i = 0; i < 2; ++i) {
                xe_vm_lock(vm, false);
-               bo = xe_bo_create_user(xe, NULL, vm, 0x10000,
+               bo = xe_bo_create_user(xe, vm, 0x10000,
                                       DRM_XE_GEM_CPU_CACHING_WC,
-                                      bo_flags);
+                                      bo_flags, exec);
                xe_vm_unlock(vm);
                if (IS_ERR(bo)) {
                        KUNIT_FAIL(test, "bo create err=%pe\n", bo);
                        break;
                }
 
-               external = xe_bo_create_user(xe, NULL, NULL, 0x10000,
+               external = xe_bo_create_user(xe, NULL, 0x10000,
                                             DRM_XE_GEM_CPU_CACHING_WC,
-                                            bo_flags);
+                                            bo_flags, NULL);
                if (IS_ERR(external)) {
                        KUNIT_FAIL(test, "external bo create err=%pe\n", external);
                        goto cleanup_bo;
@@ -497,9 +497,9 @@ static int shrink_test_run_device(struct xe_device *xe)
                INIT_LIST_HEAD(&link->link);
 
                /* We can create bos using WC caching here. But it is slower. */
-               bo = xe_bo_create_user(xe, NULL, NULL, XE_BO_SHRINK_SIZE,
+               bo = xe_bo_create_user(xe, NULL, XE_BO_SHRINK_SIZE,
                                       DRM_XE_GEM_CPU_CACHING_WB,
-                                      XE_BO_FLAG_SYSTEM);
+                                      XE_BO_FLAG_SYSTEM, NULL);
                if (IS_ERR(bo)) {
                        if (bo != ERR_PTR(-ENOMEM) && bo != ERR_PTR(-ENOSPC) &&
                            bo != ERR_PTR(-EINTR) && bo != ERR_PTR(-ERESTARTSYS))
index 7117486f04327a44b586726d698e66a473a4eede..a7e548a2bdfb9c91830e4d1121aa8d3be27c9ba5 100644 (file)
@@ -114,8 +114,8 @@ static void xe_test_dmabuf_import_same_driver(struct xe_device *xe)
                size = SZ_64K;
 
        kunit_info(test, "running %s\n", __func__);
-       bo = xe_bo_create_user(xe, NULL, NULL, size, DRM_XE_GEM_CPU_CACHING_WC,
-                              params->mem_mask);
+       bo = xe_bo_create_user(xe, NULL, size, DRM_XE_GEM_CPU_CACHING_WC,
+                              params->mem_mask, NULL);
        if (IS_ERR(bo)) {
                KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
                           PTR_ERR(bo));
index dfb445d097590f3981f30b697d41df5e9a26254d..afa794e5606522be94169374069ee801d7cf5826 100644 (file)
@@ -642,11 +642,11 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
        struct drm_exec *exec;
        long ret;
 
-       sys_bo = xe_bo_create_user(xe, NULL, NULL, SZ_4M,
+       sys_bo = xe_bo_create_user(xe, NULL, SZ_4M,
                                   DRM_XE_GEM_CPU_CACHING_WC,
                                   XE_BO_FLAG_SYSTEM |
                                   XE_BO_FLAG_NEEDS_CPU_ACCESS |
-                                  XE_BO_FLAG_PINNED);
+                                  XE_BO_FLAG_PINNED, NULL);
 
        if (IS_ERR(sys_bo)) {
                KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
@@ -669,10 +669,10 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
        }
        xe_bo_unlock(sys_bo);
 
-       ccs_bo = xe_bo_create_user(xe, NULL, NULL, SZ_4M,
+       ccs_bo = xe_bo_create_user(xe, NULL, SZ_4M,
                                   DRM_XE_GEM_CPU_CACHING_WC,
                                   bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
-                                  XE_BO_FLAG_PINNED);
+                                  XE_BO_FLAG_PINNED, NULL);
 
        if (IS_ERR(ccs_bo)) {
                KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
@@ -694,10 +694,10 @@ static void validate_ccs_test_run_tile(struct xe_device *xe, struct xe_tile *til
        }
        xe_bo_unlock(ccs_bo);
 
-       vram_bo = xe_bo_create_user(xe, NULL, NULL, SZ_4M,
+       vram_bo = xe_bo_create_user(xe, NULL, SZ_4M,
                                    DRM_XE_GEM_CPU_CACHING_WC,
                                    bo_flags | XE_BO_FLAG_NEEDS_CPU_ACCESS |
-                                   XE_BO_FLAG_PINNED);
+                                   XE_BO_FLAG_PINNED, NULL);
        if (IS_ERR(vram_bo)) {
                KUNIT_FAIL(test, "xe_bo_create() failed with err=%ld\n",
                           PTR_ERR(vram_bo));
index 36e804dcc38ffc20ad4591bbe91114075f5c8f52..ac330159e3399ec60ab36c764895d5b740075995 100644 (file)
@@ -2199,30 +2199,66 @@ struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
                                     flags, 0, exec);
 }
 
-struct xe_bo *xe_bo_create_user(struct xe_device *xe, struct xe_tile *tile,
-                               struct xe_vm *vm, size_t size,
-                               u16 cpu_caching,
-                               u32 flags)
+static struct xe_bo *xe_bo_create_novm(struct xe_device *xe, struct xe_tile *tile,
+                                      size_t size, u16 cpu_caching,
+                                      enum ttm_bo_type type, u32 flags,
+                                      u64 alignment, bool intr)
 {
-       struct drm_exec *exec = vm ? xe_vm_validation_exec(vm) : XE_VALIDATION_UNIMPLEMENTED;
-       struct xe_bo *bo = __xe_bo_create_locked(xe, tile, vm, size, 0, ~0ULL,
-                                                cpu_caching, ttm_bo_type_device,
-                                                flags | XE_BO_FLAG_USER, 0, exec);
-       if (!IS_ERR(bo))
-               xe_bo_unlock_vm_held(bo);
+       struct xe_validation_ctx ctx;
+       struct drm_exec exec;
+       struct xe_bo *bo;
+       int ret = 0;
 
-       return bo;
+       xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {.interruptible = intr},
+                           ret) {
+               bo = __xe_bo_create_locked(xe, tile, NULL, size, 0, ~0ULL,
+                                          cpu_caching, type, flags, alignment, &exec);
+               drm_exec_retry_on_contention(&exec);
+               if (IS_ERR(bo)) {
+                       ret = PTR_ERR(bo);
+                       xe_validation_retry_on_oom(&ctx, &ret);
+               } else {
+                       xe_bo_unlock(bo);
+               }
+       }
+
+       return ret ? ERR_PTR(ret) : bo;
 }
 
-struct xe_bo *xe_bo_create(struct xe_device *xe, struct xe_tile *tile,
-                          struct xe_vm *vm, size_t size,
-                          enum ttm_bo_type type, u32 flags)
+/**
+ * xe_bo_create_user() - Create a user BO
+ * @xe: The xe device.
+ * @vm: The local vm or NULL for external objects.
+ * @size: The storage size to use for the bo.
+ * @cpu_caching: The caching mode to be used for system backing store.
+ * @flags: XE_BO_FLAG_ flags.
+ * @exec: The drm_exec transaction to use for exhaustive eviction, or NULL
+ * if such a transaction should be initiated by the call.
+ *
+ * Create a bo on behalf of user-space.
+ *
+ * Return: The buffer object on success. Negative error pointer on failure.
+ */
+struct xe_bo *xe_bo_create_user(struct xe_device *xe,
+                               struct xe_vm *vm, size_t size,
+                               u16 cpu_caching,
+                               u32 flags, struct drm_exec *exec)
 {
-       struct drm_exec *exec = vm ? xe_vm_validation_exec(vm) : XE_VALIDATION_UNIMPLEMENTED;
-       struct xe_bo *bo = xe_bo_create_locked(xe, tile, vm, size, type, flags, exec);
+       struct xe_bo *bo;
 
-       if (!IS_ERR(bo))
-               xe_bo_unlock_vm_held(bo);
+       flags |= XE_BO_FLAG_USER;
+
+       if (vm || exec) {
+               xe_assert(xe, exec);
+               bo = __xe_bo_create_locked(xe, NULL, vm, size, 0, ~0ULL,
+                                          cpu_caching, ttm_bo_type_device,
+                                          flags, 0, exec);
+               if (!IS_ERR(bo))
+                       xe_bo_unlock_vm_held(bo);
+       } else {
+               bo = xe_bo_create_novm(xe, NULL, size, cpu_caching,
+                                      ttm_bo_type_device, flags, 0, true);
+       }
 
        return bo;
 }
@@ -2777,8 +2813,9 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
        struct xe_device *xe = to_xe_device(dev);
        struct xe_file *xef = to_xe_file(file);
        struct drm_xe_gem_create *args = data;
+       struct xe_validation_ctx ctx;
+       struct drm_exec exec;
        struct xe_vm *vm = NULL;
-       ktime_t end = 0;
        struct xe_bo *bo;
        unsigned int bo_flags;
        u32 handle;
@@ -2852,25 +2889,26 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
                        return -ENOENT;
        }
 
-retry:
-       if (vm) {
-               err = xe_vm_lock(vm, true);
-               if (err)
-                       goto out_vm;
+       err = 0;
+       xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {.interruptible = true},
+                           err) {
+               if (vm) {
+                       err = xe_vm_drm_exec_lock(vm, &exec);
+                       drm_exec_retry_on_contention(&exec);
+                       if (err)
+                               break;
+               }
+               bo = xe_bo_create_user(xe, vm, args->size, args->cpu_caching,
+                                      bo_flags, &exec);
+               drm_exec_retry_on_contention(&exec);
+               if (IS_ERR(bo)) {
+                       err = PTR_ERR(bo);
+                       xe_validation_retry_on_oom(&ctx, &err);
+                       break;
+               }
        }
-
-       bo = xe_bo_create_user(xe, NULL, vm, args->size, args->cpu_caching,
-                              bo_flags);
-
-       if (vm)
-               xe_vm_unlock(vm);
-
-       if (IS_ERR(bo)) {
-               err = PTR_ERR(bo);
-               if (xe_vm_validate_should_retry(NULL, err, &end))
-                       goto retry;
+       if (err)
                goto out_vm;
-       }
 
        if (args->extensions) {
                err = gem_create_user_extensions(xe, bo, args->extensions, 0);
@@ -3243,11 +3281,11 @@ int xe_bo_dumb_create(struct drm_file *file_priv,
        args->size = ALIGN(mul_u32_u32(args->pitch, args->height),
                           page_size);
 
-       bo = xe_bo_create_user(xe, NULL, NULL, args->size,
+       bo = xe_bo_create_user(xe, NULL, args->size,
                               DRM_XE_GEM_CPU_CACHING_WC,
                               XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
                               XE_BO_FLAG_SCANOUT |
-                              XE_BO_FLAG_NEEDS_CPU_ACCESS);
+                              XE_BO_FLAG_NEEDS_CPU_ACCESS, NULL);
        if (IS_ERR(bo))
                return PTR_ERR(bo);
 
index fa6813a7b4bcc3d1cd4e2ad9a027971ca4baaaf1..3878df635b038361e7359455ee60e3bdbfb5a247 100644 (file)
@@ -104,13 +104,8 @@ struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
                                  struct xe_vm *vm, size_t size,
                                  enum ttm_bo_type type, u32 flags,
                                  struct drm_exec *exec);
-struct xe_bo *xe_bo_create(struct xe_device *xe, struct xe_tile *tile,
-                          struct xe_vm *vm, size_t size,
-                          enum ttm_bo_type type, u32 flags);
-struct xe_bo *xe_bo_create_user(struct xe_device *xe, struct xe_tile *tile,
-                               struct xe_vm *vm, size_t size,
-                               u16 cpu_caching,
-                               u32 flags);
+struct xe_bo *xe_bo_create_user(struct xe_device *xe, struct xe_vm *vm, size_t size,
+                               u16 cpu_caching, u32 flags, struct drm_exec *exec);
 struct xe_bo *xe_bo_create_pin_map(struct xe_device *xe, struct xe_tile *tile,
                                   struct xe_vm *vm, size_t size,
                                   enum ttm_bo_type type, u32 flags);
index 9e2952c9c06a8bb3b8914e96c3bbbadc7e6618d3..c7bba535b1456fe794a69ec8c11e1baa563aeaac 100644 (file)
@@ -457,6 +457,8 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
        if (err)
                goto err;
 
+       xe_validation_device_init(&xe->val);
+
        init_waitqueue_head(&xe->ufence_wq);
 
        init_rwsem(&xe->usm.lock);
index a6ba880e41814597ef04a087f5e4359151d516ef..8233002e1c5b9eff9edd2d40e9901e8abdf5463b 100644 (file)
@@ -26,6 +26,7 @@
 #include "xe_sriov_vf_ccs_types.h"
 #include "xe_step_types.h"
 #include "xe_survivability_mode_types.h"
+#include "xe_validation.h"
 
 #if IS_ENABLED(CONFIG_DRM_XE_DEBUG)
 #define TEST_VM_OPS_ERROR
@@ -583,6 +584,8 @@ struct xe_device {
         */
        atomic64_t global_total_pages;
 #endif
+       /** @val: The domain for exhaustive eviction, which is currently per device. */
+       struct xe_validation_device val;
 
        /** @psmi: GPU debugging via additional validation HW */
        struct {
index 8a6cb92e6a5b485151d4a15d8593fcf530e3fea2..5656da870d6d47d2e44d2bd19ec9b4f8342fb617 100644 (file)
@@ -47,6 +47,20 @@ static struct drm_gem_object *xe_vm_obj(struct xe_vm *vm)
        return vm->gpuvm.r_obj;
 }
 
+/**
+ * xe_vm_drm_exec_lock() - Lock the vm's resv with a drm_exec transaction
+ * @vm: The vm whose resv is to be locked.
+ * @exec: The drm_exec transaction.
+ *
+ * Helper to lock the vm's resv as part of a drm_exec transaction.
+ *
+ * Return: %0 on success. See drm_exec_lock_obj() for error codes.
+ */
+int xe_vm_drm_exec_lock(struct xe_vm *vm, struct drm_exec *exec)
+{
+       return drm_exec_lock_obj(exec, xe_vm_obj(vm));
+}
+
 static bool preempt_fences_waiting(struct xe_vm *vm)
 {
        struct xe_exec_queue *q;
index 2c241f76d5fbc5ab593068390f44020380552626..ba6636c1bd58d78d00e07b1e1ba2373635664b2a 100644 (file)
@@ -292,6 +292,8 @@ void xe_vm_kill(struct xe_vm *vm, bool unlocked);
  */
 #define xe_vm_assert_held(vm) dma_resv_assert_held(xe_vm_resv(vm))
 
+int xe_vm_drm_exec_lock(struct xe_vm *vm, struct drm_exec *exec);
+
 #if IS_ENABLED(CONFIG_DRM_XE_DEBUG_VM)
 #define vm_dbg drm_dbg
 #else