[PATCH 09/18] drm/amdgpu: update pt shadow
Chunming Zhou
David1.Zhou at amd.com
Fri Aug 12 06:38:58 UTC 2016
Change-Id: I33b31cbe794c1c83b8e02e3069159c8204ac03e3
Signed-off-by: Chunming Zhou <David1.Zhou at amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 108 +++++++++++++++++++++------------
1 file changed, 69 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index bd69cf83..73272d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -871,7 +871,8 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
*vm_update_params,
struct amdgpu_vm *vm,
uint64_t start, uint64_t end,
- uint64_t dst, uint32_t flags)
+ uint64_t dst, uint32_t flags,
+ bool shadow)
{
const uint64_t mask = AMDGPU_VM_PTE_COUNT - 1;
@@ -885,7 +886,8 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
/* initialize the variables */
addr = start;
pt_idx = addr >> amdgpu_vm_block_size;
- pt = vm->page_tables[pt_idx].entry.robj;
+ pt = shadow ? vm->page_tables[pt_idx].entry.robj->shadow :
+ vm->page_tables[pt_idx].entry.robj;
if ((addr & ~mask) == (end & ~mask))
nptes = end - addr;
@@ -904,7 +906,8 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
/* walk over the address space and update the page tables */
while (addr < end) {
pt_idx = addr >> amdgpu_vm_block_size;
- pt = vm->page_tables[pt_idx].entry.robj;
+ pt = shadow ? vm->page_tables[pt_idx].entry.robj->shadow :
+ vm->page_tables[pt_idx].entry.robj;
if ((addr & ~mask) == (end & ~mask))
nptes = end - addr;
@@ -939,31 +942,15 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev,
cur_pe_end, cur_dst, flags);
}
-/**
- * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table
- *
- * @adev: amdgpu_device pointer
- * @exclusive: fence we need to sync to
- * @src: address where to copy page table entries from
- * @pages_addr: DMA addresses to use for mapping
- * @vm: requested vm
- * @start: start of mapped range
- * @last: last mapped entry
- * @flags: flags for the entries
- * @addr: addr to set the area to
- * @fence: optional resulting fence
- *
- * Fill in the page table entries between @start and @last.
- * Returns 0 for success, -EINVAL for failure.
- */
-static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
- struct fence *exclusive,
- uint64_t src,
- dma_addr_t *pages_addr,
- struct amdgpu_vm *vm,
- uint64_t start, uint64_t last,
- uint32_t flags, uint64_t addr,
- struct fence **fence)
+static int amdgpu_vm_bo_update_mapping_or_shadow(struct amdgpu_device *adev,
+ struct fence *exclusive,
+ uint64_t src,
+ dma_addr_t *pages_addr,
+ struct amdgpu_vm *vm,
+ uint64_t start, uint64_t last,
+ uint32_t flags, uint64_t addr,
+ struct fence **fence,
+ bool shadow)
{
struct amdgpu_ring *ring;
void *owner = AMDGPU_FENCE_OWNER_VM;
@@ -1018,29 +1005,30 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
vm_update_params.ib = &job->ibs[0];
- r = amdgpu_sync_fence(adev, &job->sync, exclusive);
- if (r)
- goto error_free;
-
- r = amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv,
- owner);
- if (r)
- goto error_free;
+ if (!shadow) {
+ r = amdgpu_sync_fence(adev, &job->sync, exclusive);
+ if (r)
+ goto error_free;
+ r = amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv,
+ owner);
+ if (r)
+ goto error_free;
+ }
r = reservation_object_reserve_shared(vm->page_directory->tbo.resv);
if (r)
goto error_free;
amdgpu_vm_update_ptes(adev, &vm_update_params, vm, start,
- last + 1, addr, flags);
+ last + 1, addr, flags, shadow);
amdgpu_ring_pad_ib(ring, vm_update_params.ib);
WARN_ON(vm_update_params.ib->length_dw > ndw);
- r = amdgpu_job_submit(job, ring, &vm->entity,
+ r = amdgpu_job_submit(job, ring,
+ shadow ? &vm->shadow_entity : &vm->entity,
AMDGPU_FENCE_OWNER_VM, &f);
if (r)
goto error_free;
-
amdgpu_bo_fence(vm->page_directory, f, true);
if (fence) {
fence_put(*fence);
@@ -1055,6 +1043,48 @@ error_free:
}
/**
+ * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table
+ *
+ * @adev: amdgpu_device pointer
+ * @exclusive: fence we need to sync to
+ * @src: address where to copy page table entries from
+ * @pages_addr: DMA addresses to use for mapping
+ * @vm: requested vm
+ * @start: start of mapped range
+ * @last: last mapped entry
+ * @flags: flags for the entries
+ * @addr: addr to set the area to
+ * @fence: optional resulting fence
+ *
+ * Fill in the page table entries between @start and @last.
+ * Returns 0 for success, -EINVAL for failure.
+ */
+static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
+ struct fence *exclusive,
+ uint64_t src,
+ dma_addr_t *pages_addr,
+ struct amdgpu_vm *vm,
+ uint64_t start, uint64_t last,
+ uint32_t flags, uint64_t addr,
+ struct fence **fence)
+{
+ int r;
+
+ r = amdgpu_vm_bo_update_mapping_or_shadow(adev, exclusive, src,
+ pages_addr, vm,
+ start, last,
+ flags, addr,
+ NULL, true);
+ if (r)
+ return r;
+ return amdgpu_vm_bo_update_mapping_or_shadow(adev, exclusive, src,
+ pages_addr, vm,
+ start, last,
+ flags, addr,
+ fence, false);
+}
+
+/**
* amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks
*
* @adev: amdgpu_device pointer
--
1.9.1
More information about the amd-gfx
mailing list