[PATCH v5] drm/amdgpu: bind BOs when the eviction fence is attached

Yifan Zhang <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Prerona Ghosh <[email protected]>

DMA-buf imports are created in TTM_PL_SYSTEM and land on the VM idle
list, so nothing binds them for a VM using user queues: amdgpu_vm_validate()
and amdgpu_userq_bo_validate() skip idle BOs, and amdgpu_cs never runs.
AMDGPU_GEM_VA then programs PTEs without AMDGPU_PTE_VALID and the first
GPU access faults.

amdgpu_evf_mgr_attach_fence() is the right place to fix this, but it only
validated while the eviction fence was unsignaled. At amdgpu_gem_object_open()
time the fence is still the permanently signaled stub installed by
amdgpu_evf_mgr_init(); a real fence only appears after amdgpu_evf_mgr_rearm().
Natively created BOs hide the bug because amdgpu_bo_create() already
validated them.

Validate imported BOs even when the fence is signaled, and unwind the
bo_va if that fails.

v3: validate inside amdgpu_gem_object_open (Christian)
v4: fix amdgpu_evf_mgr_attach_fence itself instead (Christian)
v5: restrict the extra validation to imports so that resident and pinned
    BOs are not migrated or failed on every GEM open

Signed-off-by: Prerona Ghosh <[email protected]>
Signed-off-by: Yifan Zhang <[email protected]>
Assisted-by: Claude:claude-opus-5.0
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c | 11 ++++++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c            |  9 ++++++++-
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
index 4c5e38dea4c2..c2f9380511a3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c
@@ -101,11 +101,16 @@ int amdgpu_evf_mgr_attach_fence(struct amdgpu_eviction_fence_mgr *evf_mgr,
 	struct dma_resv *resv = bo->tbo.base.resv;
 	int ret;
 
-	if (!dma_fence_is_signaled(ev_fence)) {
-
+	/*
+	 * Imports are created in TTM_PL_SYSTEM and this is the only place a VM
+	 * using user queues binds them, so validate those even when the fence
+	 * is already signaled.
+	 */
+	if (!dma_fence_is_signaled(ev_fence) ||
+	    drm_gem_is_imported(&bo->tbo.base)) {
 		amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
 		ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
-		if (!ret)
+		if (!ret && !dma_fence_is_signaled(ev_fence))
 			dma_resv_add_fence(resv, ev_fence,
 					   DMA_RESV_USAGE_BOOKKEEP);
 	} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index f754a4a3a1c2..3118b3036564 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -264,9 +264,16 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
 	bo_va = amdgpu_vm_bo_find(vm, abo);
 	if (!bo_va) {
 		bo_va = amdgpu_vm_bo_add(adev, vm, abo);
+		if (!bo_va) {
+			r = -ENOMEM;
+			goto out_unlock;
+		}
+
 		r = amdgpu_evf_mgr_attach_fence(&fpriv->evf_mgr, abo);
-		if (r)
+		if (r) {
+			amdgpu_vm_bo_del(adev, bo_va);
 			goto out_unlock;
+		}
 	} else {
 		++bo_va->ref_count;
 	}
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.