On 2016年08月11日 16:39, Christian König wrote:
Am 05.08.2016 um 11:38 schrieb Chunming Zhou:
Change-Id: I46783043eecbe9fc9c2ce9230be1085aca3731bd
Signed-off-by: Chunming Zhou <[email protected]>
---
  drivers/gpu/drm/amd/amdgpu/amdgpu.h    |  4 +++
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 48 ++++++++++++++++++++++++++++++++++
  2 files changed, 52 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 53b7039..9cb6fda 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -921,6 +921,8 @@ struct amdgpu_vm {
        /* client id */
      u64                     client_id;
+
+    struct fence            *shadow_sync_fence;
  };
    struct amdgpu_vm_id {
@@ -1011,6 +1013,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
                 uint64_t addr);
  void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
                struct amdgpu_bo_va *bo_va);
+int amdgpu_vm_recover_page_table_from_shadow(struct amdgpu_device *adev,
+                         struct amdgpu_vm *vm);
    /*
   * context related structures
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 017274c..e6576c2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -702,6 +702,52 @@ error_free:
      return r;
  }
+int amdgpu_vm_recover_page_table_from_shadow(struct amdgpu_device *adev,
+                         struct amdgpu_vm *vm)
+{
+    struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+    struct fence *fence;
+    uint64_t pt_idx;
+    int r;
+
+    if (!vm->page_directory->shadow)
+        return 0;
+
+    r = amdgpu_bo_reserve(vm->page_directory, false);
+    if (r)
+        return r;

I think that the caller should reserve the BOs here.

Especially during CS we only want to reserve everything once.

This function is called in gpu reset, not in cs ioctl.


BTW: How do we handle swapping the PD/PTs in and out?

E.g. we don't need to copy them from VRAM to GART any more.

Yes, we only need to copy from GART to VRAM when gpu reset.

Regards,
David Zhou

Regards,
Christian.

+ vm->page_directory->shadow_flag = AMDGPU_SHADOW_FLAG_SYNC_TO_PARENT;
+    r = amdgpu_bo_sync_between_bo_and_shadow(adev, ring,
+                         vm->page_directory,
+                         NULL, &fence);
+    if (r) {
+        DRM_ERROR("recover page table failed!\n");
+        goto err;
+    }
+    fence_put(vm->shadow_sync_fence);
+    vm->shadow_sync_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;
+
+        if (!bo)
+            continue;
+        bo->shadow_flag = AMDGPU_SHADOW_FLAG_SYNC_TO_PARENT;
+        r = amdgpu_bo_sync_between_bo_and_shadow(adev, ring, bo,
+                             NULL, &fence);
+        if (r) {
+            DRM_ERROR("recover page table failed!\n");
+            goto err;
+        }
+        fence_put(vm->shadow_sync_fence);
+        vm->shadow_sync_fence = fence_get(fence);
+        fence_put(fence);
+    }
+
+err:
+    amdgpu_bo_unreserve(vm->page_directory);
+    return r;
+}
  /**
   * amdgpu_vm_frag_ptes - add fragment information to PTEs
   *
@@ -1556,6 +1602,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
      if (r)
          goto error_free_page_directory;
      vm->last_eviction_counter = atomic64_read(&adev->num_evictions);
+    vm->shadow_sync_fence = NULL;
        return 0;
@@ -1604,6 +1651,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->shadow_sync_fence);
  }
    /**



_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to