Commit 67003a15 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: generalize page table level

No functional change, but the base for multi level page tables.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8437a097
...@@ -872,7 +872,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, ...@@ -872,7 +872,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
} }
if (p->job->vm) { if (p->job->vm) {
p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->root.bo);
r = amdgpu_bo_vm_update_pte(p); r = amdgpu_bo_vm_update_pte(p);
if (r) if (r)
......
...@@ -115,9 +115,9 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, ...@@ -115,9 +115,9 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
struct list_head *validated, struct list_head *validated,
struct amdgpu_bo_list_entry *entry) struct amdgpu_bo_list_entry *entry)
{ {
entry->robj = vm->page_directory; entry->robj = vm->root.bo;
entry->priority = 0; entry->priority = 0;
entry->tv.bo = &vm->page_directory->tbo; entry->tv.bo = &entry->robj->tbo;
entry->tv.shared = true; entry->tv.shared = true;
entry->user_pages = NULL; entry->user_pages = NULL;
list_add(&entry->tv.head, validated); list_add(&entry->tv.head, validated);
...@@ -149,8 +149,8 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, ...@@ -149,8 +149,8 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
return 0; return 0;
/* add the vm page table to the list */ /* add the vm page table to the list */
for (i = 0; i <= vm->max_pde_used; ++i) { for (i = 0; i <= vm->root.last_entry_used; ++i) {
struct amdgpu_bo *bo = vm->page_tables[i].bo; struct amdgpu_bo *bo = vm->root.entries[i].bo;
if (!bo) if (!bo)
continue; continue;
...@@ -178,8 +178,8 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, ...@@ -178,8 +178,8 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
unsigned i; unsigned i;
spin_lock(&glob->lru_lock); spin_lock(&glob->lru_lock);
for (i = 0; i <= vm->max_pde_used; ++i) { for (i = 0; i <= vm->root.last_entry_used; ++i) {
struct amdgpu_bo *bo = vm->page_tables[i].bo; struct amdgpu_bo *bo = vm->root.entries[i].bo;
if (!bo) if (!bo)
continue; continue;
...@@ -227,15 +227,15 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, ...@@ -227,15 +227,15 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
BUG_ON(eaddr >= amdgpu_vm_num_pdes(adev)); BUG_ON(eaddr >= amdgpu_vm_num_pdes(adev));
if (eaddr > vm->max_pde_used) if (eaddr > vm->root.last_entry_used)
vm->max_pde_used = eaddr; vm->root.last_entry_used = eaddr;
/* walk over the address space and allocate the page tables */ /* walk over the address space and allocate the page tables */
for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) { for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) {
struct reservation_object *resv = vm->page_directory->tbo.resv; struct reservation_object *resv = vm->root.bo->tbo.resv;
struct amdgpu_bo *pt; struct amdgpu_bo *pt;
if (vm->page_tables[pt_idx].bo) if (vm->root.entries[pt_idx].bo)
continue; continue;
r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8, r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8,
...@@ -252,10 +252,10 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, ...@@ -252,10 +252,10 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
/* Keep a reference to the page table to avoid freeing /* Keep a reference to the page table to avoid freeing
* them up in the wrong order. * them up in the wrong order.
*/ */
pt->parent = amdgpu_bo_ref(vm->page_directory); pt->parent = amdgpu_bo_ref(vm->root.bo);
vm->page_tables[pt_idx].bo = pt; vm->root.entries[pt_idx].bo = pt;
vm->page_tables[pt_idx].addr = 0; vm->root.entries[pt_idx].addr = 0;
} }
return 0; return 0;
...@@ -672,15 +672,15 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -672,15 +672,15 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
int r; int r;
ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
shadow = vm->page_directory->shadow; shadow = vm->root.bo->shadow;
/* padding, etc. */ /* padding, etc. */
ndw = 64; ndw = 64;
/* assume the worst case */ /* assume the worst case */
ndw += vm->max_pde_used * 6; ndw += vm->root.last_entry_used * 6;
pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); pd_addr = amdgpu_bo_gpu_offset(vm->root.bo);
if (shadow) { if (shadow) {
r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem); r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem);
if (r) if (r)
...@@ -700,8 +700,8 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -700,8 +700,8 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
params.ib = &job->ibs[0]; params.ib = &job->ibs[0];
/* walk over the address space and update the page directory */ /* walk over the address space and update the page directory */
for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { for (pt_idx = 0; pt_idx <= vm->root.last_entry_used; ++pt_idx) {
struct amdgpu_bo *bo = vm->page_tables[pt_idx].bo; struct amdgpu_bo *bo = vm->root.entries[pt_idx].bo;
uint64_t pde, pt; uint64_t pde, pt;
if (bo == NULL) if (bo == NULL)
...@@ -717,10 +717,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -717,10 +717,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
} }
pt = amdgpu_bo_gpu_offset(bo); pt = amdgpu_bo_gpu_offset(bo);
if (vm->page_tables[pt_idx].addr == pt) if (vm->root.entries[pt_idx].addr == pt)
continue; continue;
vm->page_tables[pt_idx].addr = pt; vm->root.entries[pt_idx].addr = pt;
pde = pd_addr + pt_idx * 8; pde = pd_addr + pt_idx * 8;
if (((last_pde + 8 * count) != pde) || if (((last_pde + 8 * count) != pde) ||
...@@ -755,7 +755,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -755,7 +755,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
if (count) { if (count) {
uint64_t pt_addr = amdgpu_vm_adjust_mc_addr(adev, last_pt); uint64_t pt_addr = amdgpu_vm_adjust_mc_addr(adev, last_pt);
if (vm->page_directory->shadow) if (vm->root.bo->shadow)
amdgpu_vm_do_set_ptes(&params, last_shadow, pt_addr, amdgpu_vm_do_set_ptes(&params, last_shadow, pt_addr,
count, incr, AMDGPU_PTE_VALID); count, incr, AMDGPU_PTE_VALID);
...@@ -769,7 +769,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -769,7 +769,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
} }
amdgpu_ring_pad_ib(ring, params.ib); amdgpu_ring_pad_ib(ring, params.ib);
amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv, amdgpu_sync_resv(adev, &job->sync, vm->root.bo->tbo.resv,
AMDGPU_FENCE_OWNER_VM); AMDGPU_FENCE_OWNER_VM);
if (shadow) if (shadow)
amdgpu_sync_resv(adev, &job->sync, shadow->tbo.resv, amdgpu_sync_resv(adev, &job->sync, shadow->tbo.resv,
...@@ -781,7 +781,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ...@@ -781,7 +781,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
if (r) if (r)
goto error_free; goto error_free;
amdgpu_bo_fence(vm->page_directory, fence, true); amdgpu_bo_fence(vm->root.bo, fence, true);
dma_fence_put(vm->last_dir_update); dma_fence_put(vm->last_dir_update);
vm->last_dir_update = dma_fence_get(fence); vm->last_dir_update = dma_fence_get(fence);
dma_fence_put(fence); dma_fence_put(fence);
...@@ -821,7 +821,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, ...@@ -821,7 +821,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
/* initialize the variables */ /* initialize the variables */
addr = start; addr = start;
pt_idx = addr >> amdgpu_vm_block_size; pt_idx = addr >> amdgpu_vm_block_size;
pt = params->vm->page_tables[pt_idx].bo; pt = params->vm->root.entries[pt_idx].bo;
if (params->shadow) { if (params->shadow) {
if (!pt->shadow) if (!pt->shadow)
return; return;
...@@ -844,7 +844,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, ...@@ -844,7 +844,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
/* walk over the address space and update the page tables */ /* walk over the address space and update the page tables */
while (addr < end) { while (addr < end) {
pt_idx = addr >> amdgpu_vm_block_size; pt_idx = addr >> amdgpu_vm_block_size;
pt = params->vm->page_tables[pt_idx].bo; pt = params->vm->root.entries[pt_idx].bo;
if (params->shadow) { if (params->shadow) {
if (!pt->shadow) if (!pt->shadow)
return; return;
...@@ -1058,12 +1058,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ...@@ -1058,12 +1058,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
if (r) if (r)
goto error_free; goto error_free;
r = amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv, r = amdgpu_sync_resv(adev, &job->sync, vm->root.bo->tbo.resv,
owner); owner);
if (r) if (r)
goto error_free; goto error_free;
r = reservation_object_reserve_shared(vm->page_directory->tbo.resv); r = reservation_object_reserve_shared(vm->root.bo->tbo.resv);
if (r) if (r)
goto error_free; goto error_free;
...@@ -1079,7 +1079,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ...@@ -1079,7 +1079,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
if (r) if (r)
goto error_free; goto error_free;
amdgpu_bo_fence(vm->page_directory, f, true); amdgpu_bo_fence(vm->root.bo, f, true);
dma_fence_put(*fence); dma_fence_put(*fence);
*fence = f; *fence = f;
return 0; return 0;
...@@ -1372,7 +1372,7 @@ static void amdgpu_vm_free_mapping(struct amdgpu_device *adev, ...@@ -1372,7 +1372,7 @@ static void amdgpu_vm_free_mapping(struct amdgpu_device *adev,
*/ */
static void amdgpu_vm_prt_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) static void amdgpu_vm_prt_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
{ {
struct reservation_object *resv = vm->page_directory->tbo.resv; struct reservation_object *resv = vm->root.bo->tbo.resv;
struct dma_fence *excl, **shared; struct dma_fence *excl, **shared;
unsigned i, shared_count; unsigned i, shared_count;
int r; int r;
...@@ -1897,8 +1897,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) ...@@ -1897,8 +1897,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
pd_entries = amdgpu_vm_num_pdes(adev); pd_entries = amdgpu_vm_num_pdes(adev);
/* allocate page table array */ /* allocate page table array */
vm->page_tables = drm_calloc_large(pd_entries, sizeof(struct amdgpu_vm_pt)); vm->root.entries = drm_calloc_large(pd_entries, sizeof(struct amdgpu_vm_pt));
if (vm->page_tables == NULL) { if (vm->root.entries == NULL) {
DRM_ERROR("Cannot allocate memory for page table array\n"); DRM_ERROR("Cannot allocate memory for page table array\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -1922,29 +1922,29 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) ...@@ -1922,29 +1922,29 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
AMDGPU_GEM_CREATE_SHADOW | AMDGPU_GEM_CREATE_SHADOW |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS |
AMDGPU_GEM_CREATE_VRAM_CLEARED, AMDGPU_GEM_CREATE_VRAM_CLEARED,
NULL, NULL, &vm->page_directory); NULL, NULL, &vm->root.bo);
if (r) if (r)
goto error_free_sched_entity; goto error_free_sched_entity;
r = amdgpu_bo_reserve(vm->page_directory, false); r = amdgpu_bo_reserve(vm->root.bo, false);
if (r) if (r)
goto error_free_page_directory; goto error_free_root;
vm->last_eviction_counter = atomic64_read(&adev->num_evictions); vm->last_eviction_counter = atomic64_read(&adev->num_evictions);
amdgpu_bo_unreserve(vm->page_directory); amdgpu_bo_unreserve(vm->root.bo);
return 0; return 0;
error_free_page_directory: error_free_root:
amdgpu_bo_unref(&vm->page_directory->shadow); amdgpu_bo_unref(&vm->root.bo->shadow);
amdgpu_bo_unref(&vm->page_directory); amdgpu_bo_unref(&vm->root.bo);
vm->page_directory = NULL; vm->root.bo = NULL;
error_free_sched_entity: error_free_sched_entity:
amd_sched_entity_fini(&ring->sched, &vm->entity); amd_sched_entity_fini(&ring->sched, &vm->entity);
err: err:
drm_free_large(vm->page_tables); drm_free_large(vm->root.entries);
return r; return r;
} }
...@@ -1985,7 +1985,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) ...@@ -1985,7 +1985,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
} }
for (i = 0; i < amdgpu_vm_num_pdes(adev); i++) { for (i = 0; i < amdgpu_vm_num_pdes(adev); i++) {
struct amdgpu_bo *pt = vm->page_tables[i].bo; struct amdgpu_bo *pt = vm->root.entries[i].bo;
if (!pt) if (!pt)
continue; continue;
...@@ -1993,10 +1993,10 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) ...@@ -1993,10 +1993,10 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
amdgpu_bo_unref(&pt->shadow); amdgpu_bo_unref(&pt->shadow);
amdgpu_bo_unref(&pt); amdgpu_bo_unref(&pt);
} }
drm_free_large(vm->page_tables); drm_free_large(vm->root.entries);
amdgpu_bo_unref(&vm->page_directory->shadow); amdgpu_bo_unref(&vm->root.bo->shadow);
amdgpu_bo_unref(&vm->page_directory); amdgpu_bo_unref(&vm->root.bo);
dma_fence_put(vm->last_dir_update); dma_fence_put(vm->last_dir_update);
} }
......
...@@ -79,6 +79,10 @@ struct amdgpu_bo_list_entry; ...@@ -79,6 +79,10 @@ struct amdgpu_bo_list_entry;
struct amdgpu_vm_pt { struct amdgpu_vm_pt {
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
uint64_t addr; uint64_t addr;
/* array of page tables, one for each directory entry */
struct amdgpu_vm_pt *entries;
unsigned last_entry_used;
}; };
struct amdgpu_vm { struct amdgpu_vm {
...@@ -98,14 +102,10 @@ struct amdgpu_vm { ...@@ -98,14 +102,10 @@ struct amdgpu_vm {
struct list_head freed; struct list_head freed;
/* contains the page directory */ /* contains the page directory */
struct amdgpu_bo *page_directory; struct amdgpu_vm_pt root;
unsigned max_pde_used;
struct dma_fence *last_dir_update; struct dma_fence *last_dir_update;
uint64_t last_eviction_counter; uint64_t last_eviction_counter;
/* array of page tables, one for each page directory entry */
struct amdgpu_vm_pt *page_tables;
/* for id and flush management per ring */ /* for id and flush management per ring */
struct amdgpu_vm_id *ids[AMDGPU_MAX_RINGS]; struct amdgpu_vm_id *ids[AMDGPU_MAX_RINGS];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment