Commit 9bf4ca1e authored by Alice Ryhl's avatar Alice Ryhl Committed by Danilo Krummrich
Browse files

drm/gpuvm: drm_gpuvm_bo_obtain() requires lock and staged mode



In commit 9ce4aef9 ("drm/gpuvm: take GEM lock inside
drm_gpuvm_bo_obtain_prealloc()") we update
drm_gpuvm_bo_obtain_prealloc() to take locks internally, which means
that it's only usable in immediate mode.

In this commit, we notice that drm_gpuvm_bo_obtain() requires you to use
staged mode. This means that we now have one variant of obtain for each
mode you might use gpuvm in.

To reflect this information, we add a warning about using it in
immediate mode, and to make the distinction clearer we rename the method
with a _locked() suffix so that it's clear that it requires the caller
to take the locks.

Reviewed-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: default avatarAlice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260108-gpuvm-rust-v2-2-dbd014005a0b@google.com


[ Slightly reword commit message to refer to commit 9ce4aef9
  ("drm/gpuvm: take GEM lock inside drm_gpuvm_bo_obtain_prealloc()").
  - Danilo ]
Signed-off-by: default avatarDanilo Krummrich <dakr@kernel.org>
parent 44e4c889
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -1825,16 +1825,26 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_bo_find);
 * count of the &drm_gpuvm_bo accordingly. If not found, allocates a new
 * &drm_gpuvm_bo.
 *
 * Requires the lock for the GEMs gpuva list.
 *
 * A new &drm_gpuvm_bo is added to the GEMs gpuva list.
 *
 * Returns: a pointer to the &drm_gpuvm_bo on success, an ERR_PTR on failure
 */
struct drm_gpuvm_bo *
drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm,
drm_gpuvm_bo_obtain_locked(struct drm_gpuvm *gpuvm,
			   struct drm_gem_object *obj)
{
	struct drm_gpuvm_bo *vm_bo;

	/*
	 * In immediate mode this would require the caller to hold the GEMs
	 * gpuva mutex, but it's not okay to allocate while holding that lock,
	 * and this method allocates. Immediate mode drivers should use
	 * drm_gpuvm_bo_obtain_prealloc() instead.
	 */
	drm_WARN_ON(gpuvm->drm, drm_gpuvm_immediate_mode(gpuvm));

	vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
	if (vm_bo)
		return vm_bo;
@@ -1848,7 +1858,7 @@ drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm,

	return vm_bo;
}
EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain);
EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_locked);

/**
 * drm_gpuvm_bo_obtain_prealloc() - obtains an instance of the &drm_gpuvm_bo
+1 −1
Original line number Diff line number Diff line
@@ -256,7 +256,7 @@ pvr_vm_bind_op_map_init(struct pvr_vm_bind_op *bind_op,
	bind_op->type = PVR_VM_BIND_TYPE_MAP;

	dma_resv_lock(obj->resv, NULL);
	bind_op->gpuvm_bo = drm_gpuvm_bo_obtain(&vm_ctx->gpuvm_mgr, obj);
	bind_op->gpuvm_bo = drm_gpuvm_bo_obtain_locked(&vm_ctx->gpuvm_mgr, obj);
	dma_resv_unlock(obj->resv);
	if (IS_ERR(bind_op->gpuvm_bo))
		return PTR_ERR(bind_op->gpuvm_bo);
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ struct msm_gem_vm_log_entry {
 * embedded in any larger driver structure.  The GEM object holds a list of
 * drm_gpuvm_bo, which in turn holds a list of msm_gem_vma.  A linked vma
 * holds a reference to the vm_bo, and drops it when the vma is unlinked.
 * So we just need to call drm_gpuvm_bo_obtain() to return a ref to an
 * So we just need to call drm_gpuvm_bo_obtain_locked() to return a ref to an
 * existing vm_bo, or create a new one.  Once the vma is linked, the ref
 * to the vm_bo can be dropped (since the vma is holding one).
 */
+1 −1
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ msm_gem_vma_new(struct drm_gpuvm *gpuvm, struct drm_gem_object *obj,
	if (!obj)
		return &vma->base;

	vm_bo = drm_gpuvm_bo_obtain(&vm->base, obj);
	vm_bo = drm_gpuvm_bo_obtain_locked(&vm->base, obj);
	if (IS_ERR(vm_bo)) {
		ret = PTR_ERR(vm_bo);
		goto err_va_remove;
+1 −1
Original line number Diff line number Diff line
@@ -1275,7 +1275,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job,
				return -ENOENT;

			dma_resv_lock(obj->resv, NULL);
			op->vm_bo = drm_gpuvm_bo_obtain(&uvmm->base, obj);
			op->vm_bo = drm_gpuvm_bo_obtain_locked(&uvmm->base, obj);
			dma_resv_unlock(obj->resv);
			if (IS_ERR(op->vm_bo))
				return PTR_ERR(op->vm_bo);
Loading