Commit 0e2e7c5b authored by Felix Kuehling's avatar Felix Kuehling Committed by Alex Deucher

drm/amdgpu: Attach eviction fence on alloc

Instead of attaching the eviction fence when a KFD BO is first mapped,
attach it when it is allocated or imported. This in preparation to allow
KFD BOs to be mapped using the render node API.
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5a104cb9
...@@ -425,6 +425,32 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain, ...@@ -425,6 +425,32 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain,
return ret; return ret;
} }
static int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo,
uint32_t domain,
struct dma_fence *fence)
{
int ret = amdgpu_bo_reserve(bo, false);
if (ret)
return ret;
ret = amdgpu_amdkfd_bo_validate(bo, domain, true);
if (ret)
goto unreserve_out;
ret = dma_resv_reserve_fences(bo->tbo.base.resv, 1);
if (ret)
goto unreserve_out;
dma_resv_add_fence(bo->tbo.base.resv, fence,
DMA_RESV_USAGE_BOOKKEEP);
unreserve_out:
amdgpu_bo_unreserve(bo);
return ret;
}
static int amdgpu_amdkfd_validate_vm_bo(void *_unused, struct amdgpu_bo *bo) static int amdgpu_amdkfd_validate_vm_bo(void *_unused, struct amdgpu_bo *bo)
{ {
return amdgpu_amdkfd_bo_validate(bo, bo->allowed_domains, false); return amdgpu_amdkfd_bo_validate(bo, bo->allowed_domains, false);
...@@ -1784,6 +1810,15 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( ...@@ -1784,6 +1810,15 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
} }
bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT; bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT; bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
} else {
mutex_lock(&avm->process_info->lock);
if (avm->process_info->eviction_fence &&
!dma_fence_is_signaled(&avm->process_info->eviction_fence->base))
ret = amdgpu_amdkfd_bo_validate_and_fence(bo, domain,
&avm->process_info->eviction_fence->base);
mutex_unlock(&avm->process_info->lock);
if (ret)
goto err_validate_bo;
} }
if (offset) if (offset)
...@@ -1793,6 +1828,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( ...@@ -1793,6 +1828,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
allocate_init_user_pages_failed: allocate_init_user_pages_failed:
err_pin_bo: err_pin_bo:
err_validate_bo:
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
drm_vma_node_revoke(&gobj->vma_node, drm_priv); drm_vma_node_revoke(&gobj->vma_node, drm_priv);
err_node_allow: err_node_allow:
...@@ -1866,10 +1902,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( ...@@ -1866,10 +1902,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
if (unlikely(ret)) if (unlikely(ret))
return ret; return ret;
/* The eviction fence should be removed by the last unmap.
* TODO: Log an error condition if the bo still has the eviction fence
* attached
*/
amdgpu_amdkfd_remove_eviction_fence(mem->bo, amdgpu_amdkfd_remove_eviction_fence(mem->bo,
process_info->eviction_fence); process_info->eviction_fence);
pr_debug("Release VA 0x%llx - 0x%llx\n", mem->va, pr_debug("Release VA 0x%llx - 0x%llx\n", mem->va,
...@@ -1998,19 +2030,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( ...@@ -1998,19 +2030,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
if (unlikely(ret)) if (unlikely(ret))
goto out_unreserve; goto out_unreserve;
if (mem->mapped_to_gpu_memory == 0 &&
!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
/* Validate BO only once. The eviction fence gets added to BO
* the first time it is mapped. Validate will wait for all
* background evictions to complete.
*/
ret = amdgpu_amdkfd_bo_validate(bo, domain, true);
if (ret) {
pr_debug("Validate failed\n");
goto out_unreserve;
}
}
list_for_each_entry(entry, &mem->attachments, list) { list_for_each_entry(entry, &mem->attachments, list) {
if (entry->bo_va->base.vm != avm || entry->is_mapped) if (entry->bo_va->base.vm != avm || entry->is_mapped)
continue; continue;
...@@ -2037,10 +2056,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( ...@@ -2037,10 +2056,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
mem->mapped_to_gpu_memory); mem->mapped_to_gpu_memory);
} }
if (!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) && !bo->tbo.pin_count)
dma_resv_add_fence(bo->tbo.base.resv,
&avm->process_info->eviction_fence->base,
DMA_RESV_USAGE_BOOKKEEP);
ret = unreserve_bo_and_vms(&ctx, false, false); ret = unreserve_bo_and_vms(&ctx, false, false);
goto out; goto out;
...@@ -2074,7 +2089,6 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( ...@@ -2074,7 +2089,6 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv) struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv)
{ {
struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv); struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
struct amdkfd_process_info *process_info = avm->process_info;
unsigned long bo_size = mem->bo->tbo.base.size; unsigned long bo_size = mem->bo->tbo.base.size;
struct kfd_mem_attachment *entry; struct kfd_mem_attachment *entry;
struct bo_vm_reservation_context ctx; struct bo_vm_reservation_context ctx;
...@@ -2115,15 +2129,6 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( ...@@ -2115,15 +2129,6 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
mem->mapped_to_gpu_memory); mem->mapped_to_gpu_memory);
} }
/* If BO is unmapped from all VMs, unfence it. It can be evicted if
* required.
*/
if (mem->mapped_to_gpu_memory == 0 &&
!amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) &&
!mem->bo->tbo.pin_count)
amdgpu_amdkfd_remove_eviction_fence(mem->bo,
process_info->eviction_fence);
unreserve_out: unreserve_out:
unreserve_bo_and_vms(&ctx, false, false); unreserve_bo_and_vms(&ctx, false, false);
out: out:
...@@ -2351,8 +2356,20 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, ...@@ -2351,8 +2356,20 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
amdgpu_sync_create(&(*mem)->sync); amdgpu_sync_create(&(*mem)->sync);
(*mem)->is_imported = true; (*mem)->is_imported = true;
mutex_lock(&avm->process_info->lock);
if (avm->process_info->eviction_fence &&
!dma_fence_is_signaled(&avm->process_info->eviction_fence->base))
ret = amdgpu_amdkfd_bo_validate_and_fence(bo, (*mem)->domain,
&avm->process_info->eviction_fence->base);
mutex_unlock(&avm->process_info->lock);
if (ret)
goto err_remove_mem;
return 0; return 0;
err_remove_mem:
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
drm_vma_node_revoke(&obj->vma_node, drm_priv);
err_free_mem: err_free_mem:
kfree(*mem); kfree(*mem);
err_put_obj: err_put_obj:
......
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