Commit d25e35bc authored by Ramesh Errabolu's avatar Ramesh Errabolu Committed by Alex Deucher

drm/amdgpu: Pin MMIO/DOORBELL BO's in GTT domain

MMIO/DOORBELL BOs encode control data and should be pinned in GTT
domain before enabling PCIe connected peer devices in accessing it
Signed-off-by: default avatarRamesh Errabolu <Ramesh.Errabolu@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f441dd33
...@@ -1295,6 +1295,55 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, ...@@ -1295,6 +1295,55 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
return ret; return ret;
} }
/**
* amdgpu_amdkfd_gpuvm_pin_bo() - Pins a BO using following criteria
* @bo: Handle of buffer object being pinned
* @domain: Domain into which BO should be pinned
*
* - USERPTR BOs are UNPINNABLE and will return error
* - All other BO types (GTT, VRAM, MMIO and DOORBELL) will have their
* PIN count incremented. It is valid to PIN a BO multiple times
*
* Return: ZERO if successful in pinning, Non-Zero in case of error.
*/
static int amdgpu_amdkfd_gpuvm_pin_bo(struct amdgpu_bo *bo, u32 domain)
{
int ret = 0;
ret = amdgpu_bo_reserve(bo, false);
if (unlikely(ret))
return ret;
ret = amdgpu_bo_pin_restricted(bo, domain, 0, 0);
if (ret)
pr_err("Error in Pinning BO to domain: %d\n", domain);
amdgpu_bo_sync_wait(bo, AMDGPU_FENCE_OWNER_KFD, false);
amdgpu_bo_unreserve(bo);
return ret;
}
/**
* amdgpu_amdkfd_gpuvm_unpin_bo() - Unpins BO using following criteria
* @bo: Handle of buffer object being unpinned
*
* - Is a illegal request for USERPTR BOs and is ignored
* - All other BO types (GTT, VRAM, MMIO and DOORBELL) will have their
* PIN count decremented. Calls to UNPIN must balance calls to PIN
*/
void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo)
{
int ret = 0;
ret = amdgpu_bo_reserve(bo, false);
if (unlikely(ret))
return;
amdgpu_bo_unpin(bo);
amdgpu_bo_unreserve(bo);
}
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev, int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
struct file *filp, u32 pasid, struct file *filp, u32 pasid,
void **process_info, void **process_info,
...@@ -1521,10 +1570,22 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( ...@@ -1521,10 +1570,22 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
if (offset) if (offset)
*offset = amdgpu_bo_mmap_offset(bo); *offset = amdgpu_bo_mmap_offset(bo);
if (flags & (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
ret = amdgpu_amdkfd_gpuvm_pin_bo(bo, AMDGPU_GEM_DOMAIN_GTT);
if (ret) {
pr_err("Pinning MMIO/DOORBELL BO during ALLOC FAILED\n");
goto err_pin_bo;
}
bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
}
return 0; return 0;
allocate_init_user_pages_failed: allocate_init_user_pages_failed:
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
err_pin_bo:
drm_vma_node_revoke(&gobj->vma_node, drm_priv); drm_vma_node_revoke(&gobj->vma_node, drm_priv);
err_node_allow: err_node_allow:
drm_gem_object_put(gobj); drm_gem_object_put(gobj);
...@@ -1557,6 +1618,14 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( ...@@ -1557,6 +1618,14 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
bool is_imported = false; bool is_imported = false;
mutex_lock(&mem->lock); mutex_lock(&mem->lock);
/* Unpin MMIO/DOORBELL BO's that were pinnned during allocation */
if (mem->alloc_flags &
(KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
amdgpu_amdkfd_gpuvm_unpin_bo(mem->bo);
}
mapped_to_gpu_memory = mem->mapped_to_gpu_memory; mapped_to_gpu_memory = mem->mapped_to_gpu_memory;
is_imported = mem->is_imported; is_imported = mem->is_imported;
mutex_unlock(&mem->lock); mutex_unlock(&mem->lock);
......
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