[PATCH 12/13] drm/amdgpu: add vm recover pt fence

Chunming Zhou David1.Zhou at amd.com
Tue Aug 2 07:49:06 UTC 2016


Before every job runs, we must make sure which's vm is recoverred completely.

Change-Id: Ibe77a3c8f8206def280543fbb4195ad2ab9772e0
Signed-off-by: Chunming Zhou <David1.Zhou at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c |  5 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 24 ++++++++++++++++++------
 3 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index a2261ac..c0e4164 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -919,6 +919,8 @@ struct amdgpu_vm {
 
 	/* client id */
 	u64                     client_id;
+
+	struct fence            *recover_pt_fence;
 };
 
 struct amdgpu_vm_id {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 6674d40..8d87a9a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -152,6 +152,10 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job)
 		fence = amdgpu_sync_get_fence(&job->sync);
 	}
 
+	if (fence == NULL && vm && vm->recover_pt_fence &&
+	    !fence_is_signaled(vm->recover_pt_fence))
+		fence = fence_get(vm->recover_pt_fence);
+
 	return fence;
 }
 
@@ -170,6 +174,7 @@ static struct fence *amdgpu_job_run(struct amd_sched_job *sched_job)
 	BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL));
 
 	trace_amdgpu_sched_run_job(job);
+
 	r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs,
 			       job->sync.last_vm_update, job, &fence);
 	if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 1cb2e71..1305dc1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -703,11 +703,11 @@ error_free:
 static int amdgpu_vm_recover_bo_from_shadow(struct amdgpu_device *adev,
 					    struct amdgpu_bo *bo,
 					    struct amdgpu_bo *bo_shadow,
-					    struct reservation_object *resv)
+					    struct reservation_object *resv,
+					    struct fence **fence)
 
 {
 	struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
-	struct fence *fence;
 	int r;
 	uint64_t vram_addr, gtt_addr;
 
@@ -727,9 +727,9 @@ static int amdgpu_vm_recover_bo_from_shadow(struct amdgpu_device *adev,
 		goto err3;
 
 	r = amdgpu_copy_buffer(ring, gtt_addr, vram_addr,
-			       amdgpu_bo_size(bo), resv, &fence);
+			       amdgpu_bo_size(bo), resv, fence);
 	if (!r)
-		amdgpu_bo_fence(bo, fence, true);
+		amdgpu_bo_fence(bo, *fence, true);
 
 err3:
 	amdgpu_bo_unpin(bo_shadow);
@@ -743,6 +743,7 @@ err1:
 int amdgpu_vm_recover_page_table_from_shadow(struct amdgpu_device *adev,
 					     struct amdgpu_vm *vm)
 {
+	struct fence *fence;
 	uint64_t pt_idx;
 	int r;
 
@@ -753,11 +754,14 @@ int amdgpu_vm_recover_page_table_from_shadow(struct amdgpu_device *adev,
 
 	r = amdgpu_vm_recover_bo_from_shadow(adev, vm->page_directory,
 					     vm->page_directory->shadow,
-					     NULL);
+					     NULL, &fence);
 	if (r) {
 		DRM_ERROR("recover page table failed!\n");
 		goto err;
 	}
+	fence_put(vm->recover_pt_fence);
+	vm->recover_pt_fence = fence_get(fence);
+	fence_put(fence);
 
 	for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) {
 		struct amdgpu_bo *bo = vm->page_tables[pt_idx].entry.robj;
@@ -766,15 +770,21 @@ int amdgpu_vm_recover_page_table_from_shadow(struct amdgpu_device *adev,
 		if (!bo || !bo_shadow)
 			continue;
 		r = amdgpu_vm_recover_bo_from_shadow(adev, bo, bo_shadow,
-						     NULL);
+						     NULL, &fence);
 		if (r) {
 			DRM_ERROR("recover page table failed!\n");
 			goto err;
 		}
+		fence_put(vm->recover_pt_fence);
+		vm->recover_pt_fence = fence_get(fence);
+		fence_put(fence);
 	}
 
 err:
 	amdgpu_bo_unreserve(vm->page_directory);
+	if (vm->recover_pt_fence)
+		r = fence_wait(vm->recover_pt_fence, false);
+
 	return r;
 }
 /**
@@ -1629,6 +1639,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 	INIT_LIST_HEAD(&vm->cleared);
 	INIT_LIST_HEAD(&vm->freed);
 	INIT_LIST_HEAD(&vm->list);
+	vm->recover_pt_fence = NULL;
 
 	pd_size = amdgpu_vm_directory_size(adev);
 	pd_entries = amdgpu_vm_num_pdes(adev);
@@ -1730,6 +1741,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
 
 	amdgpu_bo_unref(&vm->page_directory);
 	fence_put(vm->page_directory_fence);
+	fence_put(vm->recover_pt_fence);
 }
 
 /**
-- 
1.9.1



More information about the amd-gfx mailing list