Commit 08a4f00e authored by Thomas Hellström's avatar Thomas Hellström Committed by Rodrigo Vivi
Browse files

drm/xe/bo: Simplify xe_bo_lock()



xe_bo_lock() was, although it only grabbed a single lock, unnecessarily
using ttm_eu_reserve_buffers(). Simplify and document the interface.

v2:
- Update also the xe_display subsystem.
v4:
- Reinstate a lost dma_resv_reserve_fences().
- Improve on xe_bo_lock() documentation (Matthew Brost)

Signed-off-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: default avatarMatthew Brost <matthew.brost@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230908091716.36984-2-thomas.hellstrom@linux.intel.com


Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent 9fa81f91
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -204,9 +204,9 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
			goto cleanup_bo;
		}

		xe_bo_lock(external, &ww, 0, false);
		xe_bo_lock(external, false);
		err = xe_bo_pin_external(external);
		xe_bo_unlock(external, &ww);
		xe_bo_unlock(external);
		if (err) {
			KUNIT_FAIL(test, "external bo pin err=%pe\n",
				   ERR_PTR(err));
@@ -272,9 +272,9 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
					   ERR_PTR(err));
				goto cleanup_all;
			}
			xe_bo_lock(external, &ww, 0, false);
			xe_bo_lock(external, false);
			err = xe_bo_validate(external, NULL, false);
			xe_bo_unlock(external, &ww);
			xe_bo_unlock(external);
			if (err) {
				KUNIT_FAIL(test, "external bo valid err=%pe\n",
					   ERR_PTR(err));
@@ -282,28 +282,28 @@ static int evict_test_run_tile(struct xe_device *xe, struct xe_tile *tile, struc
			}
		}

		xe_bo_lock(external, &ww, 0, false);
		xe_bo_lock(external, false);
		xe_bo_unpin_external(external);
		xe_bo_unlock(external, &ww);
		xe_bo_unlock(external);

		xe_bo_put(external);

		xe_bo_lock(bo, &ww, 0, false);
		xe_bo_lock(bo, false);
		__xe_bo_unset_bulk_move(bo);
		xe_bo_unlock(bo, &ww);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		continue;

cleanup_all:
		xe_bo_lock(external, &ww, 0, false);
		xe_bo_lock(external, false);
		xe_bo_unpin_external(external);
		xe_bo_unlock(external, &ww);
		xe_bo_unlock(external);
cleanup_external:
		xe_bo_put(external);
cleanup_bo:
		xe_bo_lock(bo, &ww, 0, false);
		xe_bo_lock(bo, false);
		__xe_bo_unset_bulk_move(bo);
		xe_bo_unlock(bo, &ww);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		break;
	}
+26 −17
Original line number Diff line number Diff line
@@ -1082,13 +1082,11 @@ static void xe_gem_object_close(struct drm_gem_object *obj,
	struct xe_bo *bo = gem_to_xe_bo(obj);

	if (bo->vm && !xe_vm_in_fault_mode(bo->vm)) {
		struct ww_acquire_ctx ww;

		XE_WARN_ON(!xe_bo_is_user(bo));

		xe_bo_lock(bo, &ww, 0, false);
		xe_bo_lock(bo, false);
		ttm_bo_set_bulk_move(&bo->ttm, NULL);
		xe_bo_unlock(bo, &ww);
		xe_bo_unlock(bo);
	}
}

@@ -1873,26 +1871,37 @@ int xe_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
	return 0;
}

int xe_bo_lock(struct xe_bo *bo, struct ww_acquire_ctx *ww,
	       int num_resv, bool intr)
/**
 * xe_bo_lock() - Lock the buffer object's dma_resv object
 * @bo: The struct xe_bo whose lock is to be taken
 * @intr: Whether to perform any wait interruptible
 *
 * Locks the buffer object's dma_resv object. If the buffer object is
 * pointing to a shared dma_resv object, that shared lock is locked.
 *
 * Return: 0 on success, -EINTR if @intr is true and the wait for a
 * contended lock was interrupted. If @intr is set to false, the
 * function always returns 0.
 */
int xe_bo_lock(struct xe_bo *bo, bool intr)
{
	struct ttm_validate_buffer tv_bo;
	LIST_HEAD(objs);
	LIST_HEAD(dups);
	if (intr)
		return dma_resv_lock_interruptible(bo->ttm.base.resv, NULL);

	XE_WARN_ON(!ww);
	dma_resv_lock(bo->ttm.base.resv, NULL);

	tv_bo.num_shared = num_resv;
	tv_bo.bo = &bo->ttm;
	list_add_tail(&tv_bo.head, &objs);

	return ttm_eu_reserve_buffers(ww, &objs, intr, &dups);
	return 0;
}

void xe_bo_unlock(struct xe_bo *bo, struct ww_acquire_ctx *ww)
/**
 * xe_bo_unlock() - Unlock the buffer object's dma_resv object
 * @bo: The struct xe_bo whose lock is to be released.
 *
 * Unlock a buffer object lock that was locked by xe_bo_lock().
 */
void xe_bo_unlock(struct xe_bo *bo)
{
	dma_resv_unlock(bo->ttm.base.resv);
	ww_acquire_fini(ww);
}

/**
+2 −3
Original line number Diff line number Diff line
@@ -158,10 +158,9 @@ static inline void xe_bo_assert_held(struct xe_bo *bo)
		dma_resv_assert_held((bo)->ttm.base.resv);
}

int xe_bo_lock(struct xe_bo *bo, struct ww_acquire_ctx *ww,
	       int num_resv, bool intr);
int xe_bo_lock(struct xe_bo *bo, bool intr);

void xe_bo_unlock(struct xe_bo *bo, struct ww_acquire_ctx *ww);
void xe_bo_unlock(struct xe_bo *bo);

static inline void xe_bo_unlock_vm_held(struct xe_bo *bo)
{
+8 −11
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@
int xe_bo_evict_all(struct xe_device *xe)
{
	struct ttm_device *bdev = &xe->ttm;
	struct ww_acquire_ctx ww;
	struct xe_bo *bo;
	struct xe_tile *tile;
	struct list_head still_in_list;
@@ -62,9 +61,9 @@ int xe_bo_evict_all(struct xe_device *xe)
		list_move_tail(&bo->pinned_link, &still_in_list);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, &ww, 0, false);
		xe_bo_lock(bo, false);
		ret = xe_bo_evict_pinned(bo);
		xe_bo_unlock(bo, &ww);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		if (ret) {
			spin_lock(&xe->pinned.lock);
@@ -96,9 +95,9 @@ int xe_bo_evict_all(struct xe_device *xe)
		list_move_tail(&bo->pinned_link, &xe->pinned.evicted);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, &ww, 0, false);
		xe_bo_lock(bo, false);
		ret = xe_bo_evict_pinned(bo);
		xe_bo_unlock(bo, &ww);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		if (ret)
			return ret;
@@ -123,7 +122,6 @@ int xe_bo_evict_all(struct xe_device *xe)
 */
int xe_bo_restore_kernel(struct xe_device *xe)
{
	struct ww_acquire_ctx ww;
	struct xe_bo *bo;
	int ret;

@@ -140,9 +138,9 @@ int xe_bo_restore_kernel(struct xe_device *xe)
		list_move_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, &ww, 0, false);
		xe_bo_lock(bo, false);
		ret = xe_bo_restore_pinned(bo);
		xe_bo_unlock(bo, &ww);
		xe_bo_unlock(bo);
		if (ret) {
			xe_bo_put(bo);
			return ret;
@@ -184,7 +182,6 @@ int xe_bo_restore_kernel(struct xe_device *xe)
 */
int xe_bo_restore_user(struct xe_device *xe)
{
	struct ww_acquire_ctx ww;
	struct xe_bo *bo;
	struct xe_tile *tile;
	struct list_head still_in_list;
@@ -206,9 +203,9 @@ int xe_bo_restore_user(struct xe_device *xe)
		xe_bo_get(bo);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, &ww, 0, false);
		xe_bo_lock(bo, false);
		ret = xe_bo_restore_pinned(bo);
		xe_bo_unlock(bo, &ww);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		if (ret) {
			spin_lock(&xe->pinned.lock);
+15 −26
Original line number Diff line number Diff line
@@ -171,20 +171,18 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)

	/* Lock VM and BOs dma-resv */
	bo = xe_vma_bo(vma);
	if (only_needs_bo_lock(bo)) {
		/* This path ensures the BO's LRU is updated */
		ret = xe_bo_lock(bo, &ww, xe->info.tile_count, false);
	} else {
	if (!only_needs_bo_lock(bo)) {
		tv_vm.num_shared = xe->info.tile_count;
		tv_vm.bo = xe_vm_ttm_bo(vm);
		list_add(&tv_vm.head, &objs);
	}
	if (bo) {
		tv_bo.bo = &bo->ttm;
		tv_bo.num_shared = xe->info.tile_count;
		list_add(&tv_bo.head, &objs);
	}

	ret = ttm_eu_reserve_buffers(&ww, &objs, false, &dups);
	}
	if (ret)
		goto unlock_vm;

@@ -227,9 +225,6 @@ static int handle_pagefault(struct xe_gt *gt, struct pagefault *pf)
	vma->usm.tile_invalidated &= ~BIT(tile->id);

unlock_dma_resv:
	if (only_needs_bo_lock(bo))
		xe_bo_unlock(bo, &ww);
	else
	ttm_eu_backoff_reservation(&ww, &objs);
unlock_vm:
	if (!ret)
@@ -534,27 +529,21 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc)

	/* Lock VM and BOs dma-resv */
	bo = xe_vma_bo(vma);
	if (only_needs_bo_lock(bo)) {
		/* This path ensures the BO's LRU is updated */
		ret = xe_bo_lock(bo, &ww, xe->info.tile_count, false);
	} else {
	if (!only_needs_bo_lock(bo)) {
		tv_vm.num_shared = xe->info.tile_count;
		tv_vm.bo = xe_vm_ttm_bo(vm);
		list_add(&tv_vm.head, &objs);
	}
	tv_bo.bo = &bo->ttm;
	tv_bo.num_shared = xe->info.tile_count;
	list_add(&tv_bo.head, &objs);
	ret = ttm_eu_reserve_buffers(&ww, &objs, false, &dups);
	}
	if (ret)
		goto unlock_vm;

	/* Migrate to VRAM, move should invalidate the VMA first */
	ret = xe_bo_migrate(bo, XE_PL_VRAM0 + tile->id);

	if (only_needs_bo_lock(bo))
		xe_bo_unlock(bo, &ww);
	else
	ttm_eu_backoff_reservation(&ww, &objs);
unlock_vm:
	up_read(&vm->lock);
Loading