drm/xe: add missing bulk_move reset
authorMatthew Auld <matthew.auld@intel.com>
Thu, 13 Jul 2023 09:00:49 +0000 (10:00 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:37:37 +0000 (11:37 -0500)
It looks like bulk_move is set during object construction, but is only
removed on object close, however in various places we might not yet have
an actual fd to close, like on the error paths for the gem_create ioctl,
and also one internal user for the evict_test_run_gt() selftest. Try to
handle those cases by manually resetting the bulk_move. This should
prevent triggering:

WARNING: CPU: 7 PID: 8252 at drivers/gpu/drm/ttm/ttm_bo.c:327
ttm_bo_release+0x25e/0x2a0 [ttm]

v2 (Nirmoy):
  - It should be safe to just unconditionally call
    __xe_bo_unset_bulk_move() in most places.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Nirmoy Das <nirmoy.das@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/tests/xe_bo.c
drivers/gpu/drm/xe/xe_bo.c
drivers/gpu/drm/xe/xe_bo.h

index 5d60dc6bfe7110ccfc4172335eaa12df495b385c..b32a9068d76c875fdd51a8ce4dab6b84a593bbaa 100644 (file)
@@ -283,6 +283,10 @@ static int evict_test_run_gt(struct xe_device *xe, struct xe_gt *gt, struct kuni
                xe_bo_unlock(external, &ww);
 
                xe_bo_put(external);
+
+               xe_bo_lock(bo, &ww, 0, false);
+               __xe_bo_unset_bulk_move(bo);
+               xe_bo_unlock(bo, &ww);
                xe_bo_put(bo);
                continue;
 
@@ -293,6 +297,9 @@ cleanup_all:
 cleanup_external:
                xe_bo_put(external);
 cleanup_bo:
+               xe_bo_lock(bo, &ww, 0, false);
+               __xe_bo_unset_bulk_move(bo);
+               xe_bo_unlock(bo, &ww);
                xe_bo_put(bo);
                break;
        }
index 9ad5cf3e246332f28a3bc399fad6eeaea9df350d..a3bb14aa223457cd420258a50f25bb5f64ddca89 100644 (file)
@@ -1327,6 +1327,7 @@ xe_bo_create_locked_range(struct xe_device *xe,
        return bo;
 
 err_unlock_put_bo:
+       __xe_bo_unset_bulk_move(bo);
        xe_bo_unlock_vm_held(bo);
        xe_bo_put(bo);
        return ERR_PTR(err);
@@ -1770,22 +1771,29 @@ int xe_gem_create_ioctl(struct drm_device *dev, void *data,
        bo_flags |= args->flags << (ffs(XE_BO_CREATE_SYSTEM_BIT) - 1);
        bo = xe_bo_create(xe, NULL, vm, args->size, ttm_bo_type_device,
                          bo_flags);
-       if (vm) {
-               xe_vm_unlock(vm, &ww);
-               xe_vm_put(vm);
+       if (IS_ERR(bo)) {
+               err = PTR_ERR(bo);
+               goto out_vm;
        }
 
-       if (IS_ERR(bo))
-               return PTR_ERR(bo);
-
        err = drm_gem_handle_create(file, &bo->ttm.base, &handle);
-       xe_bo_put(bo);
        if (err)
-               return err;
+               goto out_bulk;
 
        args->handle = handle;
+       goto out_put;
 
-       return 0;
+out_bulk:
+       if (vm && !xe_vm_in_fault_mode(vm))
+               __xe_bo_unset_bulk_move(bo);
+out_put:
+       xe_bo_put(bo);
+out_vm:
+       if (vm) {
+               xe_vm_unlock(vm, &ww);
+               xe_vm_put(vm);
+       }
+       return err;
 }
 
 int xe_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
index 53a82ff7bce25c470d8b1e198ed66b9c07567547..3e98f3c0b85e47486794c3866dda7516d08c21c5 100644 (file)
@@ -144,6 +144,12 @@ static inline void xe_bo_put(struct xe_bo *bo)
                drm_gem_object_put(&bo->ttm.base);
 }
 
+static inline void __xe_bo_unset_bulk_move(struct xe_bo *bo)
+{
+       if (bo)
+               ttm_bo_set_bulk_move(&bo->ttm, NULL);
+}
+
 static inline void xe_bo_assert_held(struct xe_bo *bo)
 {
        if (bo)