diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1787-drm-amdgpu-track-evicted-page-tables-v2.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1787-drm-amdgpu-track-evicted-page-tables-v2.patch | 639 |
1 files changed, 639 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1787-drm-amdgpu-track-evicted-page-tables-v2.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1787-drm-amdgpu-track-evicted-page-tables-v2.patch new file mode 100644 index 00000000..7dba2441 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1787-drm-amdgpu-track-evicted-page-tables-v2.patch @@ -0,0 +1,639 @@ +From e56fb93212e371ab3c2aa44b8ee6d7a967266753 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 3 Aug 2017 14:02:13 +0200 +Subject: [PATCH 1787/4131] drm/amdgpu: track evicted page tables v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Instead of validating all page tables when one was evicted, +track which one needs a validation. + +v2: simplify amdgpu_vm_ready as well + +Change-Id: I8cf9c6b18ce40a183b79c22912c31838b484bf10 +Signed-off-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1) +Reviewed-by: Chunming Zhou <david1.zhou@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 26 ++- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 7 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 227 ++++++++++------------- + 4 files changed, 118 insertions(+), 144 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +index 528ddb9..f5d61eb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -381,7 +381,7 @@ static int amdgpu_amdkfd_validate(void *param, struct amdgpu_bo *bo) + */ + static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm) + { +- struct amdgpu_bo *pd = vm->root.bo; ++ struct amdgpu_bo *pd = vm->root.base.bo; + struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev); + struct amdgpu_vm_parser param; + int ret; +@@ -402,8 +402,6 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm) + return ret; + } + +- vm->last_eviction_counter = atomic64_read(&adev->num_evictions); +- + ret = amdgpu_vm_update_directories(adev, vm); + if (ret != 0) + return ret; +@@ -431,7 +429,7 @@ static int add_bo_to_vm(struct amdgpu_device *adev, struct kgd_mem *mem, + struct kfd_bo_va_list *bo_va_entry; + struct amdkfd_vm *kvm = container_of(avm, + struct amdkfd_vm, base); +- struct amdgpu_bo *pd = avm->root.bo; ++ struct amdgpu_bo *pd = avm->root.base.bo; + struct amdgpu_bo *bo = mem->bo; + uint64_t va = mem->va; + struct list_head *list_bo_va = &mem->bo_va_list; +@@ -952,7 +950,7 @@ static int unmap_bo_from_gpuvm(struct amdgpu_device *adev, + struct amdgpu_bo_va *bo_va = entry->bo_va; + struct amdgpu_vm *vm = bo_va->base.vm; + struct amdkfd_vm *kvm = container_of(vm, struct amdkfd_vm, base); +- struct amdgpu_bo *pd = vm->root.bo; ++ struct amdgpu_bo *pd = vm->root.base.bo; + + /* Remove eviction fence from PD (and thereby from PTs too as they + * share the resv. object. Otherwise during PT update job (see +@@ -1384,16 +1382,16 @@ static u64 get_vm_pd_gpu_offset(void *vm) + { + struct amdgpu_vm *avm = (struct amdgpu_vm *) vm; + struct amdgpu_device *adev = +- amdgpu_ttm_adev(avm->root.bo->tbo.bdev); ++ amdgpu_ttm_adev(avm->root.base.bo->tbo.bdev); + u64 offset; + + BUG_ON(avm == NULL); + +- amdgpu_bo_reserve(avm->root.bo, false); ++ amdgpu_bo_reserve(avm->root.base.bo, false); + +- offset = amdgpu_bo_gpu_offset(avm->root.bo); ++ offset = amdgpu_bo_gpu_offset(avm->root.base.bo); + +- amdgpu_bo_unreserve(avm->root.bo); ++ amdgpu_bo_unreserve(avm->root.base.bo); + + /* On some ASICs the FB doesn't start at 0. Adjust FB offset + * to an actual MC address. +@@ -1493,7 +1491,7 @@ void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm) + + pr_debug("Destroying process vm %p\n", vm); + /* Release eviction fence from PD */ +- pd = avm->root.bo; ++ pd = avm->root.base.bo; + amdgpu_bo_reserve(pd, false); + amdgpu_bo_fence(pd, NULL, false); + amdgpu_bo_unreserve(pd); +@@ -2114,7 +2112,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info) + */ + list_for_each_entry(peer_vm, &process_info->vm_list_head, + vm_list_node) +- amdgpu_amdkfd_remove_eviction_fence(peer_vm->base.root.bo, ++ amdgpu_amdkfd_remove_eviction_fence(peer_vm->base.root.base.bo, + process_info->eviction_fence, + NULL, NULL); + +@@ -2181,7 +2179,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info) + unreserve_out: + list_for_each_entry(peer_vm, &process_info->vm_list_head, + vm_list_node) +- amdgpu_bo_fence(peer_vm->base.root.bo, ++ amdgpu_bo_fence(peer_vm->base.root.base.bo, + &process_info->eviction_fence->base, true); + ttm_eu_backoff_reservation(&ticket, &resv_list); + amdgpu_sync_wait(&sync, false); +@@ -2352,7 +2350,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info) + /* FIXME: I think this isn't needed */ + list_for_each_entry(peer_vm, &process_info->vm_list_head, + vm_list_node) { +- struct amdgpu_bo *bo = peer_vm->base.root.bo; ++ struct amdgpu_bo *bo = peer_vm->base.root.base.bo; + + ttm_bo_wait(&bo->tbo, false, false); + } +@@ -2398,7 +2396,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info) + /* Attach eviction fence to PD / PT BOs */ + list_for_each_entry(peer_vm, &process_info->vm_list_head, + vm_list_node) { +- struct amdgpu_bo *bo = peer_vm->base.root.bo; ++ struct amdgpu_bo *bo = peer_vm->base.root.base.bo; + + amdgpu_bo_fence(bo, &process_info->eviction_fence->base, true); + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index 87d6ff4..8072f2f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -669,9 +669,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, + + amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved, + p->bytes_moved_vis); +- fpriv->vm.last_eviction_counter = +- atomic64_read(&p->adev->num_evictions); +- + if (p->bo_list) { + struct amdgpu_bo *gds = p->bo_list->gds_obj; + struct amdgpu_bo *gws = p->bo_list->gws_obj; +@@ -878,7 +875,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p) + if (!bo) + continue; + +- amdgpu_vm_bo_invalidate(adev, bo); ++ amdgpu_vm_bo_invalidate(adev, bo, false); + } + } + +@@ -903,7 +900,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, + } + + if (p->job->vm) { +- p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->root.bo); ++ p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->root.base.bo); + + r = amdgpu_bo_vm_update_pte(p); + if (r) +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +index f503bcf..7aa7b6c 100755 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +@@ -972,7 +972,7 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, + return; + + abo = container_of(bo, struct amdgpu_bo, tbo); +- amdgpu_vm_bo_invalidate(adev, abo); ++ amdgpu_vm_bo_invalidate(adev, abo, evict); + + amdgpu_bo_kunmap(abo); + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index eee826d..7fdecc0 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -146,7 +146,7 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, + struct list_head *validated, + struct amdgpu_bo_list_entry *entry) + { +- entry->robj = vm->root.bo; ++ entry->robj = vm->root.base.bo; + entry->priority = 0; + entry->tv.bo = &entry->robj->tbo; + entry->tv.shared = true; +@@ -155,61 +155,6 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, + } + + /** +- * amdgpu_vm_validate_layer - validate a single page table level +- * +- * @parent: parent page table level +- * @validate: callback to do the validation +- * @param: parameter for the validation callback +- * +- * Validate the page table BOs on command submission if neccessary. +- */ +-static int amdgpu_vm_validate_level(struct amdgpu_vm_pt *parent, +- int (*validate)(void *, struct amdgpu_bo *), +- void *param, bool use_cpu_for_update, +- struct ttm_bo_global *glob) +-{ +- unsigned i; +- int r; +- +- if (use_cpu_for_update) { +- r = amdgpu_bo_kmap(parent->bo, NULL); +- if (r) +- return r; +- } +- +- if (!parent->entries) +- return 0; +- +- for (i = 0; i <= parent->last_entry_used; ++i) { +- struct amdgpu_vm_pt *entry = &parent->entries[i]; +- +- if (!entry->bo) +- continue; +- +- r = validate(param, entry->bo); +- if (r) +- return r; +- +- spin_lock(&glob->lru_lock); +- ttm_bo_move_to_lru_tail(&entry->bo->tbo); +- if (entry->bo->shadow) +- ttm_bo_move_to_lru_tail(&entry->bo->shadow->tbo); +- spin_unlock(&glob->lru_lock); +- +- /* +- * Recurse into the sub directory. This is harmless because we +- * have only a maximum of 5 layers. +- */ +- r = amdgpu_vm_validate_level(entry, validate, param, +- use_cpu_for_update, glob); +- if (r) +- return r; +- } +- +- return r; +-} +- +-/** + * amdgpu_vm_validate_pt_bos - validate the page table BOs + * + * @adev: amdgpu device pointer +@@ -223,32 +168,43 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, + int (*validate)(void *p, struct amdgpu_bo *bo), + void *param) + { +- uint64_t num_evictions; ++ struct ttm_bo_global *glob = adev->mman.bdev.glob; ++ int r; + +- /* We only need to validate the page tables +- * if they aren't already valid. +- */ +- num_evictions = atomic64_read(&adev->num_evictions); +- if (num_evictions == vm->last_eviction_counter) +- return 0; ++ spin_lock(&vm->status_lock); ++ while (!list_empty(&vm->evicted)) { ++ struct amdgpu_vm_bo_base *bo_base; ++ struct amdgpu_bo *bo; + +- return amdgpu_vm_validate_level(&vm->root, validate, param, +- vm->use_cpu_for_update, +- adev->mman.bdev.glob); +-} ++ bo_base = list_first_entry(&vm->evicted, ++ struct amdgpu_vm_bo_base, ++ vm_status); ++ spin_unlock(&vm->status_lock); + +-/** +- * amdgpu_vm_check - helper for amdgpu_vm_ready +- */ +-static int amdgpu_vm_check(void *param, struct amdgpu_bo *bo) +-{ +- /* if anything is swapped out don't swap it in here, +- just abort and wait for the next CS */ +- if (!amdgpu_bo_gpu_accessible(bo)) +- return -ERESTARTSYS; ++ bo = bo_base->bo; ++ BUG_ON(!bo); ++ if (bo->parent) { ++ r = validate(param, bo); ++ if (r) ++ return r; + +- if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow)) +- return -ERESTARTSYS; ++ spin_lock(&glob->lru_lock); ++ ttm_bo_move_to_lru_tail(&bo->tbo); ++ if (bo->shadow) ++ ttm_bo_move_to_lru_tail(&bo->shadow->tbo); ++ spin_unlock(&glob->lru_lock); ++ } ++ ++ if (vm->use_cpu_for_update) { ++ r = amdgpu_bo_kmap(bo, NULL); ++ if (r) ++ return r; ++ } ++ ++ spin_lock(&vm->status_lock); ++ list_del_init(&bo_base->vm_status); ++ } ++ spin_unlock(&vm->status_lock); + + return 0; + } +@@ -256,17 +212,19 @@ static int amdgpu_vm_check(void *param, struct amdgpu_bo *bo) + /** + * amdgpu_vm_ready - check VM is ready for updates + * +- * @adev: amdgpu device + * @vm: VM to check + * + * Check if all VM PDs/PTs are ready for updates + */ +-bool amdgpu_vm_ready(struct amdgpu_device *adev, struct amdgpu_vm *vm) ++bool amdgpu_vm_ready(struct amdgpu_vm *vm) + { +- if (amdgpu_vm_check(NULL, vm->root.bo)) +- return false; ++ bool ready; ++ ++ spin_lock(&vm->status_lock); ++ ready = list_empty(&vm->evicted); ++ spin_unlock(&vm->status_lock); + +- return !amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_vm_check, NULL); ++ return ready; + } + + /** +@@ -337,11 +295,11 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, + + /* walk over the address space and allocate the page tables */ + for (pt_idx = from; pt_idx <= to; ++pt_idx) { +- struct reservation_object *resv = vm->root.bo->tbo.resv; ++ struct reservation_object *resv = vm->root.base.bo->tbo.resv; + struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; + struct amdgpu_bo *pt; + +- if (!entry->bo) { ++ if (!entry->base.bo) { + r = amdgpu_bo_create(adev, + amdgpu_vm_bo_size(adev, level), + AMDGPU_GPU_PAGE_SIZE, true, +@@ -362,9 +320,12 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev, + /* Keep a reference to the root directory to avoid + * freeing them up in the wrong order. + */ +- pt->parent = amdgpu_bo_ref(vm->root.bo); ++ pt->parent = amdgpu_bo_ref(vm->root.base.bo); + +- entry->bo = pt; ++ entry->base.vm = vm; ++ entry->base.bo = pt; ++ list_add_tail(&entry->base.bo_list, &pt->va); ++ INIT_LIST_HEAD(&entry->base.vm_status); + entry->addr = 0; + } + +@@ -1031,7 +992,7 @@ static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm, + int r; + + amdgpu_sync_create(&sync); +- amdgpu_sync_resv(adev, &sync, vm->root.bo->tbo.resv, owner); ++ amdgpu_sync_resv(adev, &sync, vm->root.base.bo->tbo.resv, owner); + r = amdgpu_sync_wait(&sync, true); + amdgpu_sync_free(&sync); + +@@ -1070,10 +1031,10 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, + + memset(¶ms, 0, sizeof(params)); + params.adev = adev; +- shadow = parent->bo->shadow; ++ shadow = parent->base.bo->shadow; + + if (vm->use_cpu_for_update) { +- pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo); ++ pd_addr = (unsigned long)amdgpu_bo_kptr(parent->base.bo); + r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM); + if (unlikely(r)) + return r; +@@ -1089,7 +1050,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, + /* assume the worst case */ + ndw += parent->last_entry_used * 6; + +- pd_addr = amdgpu_bo_gpu_offset(parent->bo); ++ pd_addr = amdgpu_bo_gpu_offset(parent->base.bo); + + if (shadow) { + shadow_addr = amdgpu_bo_gpu_offset(shadow); +@@ -1109,7 +1070,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, + + /* walk over the address space and update the directory */ + for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { +- struct amdgpu_bo *bo = parent->entries[pt_idx].bo; ++ struct amdgpu_bo *bo = parent->entries[pt_idx].base.bo; + uint64_t pde, pt; + + if (bo == NULL) +@@ -1152,7 +1113,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, + } + + if (count) { +- if (vm->root.bo->shadow) ++ if (vm->root.base.bo->shadow) + params.func(¶ms, last_shadow, last_pt, + count, incr, AMDGPU_PTE_VALID); + +@@ -1165,7 +1126,8 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, + amdgpu_job_free(job); + } else { + amdgpu_ring_pad_ib(ring, params.ib); +- amdgpu_sync_resv(adev, &job->sync, parent->bo->tbo.resv, ++ amdgpu_sync_resv(adev, &job->sync, ++ parent->base.bo->tbo.resv, + AMDGPU_FENCE_OWNER_VM); + if (shadow) + amdgpu_sync_resv(adev, &job->sync, +@@ -1178,7 +1140,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, + if (r) + goto error_free; + +- amdgpu_bo_fence(parent->bo, fence, true); ++ amdgpu_bo_fence(parent->base.bo, fence, true); + dma_fence_put(vm->last_dir_update); + vm->last_dir_update = dma_fence_get(fence); + dma_fence_put(fence); +@@ -1191,7 +1153,7 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev, + for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { + struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; + +- if (!entry->bo) ++ if (!entry->base.bo) + continue; + + r = amdgpu_vm_update_level(adev, vm, entry, level + 1); +@@ -1224,7 +1186,7 @@ static void amdgpu_vm_invalidate_level(struct amdgpu_vm_pt *parent) + for (pt_idx = 0; pt_idx <= parent->last_entry_used; ++pt_idx) { + struct amdgpu_vm_pt *entry = &parent->entries[pt_idx]; + +- if (!entry->bo) ++ if (!entry->base.bo) + continue; + + entry->addr = ~0ULL; +@@ -1279,7 +1241,7 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr, + *entry = &p->vm->root; + while ((*entry)->entries) { + idx = addr >> (p->adev->vm_manager.block_size * level--); +- idx %= amdgpu_bo_size((*entry)->bo) / 8; ++ idx %= amdgpu_bo_size((*entry)->base.bo) / 8; + *parent = *entry; + *entry = &(*entry)->entries[idx]; + } +@@ -1315,7 +1277,7 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, + p->src || + !(flags & AMDGPU_PTE_VALID)) { + +- dst = amdgpu_bo_gpu_offset(entry->bo); ++ dst = amdgpu_bo_gpu_offset(entry->base.bo); + dst = amdgpu_gart_get_vm_pde(p->adev, dst); + flags = AMDGPU_PTE_VALID; + } else { +@@ -1341,18 +1303,18 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, + tmp = p->pages_addr; + p->pages_addr = NULL; + +- pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo); ++ pd_addr = (unsigned long)amdgpu_bo_kptr(parent->base.bo); + pde = pd_addr + (entry - parent->entries) * 8; + amdgpu_vm_cpu_set_ptes(p, pde, dst, 1, 0, flags); + + p->pages_addr = tmp; + } else { +- if (parent->bo->shadow) { +- pd_addr = amdgpu_bo_gpu_offset(parent->bo->shadow); ++ if (parent->base.bo->shadow) { ++ pd_addr = amdgpu_bo_gpu_offset(parent->base.bo->shadow); + pde = pd_addr + (entry - parent->entries) * 8; + amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); + } +- pd_addr = amdgpu_bo_gpu_offset(parent->bo); ++ pd_addr = amdgpu_bo_gpu_offset(parent->base.bo); + pde = pd_addr + (entry - parent->entries) * 8; + amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); + } +@@ -1403,7 +1365,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params, + if (entry->addr & AMDGPU_PDE_PTE) + continue; + +- pt = entry->bo; ++ pt = entry->base.bo; + if (use_cpu_update) { + pe_start = (unsigned long)amdgpu_bo_kptr(pt); + } else { +@@ -1623,12 +1585,12 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, + if (r) + goto error_free; + +- r = amdgpu_sync_resv(adev, &job->sync, vm->root.bo->tbo.resv, ++ r = amdgpu_sync_resv(adev, &job->sync, vm->root.base.bo->tbo.resv, + owner); + if (r) + goto error_free; + +- r = reservation_object_reserve_shared(vm->root.bo->tbo.resv); ++ r = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv); + if (r) + goto error_free; + +@@ -1643,7 +1605,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, + if (r) + goto error_free; + +- amdgpu_bo_fence(vm->root.bo, f, true); ++ amdgpu_bo_fence(vm->root.base.bo, f, true); + dma_fence_put(*fence); + *fence = f; + return 0; +@@ -1955,7 +1917,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) + { +- struct reservation_object *resv = vm->root.bo->tbo.resv; ++ struct reservation_object *resv = vm->root.base.bo->tbo.resv; + struct dma_fence *excl, **shared; + unsigned i, shared_count; + int r; +@@ -2442,12 +2404,25 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, + * Mark @bo as invalid. + */ + void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, +- struct amdgpu_bo *bo) ++ struct amdgpu_bo *bo, bool evicted) + { + struct amdgpu_vm_bo_base *bo_base; + + list_for_each_entry(bo_base, &bo->va, bo_list) { ++ struct amdgpu_vm *vm = bo_base->vm; ++ + bo_base->moved = true; ++ if (evicted && bo->tbo.resv == vm->root.base.bo->tbo.resv) { ++ spin_lock(&bo_base->vm->status_lock); ++ list_move(&bo_base->vm_status, &vm->evicted); ++ spin_unlock(&bo_base->vm->status_lock); ++ continue; ++ } ++ ++ /* Don't add page tables to the moved state */ ++ if (bo->tbo.type == ttm_bo_type_kernel) ++ continue; ++ + spin_lock(&bo_base->vm->status_lock); + spin_unlock(&bo_base->vm->status_lock); + } +@@ -2534,6 +2509,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, + for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) + vm->reserved_vmid[i] = NULL; + spin_lock_init(&vm->status_lock); ++ INIT_LIST_HEAD(&vm->evicted); + INIT_LIST_HEAD(&vm->moved); + INIT_LIST_HEAD(&vm->freed); + +@@ -2578,23 +2554,24 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, + r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, true, + AMDGPU_GEM_DOMAIN_VRAM, + flags, +- NULL, NULL, init_pde_value, &vm->root.bo); ++ NULL, NULL, init_pde_value, &vm->root.base.bo); + if (r) + goto error_free_sched_entity; + +- r = amdgpu_bo_reserve(vm->root.bo, false); +- if (r) +- goto error_free_root; +- +- vm->last_eviction_counter = atomic64_read(&adev->num_evictions); ++ vm->root.base.vm = vm; ++ list_add_tail(&vm->root.base.bo_list, &vm->root.base.bo->va); ++ INIT_LIST_HEAD(&vm->root.base.vm_status); + + if (vm->use_cpu_for_update) { +- r = amdgpu_bo_kmap(vm->root.bo, NULL); ++ r = amdgpu_bo_reserve(vm->root.base.bo, false); + if (r) + goto error_free_root; +- } + +- amdgpu_bo_unreserve(vm->root.bo); ++ r = amdgpu_bo_kmap(vm->root.base.bo, NULL); ++ if (r) ++ goto error_free_root; ++ amdgpu_bo_unreserve(vm->root.base.bo); ++ } + + vm->vm_context = vm_context; + if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE) { +@@ -2619,9 +2596,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, + return 0; + + error_free_root: +- amdgpu_bo_unref(&vm->root.bo->shadow); +- amdgpu_bo_unref(&vm->root.bo); +- vm->root.bo = NULL; ++ amdgpu_bo_unref(&vm->root.base.bo->shadow); ++ amdgpu_bo_unref(&vm->root.base.bo); ++ vm->root.base.bo = NULL; + + error_free_sched_entity: + amd_sched_entity_fini(&ring->sched, &vm->entity); +@@ -2640,9 +2617,11 @@ static void amdgpu_vm_free_levels(struct amdgpu_vm_pt *level) + { + unsigned i; + +- if (level->bo) { +- amdgpu_bo_unref(&level->bo->shadow); +- amdgpu_bo_unref(&level->bo); ++ if (level->base.bo) { ++ list_del(&level->base.bo_list); ++ list_del(&level->base.vm_status); ++ amdgpu_bo_unref(&level->base.bo->shadow); ++ amdgpu_bo_unref(&level->base.bo); + } + + if (level->entries) +-- +2.7.4 + |