All of lore.kernel.org
 help / color / mirror / Atom feed
* VM changes for invalidating PTEs without holding the reservation lock
@ 2020-01-06 15:03 Christian König
  2020-01-06 15:03 ` [PATCH 01/12] drm/amdgpu: explicitely sync to VM updates v2 Christian König
                   ` (11 more replies)
  0 siblings, 12 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

Hi guys,

I'm still narrowing down one problem with the glob lru lock, but that only happens in a constructed test case so far.

Please take a look and comment,
Christian.


_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/12] drm/amdgpu: explicitely sync to VM updates v2
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 02/12] drm/amdgpu: stop adding VM updates fences to the resv obj Christian König
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

Allows us to reduce the overhead while syncing to fences a bit.

v2: also drop adev parameter from the functions

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  8 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c        | 19 +++-------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c       | 13 +++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c       |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c      | 38 ++++++++++++++-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h      |  8 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c   |  2 +-
 7 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index b6d1958d514f..d8db5ecdf9c1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -358,7 +358,7 @@ static int vm_update_pds(struct amdgpu_vm *vm, struct amdgpu_sync *sync)
 	if (ret)
 		return ret;
 
-	return amdgpu_sync_fence(NULL, sync, vm->last_update, false);
+	return amdgpu_sync_fence(sync, vm->last_update, false);
 }
 
 static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
@@ -751,7 +751,7 @@ static int unmap_bo_from_gpuvm(struct amdgpu_device *adev,
 
 	amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
 
-	amdgpu_sync_fence(NULL, sync, bo_va->last_pt_update, false);
+	amdgpu_sync_fence(sync, bo_va->last_pt_update, false);
 
 	return 0;
 }
@@ -770,7 +770,7 @@ static int update_gpuvm_pte(struct amdgpu_device *adev,
 		return ret;
 	}
 
-	return amdgpu_sync_fence(NULL, sync, bo_va->last_pt_update, false);
+	return amdgpu_sync_fence(sync, bo_va->last_pt_update, false);
 }
 
 static int map_bo_to_gpuvm(struct amdgpu_device *adev,
@@ -2045,7 +2045,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
 			pr_debug("Memory eviction: Validate BOs failed. Try again\n");
 			goto validate_map_fail;
 		}
-		ret = amdgpu_sync_fence(NULL, &sync_obj, bo->tbo.moving, false);
+		ret = amdgpu_sync_fence(&sync_obj, bo->tbo.moving, false);
 		if (ret) {
 			pr_debug("Memory eviction: Sync BO fence failed. Try again\n");
 			goto validate_map_fail;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 9e0c99760367..614919f265b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -799,29 +799,23 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
 	if (r)
 		return r;
 
-	r = amdgpu_sync_fence(adev, &p->job->sync,
-			      fpriv->prt_va->last_pt_update, false);
+	r = amdgpu_sync_vm_fence(&p->job->sync, fpriv->prt_va->last_pt_update);
 	if (r)
 		return r;
 
 	if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
-		struct dma_fence *f;
-
 		bo_va = fpriv->csa_va;
 		BUG_ON(!bo_va);
 		r = amdgpu_vm_bo_update(adev, bo_va, false);
 		if (r)
 			return r;
 
-		f = bo_va->last_pt_update;
-		r = amdgpu_sync_fence(adev, &p->job->sync, f, false);
+		r = amdgpu_sync_vm_fence(&p->job->sync, bo_va->last_pt_update);
 		if (r)
 			return r;
 	}
 
 	amdgpu_bo_list_for_each_entry(e, p->bo_list) {
-		struct dma_fence *f;
-
 		/* ignore duplicates */
 		bo = ttm_to_amdgpu_bo(e->tv.bo);
 		if (!bo)
@@ -835,8 +829,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
 		if (r)
 			return r;
 
-		f = bo_va->last_pt_update;
-		r = amdgpu_sync_fence(adev, &p->job->sync, f, false);
+		r = amdgpu_sync_vm_fence(&p->job->sync, bo_va->last_pt_update);
 		if (r)
 			return r;
 	}
@@ -849,7 +842,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
 	if (r)
 		return r;
 
-	r = amdgpu_sync_fence(adev, &p->job->sync, vm->last_update, false);
+	r = amdgpu_sync_vm_fence(&p->job->sync, vm->last_update);
 	if (r)
 		return r;
 
@@ -991,7 +984,7 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p,
 			dma_fence_put(old);
 		}
 
-		r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true);
+		r = amdgpu_sync_fence(&p->job->sync, fence, true);
 		dma_fence_put(fence);
 		if (r)
 			return r;
@@ -1013,7 +1006,7 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
 		return r;
 	}
 
-	r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true);
+	r = amdgpu_sync_fence(&p->job->sync, fence, true);
 	dma_fence_put(fence);
 
 	return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
index 6f9289735e31..3a67f6c046d4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -206,7 +206,7 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
 	int r;
 
 	if (ring->vmid_wait && !dma_fence_is_signaled(ring->vmid_wait))
-		return amdgpu_sync_fence(adev, sync, ring->vmid_wait, false);
+		return amdgpu_sync_fence(sync, ring->vmid_wait, false);
 
 	fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL);
 	if (!fences)
@@ -241,7 +241,7 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
 			return -ENOMEM;
 		}
 
-		r = amdgpu_sync_fence(adev, sync, &array->base, false);
+		r = amdgpu_sync_fence(sync, &array->base, false);
 		dma_fence_put(ring->vmid_wait);
 		ring->vmid_wait = &array->base;
 		return r;
@@ -294,7 +294,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
 		tmp = amdgpu_sync_peek_fence(&(*id)->active, ring);
 		if (tmp) {
 			*id = NULL;
-			r = amdgpu_sync_fence(adev, sync, tmp, false);
+			r = amdgpu_sync_fence(sync, tmp, false);
 			return r;
 		}
 		needs_flush = true;
@@ -303,7 +303,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
 	/* Good we can use this VMID. Remember this submission as
 	* user of the VMID.
 	*/
-	r = amdgpu_sync_fence(ring->adev, &(*id)->active, fence, false);
+	r = amdgpu_sync_fence(&(*id)->active, fence, false);
 	if (r)
 		return r;
 
@@ -375,7 +375,7 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
 		/* Good, we can use this VMID. Remember this submission as
 		 * user of the VMID.
 		 */
-		r = amdgpu_sync_fence(ring->adev, &(*id)->active, fence, false);
+		r = amdgpu_sync_fence(&(*id)->active, fence, false);
 		if (r)
 			return r;
 
@@ -435,8 +435,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
 			id = idle;
 
 			/* Remember this submission as user of the VMID */
-			r = amdgpu_sync_fence(ring->adev, &id->active,
-					      fence, false);
+			r = amdgpu_sync_fence(&id->active, fence, false);
 			if (r)
 				goto error;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 4fb20e870e63..73328d0c741d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -193,8 +193,7 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,
 	fence = amdgpu_sync_get_fence(&job->sync, &explicit);
 	if (fence && explicit) {
 		if (drm_sched_dependency_optimized(fence, s_entity)) {
-			r = amdgpu_sync_fence(ring->adev, &job->sched_sync,
-					      fence, false);
+			r = amdgpu_sync_fence(&job->sched_sync, fence, false);
 			if (r)
 				DRM_ERROR("Error adding fence (%d)\n", r);
 		}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index 95e5e93edd18..f1e5fbef54d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -129,7 +129,8 @@ static void amdgpu_sync_keep_later(struct dma_fence **keep,
  * Tries to add the fence to an existing hash entry. Returns true when an entry
  * was found, false otherwise.
  */
-static bool amdgpu_sync_add_later(struct amdgpu_sync *sync, struct dma_fence *f, bool explicit)
+static bool amdgpu_sync_add_later(struct amdgpu_sync *sync, struct dma_fence *f,
+				  bool explicit)
 {
 	struct amdgpu_sync_entry *e;
 
@@ -151,19 +152,18 @@ static bool amdgpu_sync_add_later(struct amdgpu_sync *sync, struct dma_fence *f,
  * amdgpu_sync_fence - remember to sync to this fence
  *
  * @sync: sync object to add fence to
- * @fence: fence to sync to
+ * @f: fence to sync to
+ * @explicit: if this is an explicit dependency
  *
+ * Add the fence to the sync object.
  */
-int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
-		      struct dma_fence *f, bool explicit)
+int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f,
+		      bool explicit)
 {
 	struct amdgpu_sync_entry *e;
 
 	if (!f)
 		return 0;
-	if (amdgpu_sync_same_dev(adev, f) &&
-	    amdgpu_sync_get_owner(f) == AMDGPU_FENCE_OWNER_VM)
-		amdgpu_sync_keep_later(&sync->last_vm_update, f);
 
 	if (amdgpu_sync_add_later(sync, f, explicit))
 		return 0;
@@ -179,6 +179,24 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
 	return 0;
 }
 
+/**
+ * amdgpu_sync_vm_fence - remember to sync to this VM fence
+ *
+ * @adev: amdgpu device
+ * @sync: sync object to add fence to
+ * @fence: the VM fence to add
+ *
+ * Add the fence to the sync object and remember it as VM update.
+ */
+int amdgpu_sync_vm_fence(struct amdgpu_sync *sync, struct dma_fence *fence)
+{
+	if (!fence)
+		return 0;
+
+	amdgpu_sync_keep_later(&sync->last_vm_update, fence);
+	return amdgpu_sync_fence(sync, fence, false);
+}
+
 /**
  * amdgpu_sync_resv - sync to a reservation object
  *
@@ -204,7 +222,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 
 	/* always sync to the exclusive fence */
 	f = dma_resv_get_excl(resv);
-	r = amdgpu_sync_fence(adev, sync, f, false);
+	r = amdgpu_sync_fence(sync, f, false);
 
 	flist = dma_resv_get_list(resv);
 	if (!flist || r)
@@ -239,7 +257,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 				continue;
 		}
 
-		r = amdgpu_sync_fence(adev, sync, f, false);
+		r = amdgpu_sync_fence(sync, f, false);
 		if (r)
 			break;
 	}
@@ -340,7 +358,7 @@ int amdgpu_sync_clone(struct amdgpu_sync *source, struct amdgpu_sync *clone)
 	hash_for_each_safe(source->fences, i, tmp, e, node) {
 		f = e->fence;
 		if (!dma_fence_is_signaled(f)) {
-			r = amdgpu_sync_fence(NULL, clone, f, e->explicit);
+			r = amdgpu_sync_fence(clone, f, e->explicit);
 			if (r)
 				return r;
 		} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
index b5f1778a2319..d62c2b81d92b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
@@ -40,8 +40,9 @@ struct amdgpu_sync {
 };
 
 void amdgpu_sync_create(struct amdgpu_sync *sync);
-int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
-		      struct dma_fence *f, bool explicit);
+int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f,
+		      bool explicit);
+int amdgpu_sync_vm_fence(struct amdgpu_sync *sync, struct dma_fence *fence);
 int amdgpu_sync_resv(struct amdgpu_device *adev,
 		     struct amdgpu_sync *sync,
 		     struct dma_resv *resv,
@@ -49,7 +50,8 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 		     bool explicit_sync);
 struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
 				     struct amdgpu_ring *ring);
-struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit);
+struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync,
+					bool *explicit);
 int amdgpu_sync_clone(struct amdgpu_sync *source, struct amdgpu_sync *clone);
 int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr);
 void amdgpu_sync_free(struct amdgpu_sync *sync);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index 832db59f441e..50f487666977 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -71,7 +71,7 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
 	p->num_dw_left = ndw;
 
 	/* Wait for moves to be completed */
-	r = amdgpu_sync_fence(p->adev, &p->job->sync, exclusive, false);
+	r = amdgpu_sync_fence(&p->job->sync, exclusive, false);
 	if (r)
 		return r;
 
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/12] drm/amdgpu: stop adding VM updates fences to the resv obj
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
  2020-01-06 15:03 ` [PATCH 01/12] drm/amdgpu: explicitely sync to VM updates v2 Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 03/12] drm/amdgpu: add VM eviction lock v3 Christian König
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

Don't add the VM update fences to the resv object and remove
the handling to stop implicitely syncing to them.

Ongoing updates prevent page tables from being evicted and we manually
block for all updates to complete before releasing PDs and PTS.

This way we can do updates even without the resv obj locked.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c    | 10 +++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c      | 30 ++++++++++++++++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h      |  4 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 11 +++++---
 4 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index f1e5fbef54d8..a09b6b9c27d1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -240,13 +240,11 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 			continue;
 
 		if (amdgpu_sync_same_dev(adev, f)) {
-			/* VM updates are only interesting
-			 * for other VM updates and moves.
+			/* VM updates only sync with moves but not with user
+			 * command submissions or KFD evictions fences
 			 */
-			if ((owner != AMDGPU_FENCE_OWNER_UNDEFINED) &&
-			    (fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED) &&
-			    ((owner == AMDGPU_FENCE_OWNER_VM) !=
-			     (fence_owner == AMDGPU_FENCE_OWNER_VM)))
+			if (owner == AMDGPU_FENCE_OWNER_VM &&
+			    fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED)
 				continue;
 
 			/* Ignore fence from the same owner and explicit one as
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index a22bd57129d1..0d700e8154c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -562,8 +562,8 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
 {
 	entry->priority = 0;
 	entry->tv.bo = &vm->root.base.bo->tbo;
-	/* One for the VM updates, one for TTM and one for the CS job */
-	entry->tv.num_shared = 3;
+	/* One for TTM and one for the CS job */
+	entry->tv.num_shared = 2;
 	entry->user_pages = NULL;
 	list_add(&entry->tv.head, validated);
 }
@@ -2522,6 +2522,11 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo)
 	if (!dma_resv_test_signaled_rcu(bo->tbo.base.resv, true))
 		return false;
 
+	/* Don't evict VM page tables while they are updated */
+	if (!dma_fence_is_signaled(bo_base->vm->last_direct) ||
+	    !dma_fence_is_signaled(bo_base->vm->last_delayed))
+		return false;
+
 	return true;
 }
 
@@ -2687,8 +2692,16 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
  */
 long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
 {
-	return dma_resv_wait_timeout_rcu(vm->root.base.bo->tbo.base.resv,
-						   true, true, timeout);
+	timeout = dma_resv_wait_timeout_rcu(vm->root.base.bo->tbo.base.resv,
+					    true, true, timeout);
+	if (timeout <= 0)
+		return timeout;
+
+	timeout = dma_fence_wait_timeout(vm->last_direct, true, timeout);
+	if (timeout <= 0)
+		return timeout;
+
+	return dma_fence_wait_timeout(vm->last_delayed, true, timeout);
 }
 
 /**
@@ -2757,6 +2770,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	else
 		vm->update_funcs = &amdgpu_vm_sdma_funcs;
 	vm->last_update = NULL;
+	vm->last_direct = dma_fence_get_stub();
+	vm->last_delayed = dma_fence_get_stub();
 
 	amdgpu_vm_bo_param(adev, vm, adev->vm_manager.root_level, false, &bp);
 	if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE)
@@ -2807,6 +2822,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	vm->root.base.bo = NULL;
 
 error_free_delayed:
+	dma_fence_put(vm->last_direct);
+	dma_fence_put(vm->last_delayed);
 	drm_sched_entity_destroy(&vm->delayed);
 
 error_free_direct:
@@ -3007,6 +3024,11 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 		vm->pasid = 0;
 	}
 
+	dma_fence_wait(vm->last_direct, false);
+	dma_fence_put(vm->last_direct);
+	dma_fence_wait(vm->last_delayed, false);
+	dma_fence_put(vm->last_delayed);
+
 	list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
 		if (mapping->flags & AMDGPU_PTE_PRT && prt_fini_needed) {
 			amdgpu_vm_prt_fini(adev, vm);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index db561765453b..d93ea9ad879e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -269,6 +269,10 @@ struct amdgpu_vm {
 	struct drm_sched_entity	direct;
 	struct drm_sched_entity	delayed;
 
+	/* Last submission to the scheduler entities */
+	struct dma_fence	*last_direct;
+	struct dma_fence	*last_delayed;
+
 	unsigned int		pasid;
 	/* dedicated to vm */
 	struct amdgpu_vmid	*reserved_vmid[AMDGPU_MAX_VMHUBS];
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index 50f487666977..19b7f80758f1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -95,11 +95,10 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
 static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
 				 struct dma_fence **fence)
 {
-	struct amdgpu_bo *root = p->vm->root.base.bo;
 	struct amdgpu_ib *ib = p->job->ibs;
 	struct drm_sched_entity *entity;
+	struct dma_fence *f, *tmp;
 	struct amdgpu_ring *ring;
-	struct dma_fence *f;
 	int r;
 
 	entity = p->direct ? &p->vm->direct : &p->vm->delayed;
@@ -112,7 +111,13 @@ static int amdgpu_vm_sdma_commit(struct amdgpu_vm_update_params *p,
 	if (r)
 		goto error;
 
-	amdgpu_bo_fence(root, f, true);
+	tmp = dma_fence_get(f);
+	if (p->direct)
+		swap(p->vm->last_direct, tmp);
+	else
+		swap(p->vm->last_delayed, tmp);
+	dma_fence_put(tmp);
+
 	if (fence && !p->direct)
 		swap(*fence, f);
 	dma_fence_put(f);
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/12] drm/amdgpu: add VM eviction lock v3
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
  2020-01-06 15:03 ` [PATCH 01/12] drm/amdgpu: explicitely sync to VM updates v2 Christian König
  2020-01-06 15:03 ` [PATCH 02/12] drm/amdgpu: stop adding VM updates fences to the resv obj Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 04/12] drm/amdgpu: drop amdgpu_job.owner Christian König
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

This allows to invalidate VM entries without taking the reservation lock.

v3: use -EBUSY

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 39 +++++++++++++++++++++-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  4 +++
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 0d700e8154c4..54430c9f7a27 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -656,7 +656,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 			      void *param)
 {
 	struct amdgpu_vm_bo_base *bo_base, *tmp;
-	int r = 0;
+	int r;
 
 	vm->bulk_moveable &= list_empty(&vm->evicted);
 
@@ -665,7 +665,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 
 		r = validate(param, bo);
 		if (r)
-			break;
+			return r;
 
 		if (bo->tbo.type != ttm_bo_type_kernel) {
 			amdgpu_vm_bo_moved(bo_base);
@@ -678,7 +678,11 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 		}
 	}
 
-	return r;
+	mutex_lock(&vm->eviction_lock);
+	vm->evicting = false;
+	mutex_unlock(&vm->eviction_lock);
+
+	return 0;
 }
 
 /**
@@ -1555,15 +1559,25 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
 	if (!(flags & AMDGPU_PTE_VALID))
 		owner = AMDGPU_FENCE_OWNER_KFD;
 
+	mutex_lock(&vm->eviction_lock);
+	if (vm->evicting) {
+		r = -EBUSY;
+		goto error_unlock;
+	}
+
 	r = vm->update_funcs->prepare(&params, owner, exclusive);
 	if (r)
-		return r;
+		goto error_unlock;
 
 	r = amdgpu_vm_update_ptes(&params, start, last + 1, addr, flags);
 	if (r)
-		return r;
+		goto error_unlock;
 
-	return vm->update_funcs->commit(&params, fence);
+	r = vm->update_funcs->commit(&params, fence);
+
+error_unlock:
+	mutex_unlock(&vm->eviction_lock);
+	return r;
 }
 
 /**
@@ -2522,11 +2536,19 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo)
 	if (!dma_resv_test_signaled_rcu(bo->tbo.base.resv, true))
 		return false;
 
+	/* Try to block ongoing updates */
+	if (!mutex_trylock(&bo_base->vm->eviction_lock))
+		return false;
+
 	/* Don't evict VM page tables while they are updated */
 	if (!dma_fence_is_signaled(bo_base->vm->last_direct) ||
-	    !dma_fence_is_signaled(bo_base->vm->last_delayed))
+	    !dma_fence_is_signaled(bo_base->vm->last_delayed)) {
+		mutex_unlock(&bo_base->vm->eviction_lock);
 		return false;
+	}
 
+	bo_base->vm->evicting = true;
+	mutex_unlock(&bo_base->vm->eviction_lock);
 	return true;
 }
 
@@ -2773,6 +2795,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 	vm->last_direct = dma_fence_get_stub();
 	vm->last_delayed = dma_fence_get_stub();
 
+	mutex_init(&vm->eviction_lock);
+	vm->evicting = false;
+
 	amdgpu_vm_bo_param(adev, vm, adev->vm_manager.root_level, false, &bp);
 	if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE)
 		bp.flags &= ~AMDGPU_GEM_CREATE_SHADOW;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index d93ea9ad879e..d5613d184e99 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -242,6 +242,10 @@ struct amdgpu_vm {
 	/* tree of virtual addresses mapped */
 	struct rb_root_cached	va;
 
+	/* Lock to prevent eviction while we are updating page tables */
+	struct mutex		eviction_lock;
+	bool			evicting;
+
 	/* BOs who needs a validation */
 	struct list_head	evicted;
 
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/12] drm/amdgpu: drop amdgpu_job.owner
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (2 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 03/12] drm/amdgpu: add VM eviction lock v3 Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 05/12] drm/amdgpu: explicitly sync VM update to PDs/PTs Christian König
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

Entirely unused.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  | 1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 1 -
 3 files changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 614919f265b9..c4a8148b9b6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1233,7 +1233,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 		goto error_abort;
 	}
 
-	job->owner = p->filp;
 	p->fence = dma_fence_get(&job->base.s_fence->finished);
 
 	amdgpu_ctx_add_fence(p->ctx, entity, p->fence, &seq);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 73328d0c741d..d42be880a236 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -153,7 +153,6 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
 	if (r)
 		return r;
 
-	job->owner = owner;
 	*f = dma_fence_get(&job->base.s_fence->finished);
 	amdgpu_job_free_resources(job);
 	priority = job->base.s_priority;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
index aa0e375062f2..31c4444b0203 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
@@ -49,7 +49,6 @@ struct amdgpu_job {
 	uint32_t		preamble_status;
 	uint32_t                preemption_status;
 	uint32_t		num_ibs;
-	void			*owner;
 	bool                    vm_needs_flush;
 	uint64_t		vm_pd_addr;
 	unsigned		vmid;
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/12] drm/amdgpu: explicitly sync VM update to PDs/PTs
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (3 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 04/12] drm/amdgpu: drop amdgpu_job.owner Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 06/12] drm/amdgpu: use the VM as job owner Christian König
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

Explicitly sync VM updates to the moving fence in PDs and PTs.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c  | 7 +++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 5 +++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
index 73fec7a0ced5..68b013be3837 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
@@ -86,6 +86,13 @@ static int amdgpu_vm_cpu_update(struct amdgpu_vm_update_params *p,
 {
 	unsigned int i;
 	uint64_t value;
+	int r;
+
+	if (bo->tbo.moving) {
+		r = dma_fence_wait(bo->tbo.moving, true);
+		if (r)
+			return r;
+	}
 
 	pe += (unsigned long)amdgpu_bo_kptr(bo);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index 19b7f80758f1..4bbd8ff778ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -208,6 +208,11 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
 	uint64_t *pte;
 	int r;
 
+	/* Wait for PD/PT moves to be completed */
+	r = amdgpu_sync_fence(&p->job->sync, bo->tbo.moving, false);
+	if (r)
+		return r;
+
 	do {
 		ndw = p->num_dw_left;
 		ndw -= p->job->ibs->length_dw;
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/12] drm/amdgpu: use the VM as job owner
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (4 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 05/12] drm/amdgpu: explicitly sync VM update to PDs/PTs Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 07/12] drm/amdgpu: rework job synchronization Christian König
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

For HMM we need to rework how VM synchronization works, so instead of the filp use VM as job owner.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index c4a8148b9b6f..cf79f30c0af6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -655,6 +655,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 
 static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
 {
+	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
 	struct amdgpu_bo_list_entry *e;
 	int r;
 
@@ -662,7 +663,7 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
 		struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
 		struct dma_resv *resv = bo->tbo.base.resv;
 
-		r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp,
+		r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, &fpriv->vm,
 				     amdgpu_bo_explicit_sync(bo));
 
 		if (r)
@@ -1210,7 +1211,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 	job = p->job;
 	p->job = NULL;
 
-	r = drm_sched_job_init(&job->base, entity, p->filp);
+	r = drm_sched_job_init(&job->base, entity, &fpriv->vm);
 	if (r)
 		goto error_unlock;
 
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/12] drm/amdgpu: rework job synchronization
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (5 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 06/12] drm/amdgpu: use the VM as job owner Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 08/12] drm/amdgpu: rework synchronization of VM updates Christian König
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

For unlocked page table updates we need to be able
to sync to fences of a specific VM.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  6 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c        |  8 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c    |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c      | 49 ++++++++++++-------
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h      | 15 ++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c       |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c   |  2 +-
 8 files changed, 59 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d8db5ecdf9c1..9e7889c28f3e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -848,9 +848,9 @@ static int process_sync_pds_resv(struct amdkfd_process_info *process_info,
 			    vm_list_node) {
 		struct amdgpu_bo *pd = peer_vm->root.base.bo;
 
-		ret = amdgpu_sync_resv(NULL,
-					sync, pd->tbo.base.resv,
-					AMDGPU_FENCE_OWNER_KFD, false);
+		ret = amdgpu_sync_resv(NULL, sync, pd->tbo.base.resv,
+				       AMDGPU_SYNC_NE_OWNER,
+				       AMDGPU_FENCE_OWNER_KFD);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index cf79f30c0af6..d7b5efaa091c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -662,10 +662,12 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
 	list_for_each_entry(e, &p->validated, tv.head) {
 		struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
 		struct dma_resv *resv = bo->tbo.base.resv;
+		enum amdgpu_sync_mode sync_mode;
 
-		r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, &fpriv->vm,
-				     amdgpu_bo_explicit_sync(bo));
-
+		sync_mode = amdgpu_bo_explicit_sync(bo) ?
+			AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER;
+		r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, sync_mode,
+				     &fpriv->vm);
 		if (r)
 			return r;
 	}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index ca9f74585890..46c76e2e1281 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -1419,7 +1419,8 @@ int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr)
 	int r;
 
 	amdgpu_sync_create(&sync);
-	amdgpu_sync_resv(adev, &sync, bo->tbo.base.resv, owner, false);
+	amdgpu_sync_resv(adev, &sync, bo->tbo.base.resv,
+			 AMDGPU_SYNC_NE_OWNER, owner);
 	r = amdgpu_sync_wait(&sync, intr);
 	amdgpu_sync_free(&sync);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index a09b6b9c27d1..c124f64e7aae 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -202,18 +202,17 @@ int amdgpu_sync_vm_fence(struct amdgpu_sync *sync, struct dma_fence *fence)
  *
  * @sync: sync object to add fences from reservation object to
  * @resv: reservation object with embedded fence
- * @explicit_sync: true if we should only sync to the exclusive fence
+ * @mode: how owner affects which fences we sync to
+ * @owner: owner of the planned job submission
  *
  * Sync to the fence
  */
-int amdgpu_sync_resv(struct amdgpu_device *adev,
-		     struct amdgpu_sync *sync,
-		     struct dma_resv *resv,
-		     void *owner, bool explicit_sync)
+int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
+		     struct dma_resv *resv, enum amdgpu_sync_mode mode,
+		     void *owner)
 {
 	struct dma_resv_list *flist;
 	struct dma_fence *f;
-	void *fence_owner;
 	unsigned i;
 	int r = 0;
 
@@ -229,6 +228,8 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 		return r;
 
 	for (i = 0; i < flist->shared_count; ++i) {
+		void *fence_owner;
+
 		f = rcu_dereference_protected(flist->shared[i],
 					      dma_resv_held(resv));
 		/* We only want to trigger KFD eviction fences on
@@ -239,20 +240,34 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
 		    owner != AMDGPU_FENCE_OWNER_UNDEFINED)
 			continue;
 
-		if (amdgpu_sync_same_dev(adev, f)) {
-			/* VM updates only sync with moves but not with user
-			 * command submissions or KFD evictions fences
-			 */
-			if (owner == AMDGPU_FENCE_OWNER_VM &&
-			    fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED)
+		/* VM updates only sync with moves but not with user
+		 * command submissions or KFD evictions fences
+		 */
+		if (fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED &&
+		    owner == AMDGPU_FENCE_OWNER_VM)
+			continue;
+
+		/* Ignore fences depending on the sync mode */
+		switch (mode) {
+		case AMDGPU_SYNC_ALWAYS:
+			break;
+
+		case AMDGPU_SYNC_NE_OWNER:
+			if (amdgpu_sync_same_dev(adev, f) &&
+			    fence_owner == owner)
 				continue;
+			break;
 
-			/* Ignore fence from the same owner and explicit one as
-			 * long as it isn't undefined.
-			 */
-			if (owner != AMDGPU_FENCE_OWNER_UNDEFINED &&
-			    (fence_owner == owner || explicit_sync))
+		case AMDGPU_SYNC_EQ_OWNER:
+			if (amdgpu_sync_same_dev(adev, f) &&
+			    fence_owner != owner)
+				continue;
+			break;
+
+		case AMDGPU_SYNC_EXPLICIT:
+			if (owner != AMDGPU_FENCE_OWNER_UNDEFINED)
 				continue;
+			break;
 		}
 
 		r = amdgpu_sync_fence(sync, f, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
index d62c2b81d92b..cfbe5788b8b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
@@ -31,6 +31,13 @@ struct dma_resv;
 struct amdgpu_device;
 struct amdgpu_ring;
 
+enum amdgpu_sync_mode {
+	AMDGPU_SYNC_ALWAYS,
+	AMDGPU_SYNC_NE_OWNER,
+	AMDGPU_SYNC_EQ_OWNER,
+	AMDGPU_SYNC_EXPLICIT
+};
+
 /*
  * Container for fences used to sync command submissions.
  */
@@ -43,11 +50,9 @@ void amdgpu_sync_create(struct amdgpu_sync *sync);
 int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f,
 		      bool explicit);
 int amdgpu_sync_vm_fence(struct amdgpu_sync *sync, struct dma_fence *fence);
-int amdgpu_sync_resv(struct amdgpu_device *adev,
-		     struct amdgpu_sync *sync,
-		     struct dma_resv *resv,
-		     void *owner,
-		     bool explicit_sync);
+int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
+		     struct dma_resv *resv, enum amdgpu_sync_mode mode,
+		     void *owner);
 struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
 				     struct amdgpu_ring *ring);
 struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 81f6764f1ba6..05aeb55039f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -2086,8 +2086,8 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
 	}
 	if (resv) {
 		r = amdgpu_sync_resv(adev, &job->sync, resv,
-				     AMDGPU_FENCE_OWNER_UNDEFINED,
-				     false);
+				     AMDGPU_SYNC_ALWAYS,
+				     AMDGPU_FENCE_OWNER_UNDEFINED);
 		if (r) {
 			DRM_ERROR("sync failed (%d).\n", r);
 			goto error_free;
@@ -2171,7 +2171,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
 
 	if (resv) {
 		r = amdgpu_sync_resv(adev, &job->sync, resv,
-				     AMDGPU_FENCE_OWNER_UNDEFINED, false);
+				     AMDGPU_SYNC_ALWAYS,
+				     AMDGPU_FENCE_OWNER_UNDEFINED);
 		if (r) {
 			DRM_ERROR("sync failed (%d).\n", r);
 			goto error_free;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index d587ffe2af8e..099ad8d7fc15 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -1098,7 +1098,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
 			goto err_free;
 	} else {
 		r = amdgpu_sync_resv(adev, &job->sync, bo->tbo.base.resv,
-				     AMDGPU_FENCE_OWNER_UNDEFINED, false);
+				     AMDGPU_SYNC_NE_OWNER,
+				     AMDGPU_FENCE_OWNER_UNDEFINED);
 		if (r)
 			goto err_free;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index 4bbd8ff778ea..3b61317c0f08 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -80,7 +80,7 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
 		return 0;
 
 	return amdgpu_sync_resv(p->adev, &p->job->sync, root->tbo.base.resv,
-				owner, false);
+				AMDGPU_SYNC_NE_OWNER, owner);
 }
 
 /**
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/12] drm/amdgpu: rework synchronization of VM updates
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (6 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 07/12] drm/amdgpu: rework job synchronization Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 21:38   ` Felix Kuehling
  2020-01-06 15:03 ` [PATCH 09/12] drm/amdgpu: stop using amdgpu_bo_gpu_offset in the VM backend Christian König
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

If provided we only sync to the BOs reservation
object and no longer to the root PD.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c    |  7 -----
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c      | 34 ++++++++++++---------
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h      |  4 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c  | 25 ++++++---------
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 15 +++------
 5 files changed, 35 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index c124f64e7aae..5816df9f8531 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -240,13 +240,6 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
 		    owner != AMDGPU_FENCE_OWNER_UNDEFINED)
 			continue;
 
-		/* VM updates only sync with moves but not with user
-		 * command submissions or KFD evictions fences
-		 */
-		if (fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED &&
-		    owner == AMDGPU_FENCE_OWNER_VM)
-			continue;
-
 		/* Ignore fences depending on the sync mode */
 		switch (mode) {
 		case AMDGPU_SYNC_ALWAYS:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 54430c9f7a27..a03cfbe670c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -777,7 +777,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
 	params.vm = vm;
 	params.direct = direct;
 
-	r = vm->update_funcs->prepare(&params, AMDGPU_FENCE_OWNER_KFD, NULL);
+	r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
 	if (r)
 		return r;
 
@@ -1273,7 +1273,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
 	params.vm = vm;
 	params.direct = direct;
 
-	r = vm->update_funcs->prepare(&params, AMDGPU_FENCE_OWNER_VM, NULL);
+	r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
 	if (r)
 		return r;
 
@@ -1524,7 +1524,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
  * @adev: amdgpu_device pointer
  * @vm: requested vm
  * @direct: direct submission in a page fault
- * @exclusive: fence we need to sync to
+ * @resv: fences we need to sync to
  * @start: start of mapped range
  * @last: last mapped entry
  * @flags: flags for the entries
@@ -1539,14 +1539,14 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
  */
 static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
 				       struct amdgpu_vm *vm, bool direct,
-				       struct dma_fence *exclusive,
+				       struct dma_resv *resv,
 				       uint64_t start, uint64_t last,
 				       uint64_t flags, uint64_t addr,
 				       dma_addr_t *pages_addr,
 				       struct dma_fence **fence)
 {
 	struct amdgpu_vm_update_params params;
-	void *owner = AMDGPU_FENCE_OWNER_VM;
+	enum amdgpu_sync_mode sync_mode;
 	int r;
 
 	memset(&params, 0, sizeof(params));
@@ -1557,7 +1557,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
 
 	/* sync to everything except eviction fences on unmapping */
 	if (!(flags & AMDGPU_PTE_VALID))
-		owner = AMDGPU_FENCE_OWNER_KFD;
+		sync_mode = AMDGPU_SYNC_EQ_OWNER;
+	else
+		sync_mode = AMDGPU_SYNC_EXPLICIT;
 
 	mutex_lock(&vm->eviction_lock);
 	if (vm->evicting) {
@@ -1565,7 +1567,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
 		goto error_unlock;
 	}
 
-	r = vm->update_funcs->prepare(&params, owner, exclusive);
+	r = vm->update_funcs->prepare(&params, resv, sync_mode);
 	if (r)
 		goto error_unlock;
 
@@ -1584,7 +1586,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
  * amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks
  *
  * @adev: amdgpu_device pointer
- * @exclusive: fence we need to sync to
+ * @resv: fences we need to sync to
  * @pages_addr: DMA addresses to use for mapping
  * @vm: requested vm
  * @mapping: mapped range and flags to use for the update
@@ -1600,7 +1602,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
  * 0 for success, -EINVAL for failure.
  */
 static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
-				      struct dma_fence *exclusive,
+				      struct dma_resv *resv,
 				      dma_addr_t *pages_addr,
 				      struct amdgpu_vm *vm,
 				      struct amdgpu_bo_va_mapping *mapping,
@@ -1676,7 +1678,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
 		}
 
 		last = min((uint64_t)mapping->last, start + max_entries - 1);
-		r = amdgpu_vm_bo_update_mapping(adev, vm, false, exclusive,
+		r = amdgpu_vm_bo_update_mapping(adev, vm, false, resv,
 						start, last, flags, addr,
 						dma_addr, fence);
 		if (r)
@@ -1715,7 +1717,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
 	dma_addr_t *pages_addr = NULL;
 	struct ttm_mem_reg *mem;
 	struct drm_mm_node *nodes;
-	struct dma_fence *exclusive, **last_update;
+	struct dma_fence **last_update;
+	struct dma_resv *resv;
 	uint64_t flags;
 	struct amdgpu_device *bo_adev = adev;
 	int r;
@@ -1723,7 +1726,6 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
 	if (clear || !bo) {
 		mem = NULL;
 		nodes = NULL;
-		exclusive = NULL;
 	} else {
 		struct ttm_dma_tt *ttm;
 
@@ -1733,7 +1735,6 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
 			ttm = container_of(bo->tbo.ttm, struct ttm_dma_tt, ttm);
 			pages_addr = ttm->dma_address;
 		}
-		exclusive = bo->tbo.moving;
 	}
 
 	if (bo) {
@@ -1743,11 +1744,14 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
 			flags |= AMDGPU_PTE_TMZ;
 
 		bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
+		resv = bo->tbo.base.resv;
 	} else {
 		flags = 0x0;
+		resv = NULL;
 	}
 
-	if (clear || (bo && bo->tbo.base.resv == vm->root.base.bo->tbo.base.resv))
+	if (clear || (bo && bo->tbo.base.resv ==
+		      vm->root.base.bo->tbo.base.resv))
 		last_update = &vm->last_update;
 	else
 		last_update = &bo_va->last_pt_update;
@@ -1761,7 +1765,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
 	}
 
 	list_for_each_entry(mapping, &bo_va->invalids, list) {
-		r = amdgpu_vm_bo_split_mapping(adev, exclusive, pages_addr, vm,
+		r = amdgpu_vm_bo_split_mapping(adev, resv, pages_addr, vm,
 					       mapping, flags, bo_adev, nodes,
 					       last_update);
 		if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index d5613d184e99..8fb09648bc97 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -229,8 +229,8 @@ struct amdgpu_vm_update_params {
 
 struct amdgpu_vm_update_funcs {
 	int (*map_table)(struct amdgpu_bo *bo);
-	int (*prepare)(struct amdgpu_vm_update_params *p, void * owner,
-		       struct dma_fence *exclusive);
+	int (*prepare)(struct amdgpu_vm_update_params *p, struct dma_resv *resv,
+		       enum amdgpu_sync_mode sync_mode);
 	int (*update)(struct amdgpu_vm_update_params *p,
 		      struct amdgpu_bo *bo, uint64_t pe, uint64_t addr,
 		      unsigned count, uint32_t incr, uint64_t flags);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
index 68b013be3837..0be72660db4c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
@@ -44,26 +44,21 @@ static int amdgpu_vm_cpu_map_table(struct amdgpu_bo *table)
  * Returns:
  * Negativ errno, 0 for success.
  */
-static int amdgpu_vm_cpu_prepare(struct amdgpu_vm_update_params *p, void *owner,
-				 struct dma_fence *exclusive)
+static int amdgpu_vm_cpu_prepare(struct amdgpu_vm_update_params *p,
+				 struct dma_resv *resv,
+				 enum amdgpu_sync_mode sync_mode)
 {
+	struct amdgpu_sync sync;
 	int r;
 
-	/* Wait for any BO move to be completed */
-	if (exclusive) {
-		r = dma_fence_wait(exclusive, true);
-		if (unlikely(r))
-			return r;
-	}
-
-	/* Don't wait for submissions during page fault */
-	if (p->direct)
+	if (!resv)
 		return 0;
 
-	/* Wait for PT BOs to be idle. PTs share the same resv. object
-	 * as the root PD BO
-	 */
-	return amdgpu_bo_sync_wait(p->vm->root.base.bo, owner, true);
+	amdgpu_sync_create(&sync);
+	amdgpu_sync_resv(p->adev, &sync, resv, sync_mode, p->vm);
+	r = amdgpu_sync_wait(&sync, true);
+	amdgpu_sync_free(&sync);
+	return r;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index 3b61317c0f08..e7a383134521 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -58,9 +58,9 @@ static int amdgpu_vm_sdma_map_table(struct amdgpu_bo *table)
  * Negativ errno, 0 for success.
  */
 static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
-				  void *owner, struct dma_fence *exclusive)
+				  struct dma_resv *resv,
+				  enum amdgpu_sync_mode sync_mode)
 {
-	struct amdgpu_bo *root = p->vm->root.base.bo;
 	unsigned int ndw = AMDGPU_VM_SDMA_MIN_NUM_DW;
 	int r;
 
@@ -70,17 +70,10 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
 
 	p->num_dw_left = ndw;
 
-	/* Wait for moves to be completed */
-	r = amdgpu_sync_fence(&p->job->sync, exclusive, false);
-	if (r)
-		return r;
-
-	/* Don't wait for any submissions during page fault handling */
-	if (p->direct)
+	if (!resv)
 		return 0;
 
-	return amdgpu_sync_resv(p->adev, &p->job->sync, root->tbo.base.resv,
-				AMDGPU_SYNC_NE_OWNER, owner);
+	return amdgpu_sync_resv(p->adev, &p->job->sync, resv, sync_mode, p->vm);
 }
 
 /**
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/12] drm/amdgpu: stop using amdgpu_bo_gpu_offset in the VM backend
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (7 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 08/12] drm/amdgpu: rework synchronization of VM updates Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 10/12] drm/amdgpu: immedially invalidate PTEs Christian König
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

We need to update page tables without any lock held.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index e7a383134521..4cc7881f438c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -140,7 +140,7 @@ static void amdgpu_vm_sdma_copy_ptes(struct amdgpu_vm_update_params *p,
 
 	src += p->num_dw_left * 4;
 
-	pe += amdgpu_bo_gpu_offset(bo);
+	pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
 	trace_amdgpu_vm_copy_ptes(pe, src, count, p->direct);
 
 	amdgpu_vm_copy_pte(p->adev, ib, pe, src, count);
@@ -167,7 +167,7 @@ static void amdgpu_vm_sdma_set_ptes(struct amdgpu_vm_update_params *p,
 {
 	struct amdgpu_ib *ib = p->job->ibs;
 
-	pe += amdgpu_bo_gpu_offset(bo);
+	pe += amdgpu_gmc_sign_extend(bo->tbo.offset);
 	trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags, p->direct);
 	if (count < 3) {
 		amdgpu_vm_write_pte(p->adev, ib, pe, addr | flags,
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/12] drm/amdgpu: immedially invalidate PTEs
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (8 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 09/12] drm/amdgpu: stop using amdgpu_bo_gpu_offset in the VM backend Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 21:04   ` Felix Kuehling
  2020-01-06 15:03 ` [PATCH 11/12] drm/amdgpu: drop unnecessary restriction for huge root PDEs Christian König
  2020-01-06 15:03 ` [PATCH 12/12] drm/amdgpu: make sure to never allocate PDs/PTs for invalidations Christian König
  11 siblings, 1 reply; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

When a BO is evicted immedially invalidate the mapped PTEs.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index a03cfbe670c4..6844ba7467a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2569,6 +2569,7 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
 			     struct amdgpu_bo *bo, bool evicted)
 {
 	struct amdgpu_vm_bo_base *bo_base;
+	int r;
 
 	/* shadow bo doesn't have bo base, its validation needs its parent */
 	if (bo->parent && bo->parent->shadow == bo)
@@ -2576,8 +2577,22 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
 
 	for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) {
 		struct amdgpu_vm *vm = bo_base->vm;
+		struct dma_resv *resv = vm->root.base.bo->tbo.base.resv;
+
+		if (bo->tbo.type != ttm_bo_type_kernel) {
+			struct amdgpu_bo_va *bo_va;
+
+			bo_va = container_of(bo_base, struct amdgpu_bo_va,
+					     base);
+			r = amdgpu_vm_bo_update(adev, bo_va,
+						bo->tbo.base.resv != resv);
+			if (!r) {
+				amdgpu_vm_bo_idle(bo_base);
+				continue;
+			}
+		}
 
-		if (evicted && bo->tbo.base.resv == vm->root.base.bo->tbo.base.resv) {
+		if (evicted && bo->tbo.base.resv == resv) {
 			amdgpu_vm_bo_evicted(bo_base);
 			continue;
 		}
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/12] drm/amdgpu: drop unnecessary restriction for huge root PDEs
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (9 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 10/12] drm/amdgpu: immedially invalidate PTEs Christian König
@ 2020-01-06 15:03 ` Christian König
  2020-01-06 15:03 ` [PATCH 12/12] drm/amdgpu: make sure to never allocate PDs/PTs for invalidations Christian König
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

The root PD can also contain huge PDEs.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 25 +++++--------------------
 1 file changed, 5 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 6844ba7467a6..23729fdd34fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -94,23 +94,17 @@ struct amdgpu_prt_cb {
 static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev,
 				      unsigned level)
 {
-	unsigned shift = 0xff;
-
 	switch (level) {
 	case AMDGPU_VM_PDB2:
 	case AMDGPU_VM_PDB1:
 	case AMDGPU_VM_PDB0:
-		shift = 9 * (AMDGPU_VM_PDB0 - level) +
+		return 9 * (AMDGPU_VM_PDB0 - level) +
 			adev->vm_manager.block_size;
-		break;
 	case AMDGPU_VM_PTB:
-		shift = 0;
-		break;
+		return 0;
 	default:
-		dev_err(adev->dev, "the level%d isn't supported.\n", level);
+		return ~0;
 	}
-
-	return shift;
 }
 
 /**
@@ -1432,13 +1426,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
 
 		pt = cursor.entry->base.bo;
 
-		/* The root level can't be a huge page */
-		if (cursor.level == adev->vm_manager.root_level) {
-			if (!amdgpu_vm_pt_descendant(adev, &cursor))
-				return -ENOENT;
-			continue;
-		}
-
 		shift = amdgpu_vm_level_shift(adev, cursor.level);
 		parent_shift = amdgpu_vm_level_shift(adev, cursor.level - 1);
 		if (adev->asic_type < CHIP_VEGA10 &&
@@ -1457,11 +1444,9 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
 			if (!amdgpu_vm_pt_descendant(adev, &cursor))
 				return -ENOENT;
 			continue;
-		} else if (frag >= parent_shift &&
-			   cursor.level - 1 != adev->vm_manager.root_level) {
+		} else if (frag >= parent_shift) {
 			/* If the fragment size is even larger than the parent
-			 * shift we should go up one level and check it again
-			 * unless one level up is the root level.
+			 * shift we should go up one level and check it again.
 			 */
 			if (!amdgpu_vm_pt_ancestor(&cursor))
 				return -ENOENT;
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 12/12] drm/amdgpu: make sure to never allocate PDs/PTs for invalidations
  2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
                   ` (10 preceding siblings ...)
  2020-01-06 15:03 ` [PATCH 11/12] drm/amdgpu: drop unnecessary restriction for huge root PDEs Christian König
@ 2020-01-06 15:03 ` Christian König
  11 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-06 15:03 UTC (permalink / raw)
  To: Alex.Sierra, Philip.Yang, Felix.Kuehling, amd-gfx

Make sure that we never allocate a page table for an invalidation operation.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 23729fdd34fb..0e8ab09168fc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -1416,15 +1416,15 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
 		uint64_t incr, entry_end, pe_start;
 		struct amdgpu_bo *pt;
 
-		/* make sure that the page tables covering the address range are
-		 * actually allocated
-		 */
-		r = amdgpu_vm_alloc_pts(params->adev, params->vm, &cursor,
-					params->direct);
-		if (r)
-			return r;
-
-		pt = cursor.entry->base.bo;
+		if (flags & AMDGPU_PTE_VALID) {
+			/* make sure that the page tables covering the
+			 * address range are actually allocated
+			 */
+			r = amdgpu_vm_alloc_pts(params->adev, params->vm,
+						&cursor, params->direct);
+			if (r)
+				return r;
+		}
 
 		shift = amdgpu_vm_level_shift(adev, cursor.level);
 		parent_shift = amdgpu_vm_level_shift(adev, cursor.level - 1);
@@ -1453,6 +1453,10 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
 			continue;
 		}
 
+		pt = cursor.entry->base.bo;
+		if (!pt)
+			return -ENOENT;
+
 		/* Looks good so far, calculate parameters for the update */
 		incr = (uint64_t)AMDGPU_GPU_PAGE_SIZE << shift;
 		mask = amdgpu_vm_entries_mask(adev, cursor.level);
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 10/12] drm/amdgpu: immedially invalidate PTEs
  2020-01-06 15:03 ` [PATCH 10/12] drm/amdgpu: immedially invalidate PTEs Christian König
@ 2020-01-06 21:04   ` Felix Kuehling
  2020-01-07 12:48     ` Christian König
  0 siblings, 1 reply; 17+ messages in thread
From: Felix Kuehling @ 2020-01-06 21:04 UTC (permalink / raw)
  To: Christian König, Alex.Sierra, Philip.Yang, amd-gfx

On 2020-01-06 10:03 a.m., Christian König wrote:
> When a BO is evicted immedially invalidate the mapped PTEs.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 17 ++++++++++++++++-
>   1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index a03cfbe670c4..6844ba7467a6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -2569,6 +2569,7 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
>   			     struct amdgpu_bo *bo, bool evicted)
>   {
>   	struct amdgpu_vm_bo_base *bo_base;
> +	int r;
>   
>   	/* shadow bo doesn't have bo base, its validation needs its parent */
>   	if (bo->parent && bo->parent->shadow == bo)
> @@ -2576,8 +2577,22 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
>   
>   	for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) {
>   		struct amdgpu_vm *vm = bo_base->vm;
> +		struct dma_resv *resv = vm->root.base.bo->tbo.base.resv;
> +
> +		if (bo->tbo.type != ttm_bo_type_kernel) {
> +			struct amdgpu_bo_va *bo_va;
> +
> +			bo_va = container_of(bo_base, struct amdgpu_bo_va,
> +					     base);
> +			r = amdgpu_vm_bo_update(adev, bo_va,
> +						bo->tbo.base.resv != resv);

Will this update PTEs for per-VM BOs without validating them first?


> +			if (!r) {
> +				amdgpu_vm_bo_idle(bo_base);

Is this the right state? The description of amdgpu_vm_bo_idle says that 
this is for "PDs/PTs and per VM BOs". For regular BOs, I think this 
should call amdgpu_vm_bo_done.


> +				continue;

This skips a bunch of state machine logic below. Maybe some of that 
could be cleaned up.


> +			}
> +		}
>   
> -		if (evicted && bo->tbo.base.resv == vm->root.base.bo->tbo.base.resv) {
> +		if (evicted && bo->tbo.base.resv == resv) {
>   			amdgpu_vm_bo_evicted(bo_base);

It will never get here for per-VM BOs now (except if bo_update failed). 
Not sure if that's a problem.


>   			continue;
>   		}
>
>                  if (bo_base->moved)
>                          continue;
>                  bo_base->moved = true;

Maybe the whole PT invalidation should be after this to avoid multiple 
invalidations off the same BO?


>
>                  if (bo->tbo.type == ttm_bo_type_kernel)
>                          amdgpu_vm_bo_relocated(bo_base);
>                  else if (bo->tbo.resv == vm->root.base.bo->tbo.resv)
>                          amdgpu_vm_bo_moved(bo_base);
>                  else
>                          amdgpu_vm_bo_invalidated(bo_base);

I believe the last two cases are unreachable now (except if bo_update 
failed).

Regards,
   Felix


_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/12] drm/amdgpu: rework synchronization of VM updates
  2020-01-06 15:03 ` [PATCH 08/12] drm/amdgpu: rework synchronization of VM updates Christian König
@ 2020-01-06 21:38   ` Felix Kuehling
  2020-01-07 12:47     ` Christian König
  0 siblings, 1 reply; 17+ messages in thread
From: Felix Kuehling @ 2020-01-06 21:38 UTC (permalink / raw)
  To: Christian König, Alex.Sierra, Philip.Yang, amd-gfx

On 2020-01-06 10:03 a.m., Christian König wrote:
> If provided we only sync to the BOs reservation
> object and no longer to the root PD.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c    |  7 -----
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c      | 34 ++++++++++++---------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h      |  4 +--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c  | 25 ++++++---------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 15 +++------
>   5 files changed, 35 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
> index c124f64e7aae..5816df9f8531 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
> @@ -240,13 +240,6 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
>   		    owner != AMDGPU_FENCE_OWNER_UNDEFINED)
>   			continue;
>   
> -		/* VM updates only sync with moves but not with user
> -		 * command submissions or KFD evictions fences
> -		 */
> -		if (fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED &&
> -		    owner == AMDGPU_FENCE_OWNER_VM)
> -			continue;
> -
>   		/* Ignore fences depending on the sync mode */
>   		switch (mode) {
>   		case AMDGPU_SYNC_ALWAYS:
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 54430c9f7a27..a03cfbe670c4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -777,7 +777,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
>   	params.vm = vm;
>   	params.direct = direct;
>   
> -	r = vm->update_funcs->prepare(&params, AMDGPU_FENCE_OWNER_KFD, NULL);
> +	r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
>   	if (r)
>   		return r;
>   
> @@ -1273,7 +1273,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
>   	params.vm = vm;
>   	params.direct = direct;
>   
> -	r = vm->update_funcs->prepare(&params, AMDGPU_FENCE_OWNER_VM, NULL);
> +	r = vm->update_funcs->prepare(&params, NULL, AMDGPU_SYNC_EXPLICIT);
>   	if (r)
>   		return r;
>   
> @@ -1524,7 +1524,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
>    * @adev: amdgpu_device pointer
>    * @vm: requested vm
>    * @direct: direct submission in a page fault
> - * @exclusive: fence we need to sync to
> + * @resv: fences we need to sync to
>    * @start: start of mapped range
>    * @last: last mapped entry
>    * @flags: flags for the entries
> @@ -1539,14 +1539,14 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
>    */
>   static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
>   				       struct amdgpu_vm *vm, bool direct,
> -				       struct dma_fence *exclusive,
> +				       struct dma_resv *resv,
>   				       uint64_t start, uint64_t last,
>   				       uint64_t flags, uint64_t addr,
>   				       dma_addr_t *pages_addr,
>   				       struct dma_fence **fence)
>   {
>   	struct amdgpu_vm_update_params params;
> -	void *owner = AMDGPU_FENCE_OWNER_VM;
> +	enum amdgpu_sync_mode sync_mode;
>   	int r;
>   
>   	memset(&params, 0, sizeof(params));
> @@ -1557,7 +1557,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
>   
>   	/* sync to everything except eviction fences on unmapping */

I think this comment needs to be updated. Something like "Implicitly 
sync to command submissions in the same VM before unmapping. Sync to 
moving fences before mapping."


>   	if (!(flags & AMDGPU_PTE_VALID))
> -		owner = AMDGPU_FENCE_OWNER_KFD;
> +		sync_mode = AMDGPU_SYNC_EQ_OWNER;
> +	else
> +		sync_mode = AMDGPU_SYNC_EXPLICIT;
>   
>   	mutex_lock(&vm->eviction_lock);
>   	if (vm->evicting) {
> @@ -1565,7 +1567,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
>   		goto error_unlock;
>   	}
>   
> -	r = vm->update_funcs->prepare(&params, owner, exclusive);
> +	r = vm->update_funcs->prepare(&params, resv, sync_mode);
>   	if (r)
>   		goto error_unlock;
>   
> @@ -1584,7 +1586,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
>    * amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks
>    *
>    * @adev: amdgpu_device pointer
> - * @exclusive: fence we need to sync to
> + * @resv: fences we need to sync to
>    * @pages_addr: DMA addresses to use for mapping
>    * @vm: requested vm
>    * @mapping: mapped range and flags to use for the update
> @@ -1600,7 +1602,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
>    * 0 for success, -EINVAL for failure.
>    */
>   static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
> -				      struct dma_fence *exclusive,
> +				      struct dma_resv *resv,
>   				      dma_addr_t *pages_addr,
>   				      struct amdgpu_vm *vm,
>   				      struct amdgpu_bo_va_mapping *mapping,
> @@ -1676,7 +1678,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
>   		}
>   
>   		last = min((uint64_t)mapping->last, start + max_entries - 1);
> -		r = amdgpu_vm_bo_update_mapping(adev, vm, false, exclusive,
> +		r = amdgpu_vm_bo_update_mapping(adev, vm, false, resv,
>   						start, last, flags, addr,
>   						dma_addr, fence);
>   		if (r)
> @@ -1715,7 +1717,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
>   	dma_addr_t *pages_addr = NULL;
>   	struct ttm_mem_reg *mem;
>   	struct drm_mm_node *nodes;
> -	struct dma_fence *exclusive, **last_update;
> +	struct dma_fence **last_update;
> +	struct dma_resv *resv;
>   	uint64_t flags;
>   	struct amdgpu_device *bo_adev = adev;
>   	int r;
> @@ -1723,7 +1726,6 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
>   	if (clear || !bo) {
>   		mem = NULL;
>   		nodes = NULL;
> -		exclusive = NULL;
>   	} else {
>   		struct ttm_dma_tt *ttm;
>   
> @@ -1733,7 +1735,6 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
>   			ttm = container_of(bo->tbo.ttm, struct ttm_dma_tt, ttm);
>   			pages_addr = ttm->dma_address;
>   		}
> -		exclusive = bo->tbo.moving;
>   	}
>   
>   	if (bo) {
> @@ -1743,11 +1744,14 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
>   			flags |= AMDGPU_PTE_TMZ;
>   
>   		bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
> +		resv = bo->tbo.base.resv;
>   	} else {
>   		flags = 0x0;
> +		resv = NULL;
>   	}
>   
> -	if (clear || (bo && bo->tbo.base.resv == vm->root.base.bo->tbo.base.resv))
> +	if (clear || (bo && bo->tbo.base.resv ==
> +		      vm->root.base.bo->tbo.base.resv))
>   		last_update = &vm->last_update;
>   	else
>   		last_update = &bo_va->last_pt_update;
> @@ -1761,7 +1765,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
>   	}
>   
>   	list_for_each_entry(mapping, &bo_va->invalids, list) {
> -		r = amdgpu_vm_bo_split_mapping(adev, exclusive, pages_addr, vm,
> +		r = amdgpu_vm_bo_split_mapping(adev, resv, pages_addr, vm,
>   					       mapping, flags, bo_adev, nodes,
>   					       last_update);
>   		if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index d5613d184e99..8fb09648bc97 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -229,8 +229,8 @@ struct amdgpu_vm_update_params {
>   
>   struct amdgpu_vm_update_funcs {
>   	int (*map_table)(struct amdgpu_bo *bo);
> -	int (*prepare)(struct amdgpu_vm_update_params *p, void * owner,
> -		       struct dma_fence *exclusive);
> +	int (*prepare)(struct amdgpu_vm_update_params *p, struct dma_resv *resv,
> +		       enum amdgpu_sync_mode sync_mode);
>   	int (*update)(struct amdgpu_vm_update_params *p,
>   		      struct amdgpu_bo *bo, uint64_t pe, uint64_t addr,
>   		      unsigned count, uint32_t incr, uint64_t flags);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
> index 68b013be3837..0be72660db4c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
> @@ -44,26 +44,21 @@ static int amdgpu_vm_cpu_map_table(struct amdgpu_bo *table)
>    * Returns:
>    * Negativ errno, 0 for success.
>    */
> -static int amdgpu_vm_cpu_prepare(struct amdgpu_vm_update_params *p, void *owner,
> -				 struct dma_fence *exclusive)
> +static int amdgpu_vm_cpu_prepare(struct amdgpu_vm_update_params *p,
> +				 struct dma_resv *resv,
> +				 enum amdgpu_sync_mode sync_mode)
>   {
> +	struct amdgpu_sync sync;
>   	int r;
>   
> -	/* Wait for any BO move to be completed */
> -	if (exclusive) {
> -		r = dma_fence_wait(exclusive, true);
> -		if (unlikely(r))
> -			return r;
> -	}
> -
> -	/* Don't wait for submissions during page fault */
> -	if (p->direct)
> +	if (!resv)
>   		return 0;
>   
> -	/* Wait for PT BOs to be idle. PTs share the same resv. object
> -	 * as the root PD BO
> -	 */
> -	return amdgpu_bo_sync_wait(p->vm->root.base.bo, owner, true);
> +	amdgpu_sync_create(&sync);
> +	amdgpu_sync_resv(p->adev, &sync, resv, sync_mode, p->vm);
> +	r = amdgpu_sync_wait(&sync, true);
> +	amdgpu_sync_free(&sync);

This looks like it's pretty much duplicating amdgpu_bo_sync_wait. In 
fact, when I first wrote that function it was meant as 
amdgpu_sync_wait_resv (and the comment above that function still 
incorrectly has that name).

Regards,
   Felix


> +	return r;
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
> index 3b61317c0f08..e7a383134521 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
> @@ -58,9 +58,9 @@ static int amdgpu_vm_sdma_map_table(struct amdgpu_bo *table)
>    * Negativ errno, 0 for success.
>    */
>   static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
> -				  void *owner, struct dma_fence *exclusive)
> +				  struct dma_resv *resv,
> +				  enum amdgpu_sync_mode sync_mode)
>   {
> -	struct amdgpu_bo *root = p->vm->root.base.bo;
>   	unsigned int ndw = AMDGPU_VM_SDMA_MIN_NUM_DW;
>   	int r;
>   
> @@ -70,17 +70,10 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
>   
>   	p->num_dw_left = ndw;
>   
> -	/* Wait for moves to be completed */
> -	r = amdgpu_sync_fence(&p->job->sync, exclusive, false);
> -	if (r)
> -		return r;
> -
> -	/* Don't wait for any submissions during page fault handling */
> -	if (p->direct)
> +	if (!resv)
>   		return 0;
>   
> -	return amdgpu_sync_resv(p->adev, &p->job->sync, root->tbo.base.resv,
> -				AMDGPU_SYNC_NE_OWNER, owner);
> +	return amdgpu_sync_resv(p->adev, &p->job->sync, resv, sync_mode, p->vm);
>   }
>   
>   /**
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 08/12] drm/amdgpu: rework synchronization of VM updates
  2020-01-06 21:38   ` Felix Kuehling
@ 2020-01-07 12:47     ` Christian König
  0 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-07 12:47 UTC (permalink / raw)
  To: Felix Kuehling, Alex.Sierra, Philip.Yang, amd-gfx

Am 06.01.20 um 22:38 schrieb Felix Kuehling:
> On 2020-01-06 10:03 a.m., Christian König wrote:
>> [SNIP]
>> @@ -1557,7 +1557,9 @@ static int amdgpu_vm_bo_update_mapping(struct 
>> amdgpu_device *adev,
>>         /* sync to everything except eviction fences on unmapping */
>
> I think this comment needs to be updated. Something like "Implicitly 
> sync to command submissions in the same VM before unmapping. Sync to 
> moving fences before mapping."

Good point, just updated this.

>
>
>> [SNIP]
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
>> index 68b013be3837..0be72660db4c 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_cpu.c
>> @@ -44,26 +44,21 @@ static int amdgpu_vm_cpu_map_table(struct 
>> amdgpu_bo *table)
>>    * Returns:
>>    * Negativ errno, 0 for success.
>>    */
>> -static int amdgpu_vm_cpu_prepare(struct amdgpu_vm_update_params *p, 
>> void *owner,
>> -                 struct dma_fence *exclusive)
>> +static int amdgpu_vm_cpu_prepare(struct amdgpu_vm_update_params *p,
>> +                 struct dma_resv *resv,
>> +                 enum amdgpu_sync_mode sync_mode)
>>   {
>> +    struct amdgpu_sync sync;
>>       int r;
>>   -    /* Wait for any BO move to be completed */
>> -    if (exclusive) {
>> -        r = dma_fence_wait(exclusive, true);
>> -        if (unlikely(r))
>> -            return r;
>> -    }
>> -
>> -    /* Don't wait for submissions during page fault */
>> -    if (p->direct)
>> +    if (!resv)
>>           return 0;
>>   -    /* Wait for PT BOs to be idle. PTs share the same resv. object
>> -     * as the root PD BO
>> -     */
>> -    return amdgpu_bo_sync_wait(p->vm->root.base.bo, owner, true);
>> +    amdgpu_sync_create(&sync);
>> +    amdgpu_sync_resv(p->adev, &sync, resv, sync_mode, p->vm);
>> +    r = amdgpu_sync_wait(&sync, true);
>> +    amdgpu_sync_free(&sync);
>
> This looks like it's pretty much duplicating amdgpu_bo_sync_wait. In 
> fact, when I first wrote that function it was meant as 
> amdgpu_sync_wait_resv (and the comment above that function still 
> incorrectly has that name).

Question is where is the best place to put this? It doesn't really fit 
into amdgpu_sync.c because it uses the syncobject and doesn't implements it.

But if we give the reservation object as parameter amdgpu_object.c 
doesn't fits either as well.

Regards,
Christian.

>
> Regards,
>   Felix
>
>
>> +    return r;
>>   }
>>     /**
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
>> index 3b61317c0f08..e7a383134521 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
>> @@ -58,9 +58,9 @@ static int amdgpu_vm_sdma_map_table(struct 
>> amdgpu_bo *table)
>>    * Negativ errno, 0 for success.
>>    */
>>   static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
>> -                  void *owner, struct dma_fence *exclusive)
>> +                  struct dma_resv *resv,
>> +                  enum amdgpu_sync_mode sync_mode)
>>   {
>> -    struct amdgpu_bo *root = p->vm->root.base.bo;
>>       unsigned int ndw = AMDGPU_VM_SDMA_MIN_NUM_DW;
>>       int r;
>>   @@ -70,17 +70,10 @@ static int amdgpu_vm_sdma_prepare(struct 
>> amdgpu_vm_update_params *p,
>>         p->num_dw_left = ndw;
>>   -    /* Wait for moves to be completed */
>> -    r = amdgpu_sync_fence(&p->job->sync, exclusive, false);
>> -    if (r)
>> -        return r;
>> -
>> -    /* Don't wait for any submissions during page fault handling */
>> -    if (p->direct)
>> +    if (!resv)
>>           return 0;
>>   -    return amdgpu_sync_resv(p->adev, &p->job->sync, 
>> root->tbo.base.resv,
>> -                AMDGPU_SYNC_NE_OWNER, owner);
>> +    return amdgpu_sync_resv(p->adev, &p->job->sync, resv, sync_mode, 
>> p->vm);
>>   }
>>     /**

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 10/12] drm/amdgpu: immedially invalidate PTEs
  2020-01-06 21:04   ` Felix Kuehling
@ 2020-01-07 12:48     ` Christian König
  0 siblings, 0 replies; 17+ messages in thread
From: Christian König @ 2020-01-07 12:48 UTC (permalink / raw)
  To: Felix Kuehling, Alex.Sierra, Philip.Yang, amd-gfx

Am 06.01.20 um 22:04 schrieb Felix Kuehling:
> On 2020-01-06 10:03 a.m., Christian König wrote:
>> When a BO is evicted immedially invalidate the mapped PTEs.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 17 ++++++++++++++++-
>>   1 file changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> index a03cfbe670c4..6844ba7467a6 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>> @@ -2569,6 +2569,7 @@ void amdgpu_vm_bo_invalidate(struct 
>> amdgpu_device *adev,
>>                    struct amdgpu_bo *bo, bool evicted)
>>   {
>>       struct amdgpu_vm_bo_base *bo_base;
>> +    int r;
>>         /* shadow bo doesn't have bo base, its validation needs its 
>> parent */
>>       if (bo->parent && bo->parent->shadow == bo)
>> @@ -2576,8 +2577,22 @@ void amdgpu_vm_bo_invalidate(struct 
>> amdgpu_device *adev,
>>         for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) {
>>           struct amdgpu_vm *vm = bo_base->vm;
>> +        struct dma_resv *resv = vm->root.base.bo->tbo.base.resv;
>> +
>> +        if (bo->tbo.type != ttm_bo_type_kernel) {
>> +            struct amdgpu_bo_va *bo_va;
>> +
>> +            bo_va = container_of(bo_base, struct amdgpu_bo_va,
>> +                         base);
>> +            r = amdgpu_vm_bo_update(adev, bo_va,
>> +                        bo->tbo.base.resv != resv);
>
> Will this update PTEs for per-VM BOs without validating them first?

Yes and that's intentional. Essentially this should allows moving per-VM 
BOs around when they aren't fenced.

>> +            if (!r) {
>> +                amdgpu_vm_bo_idle(bo_base);
>
> Is this the right state? The description of amdgpu_vm_bo_idle says 
> that this is for "PDs/PTs and per VM BOs". For regular BOs, I think 
> this should call amdgpu_vm_bo_done.

Good point, that's indeed not correct for per-VM BOs. Looks like I need 
to rework the whole state logic.

Thanks,
Christian.

>
>
>> +                continue;
>
> This skips a bunch of state machine logic below. Maybe some of that 
> could be cleaned up.
>
>
>> +            }
>> +        }
>>   -        if (evicted && bo->tbo.base.resv == 
>> vm->root.base.bo->tbo.base.resv) {
>> +        if (evicted && bo->tbo.base.resv == resv) {
>>               amdgpu_vm_bo_evicted(bo_base);
>
> It will never get here for per-VM BOs now (except if bo_update 
> failed). Not sure if that's a problem.
>
>
>>               continue;
>>           }
>>
>>                  if (bo_base->moved)
>>                          continue;
>>                  bo_base->moved = true;
>
> Maybe the whole PT invalidation should be after this to avoid multiple 
> invalidations off the same BO?
>
>
>>
>>                  if (bo->tbo.type == ttm_bo_type_kernel)
>>                          amdgpu_vm_bo_relocated(bo_base);
>>                  else if (bo->tbo.resv == vm->root.base.bo->tbo.resv)
>>                          amdgpu_vm_bo_moved(bo_base);
>>                  else
>>                          amdgpu_vm_bo_invalidated(bo_base);
>
> I believe the last two cases are unreachable now (except if bo_update 
> failed).
>
> Regards,
>   Felix
>
>

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-01-07 12:49 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-06 15:03 VM changes for invalidating PTEs without holding the reservation lock Christian König
2020-01-06 15:03 ` [PATCH 01/12] drm/amdgpu: explicitely sync to VM updates v2 Christian König
2020-01-06 15:03 ` [PATCH 02/12] drm/amdgpu: stop adding VM updates fences to the resv obj Christian König
2020-01-06 15:03 ` [PATCH 03/12] drm/amdgpu: add VM eviction lock v3 Christian König
2020-01-06 15:03 ` [PATCH 04/12] drm/amdgpu: drop amdgpu_job.owner Christian König
2020-01-06 15:03 ` [PATCH 05/12] drm/amdgpu: explicitly sync VM update to PDs/PTs Christian König
2020-01-06 15:03 ` [PATCH 06/12] drm/amdgpu: use the VM as job owner Christian König
2020-01-06 15:03 ` [PATCH 07/12] drm/amdgpu: rework job synchronization Christian König
2020-01-06 15:03 ` [PATCH 08/12] drm/amdgpu: rework synchronization of VM updates Christian König
2020-01-06 21:38   ` Felix Kuehling
2020-01-07 12:47     ` Christian König
2020-01-06 15:03 ` [PATCH 09/12] drm/amdgpu: stop using amdgpu_bo_gpu_offset in the VM backend Christian König
2020-01-06 15:03 ` [PATCH 10/12] drm/amdgpu: immedially invalidate PTEs Christian König
2020-01-06 21:04   ` Felix Kuehling
2020-01-07 12:48     ` Christian König
2020-01-06 15:03 ` [PATCH 11/12] drm/amdgpu: drop unnecessary restriction for huge root PDEs Christian König
2020-01-06 15:03 ` [PATCH 12/12] drm/amdgpu: make sure to never allocate PDs/PTs for invalidations Christian König

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.