mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-05 08:18:02 -04:00
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: Ramesh Errabolu <Ramesh.Errabolu@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
f441dd33db
commit
d25e35bc26
@@ -1295,6 +1295,55 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
|
||||
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,
|
||||
struct file *filp, u32 pasid,
|
||||
void **process_info,
|
||||
@@ -1521,10 +1570,22 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
if (offset)
|
||||
*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;
|
||||
|
||||
allocate_init_user_pages_failed:
|
||||
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
|
||||
err_pin_bo:
|
||||
drm_vma_node_revoke(&gobj->vma_node, drm_priv);
|
||||
err_node_allow:
|
||||
drm_gem_object_put(gobj);
|
||||
@@ -1557,6 +1618,14 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
||||
bool is_imported = false;
|
||||
|
||||
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;
|
||||
is_imported = mem->is_imported;
|
||||
mutex_unlock(&mem->lock);
|
||||
|
||||
Reference in New Issue
Block a user