This patch: - Adds a amdgpu_doorbell object in MES process. - Allocs doorbell pages for MES process using doorbell manager. - uses doorbell manager to get an absolute index of doorbells. - removes a offset calculation function which is no more required. - removes prototype of a few functions which are not required. PS: This patch ensures that we don't break the existing KFD functionality, but now KFD userspace library must also move to creating doorbell pages as AMDGPU GEM objects using libdrm functions in userspace. The reference code for the same is available with AMDGPU Usermode queue libdrm MR. Cc: Alex Deucher <alexander.deucher@xxxxxxx> Cc: Christian Koenig <christian.koenig@xxxxxxx> Signed-off-by: Shashank Sharma <shashank.sharma@xxxxxxx> Signed-off-by: Arvind Yadav <arvind.yadav@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 60 ++++++++++++------------- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 12 ++--- 2 files changed, 31 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 423cd642647c..7c6cf3d2c8ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -36,33 +36,40 @@ int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev) PAGE_SIZE); } -int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev, - unsigned int *doorbell_index) +static int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev, + struct amdgpu_mes_process *process) { - int r = ida_simple_get(&adev->mes.doorbell_ida, 2, - adev->mes.max_doorbell_slices, - GFP_KERNEL); - if (r > 0) - *doorbell_index = r; + int r; + struct amdgpu_doorbell_obj *proc_doorbells = &process->proc_doorbells; + + /* Bitmap for dynamic allocation of doorbell */ + proc_doorbells->doorbell_bitmap = bitmap_zalloc( + AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS, + GFP_KERNEL); + if (!proc_doorbells->doorbell_bitmap) { + DRM_ERROR("failed to allocate MES process doorbell bitmap\n"); + return -ENOMEM; + } + + /* Reserve actual doorbells from the BAR */ + proc_doorbells->size = amdgpu_mes_doorbell_process_slice(adev); + r = amdgpu_doorbell_alloc_page(adev, proc_doorbells); + if (r) { + bitmap_free(proc_doorbells->doorbell_bitmap); + DRM_ERROR("failed to allocate MES process doorbells\n"); + return r; + } return r; } void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev, - unsigned int doorbell_index) + struct amdgpu_mes_process *process) { - if (doorbell_index) - ida_simple_remove(&adev->mes.doorbell_ida, doorbell_index); -} + struct amdgpu_doorbell_obj *proc_doorbells = &process->proc_doorbells; -unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar( - struct amdgpu_device *adev, - uint32_t doorbell_index, - unsigned int doorbell_id) -{ - return ((doorbell_index * - amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32) + - doorbell_id * 2); + bitmap_free(proc_doorbells->doorbell_bitmap); + amdgpu_doorbell_free_page(adev, proc_doorbells); } static int amdgpu_mes_kernel_doorbell_get(struct amdgpu_device *adev, @@ -275,15 +282,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid, return -ENOMEM; } - process->doorbell_bitmap = - kzalloc(DIV_ROUND_UP(AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS, - BITS_PER_BYTE), GFP_KERNEL); - if (!process->doorbell_bitmap) { - DRM_ERROR("failed to allocate doorbell bitmap\n"); - kfree(process); - return -ENOMEM; - } - /* allocate the process context bo and map it */ r = amdgpu_bo_create_kernel(adev, AMDGPU_MES_PROC_CTX_SIZE, PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, @@ -311,7 +309,7 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid, } /* allocate the starting doorbell index of the process */ - r = amdgpu_mes_alloc_process_doorbells(adev, &process->doorbell_index); + r = amdgpu_mes_alloc_process_doorbells(adev, process); if (r < 0) { DRM_ERROR("failed to allocate doorbell for process\n"); goto clean_up_pasid; @@ -336,7 +334,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid, &process->proc_ctx_gpu_addr, &process->proc_ctx_cpu_ptr); clean_up_memory: - kfree(process->doorbell_bitmap); kfree(process); return r; } @@ -382,7 +379,7 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid) idr_remove(&adev->mes.gang_id_idr, gang->gang_id); } - amdgpu_mes_free_process_doorbells(adev, process->doorbell_index); + amdgpu_mes_free_process_doorbells(adev, process); idr_remove(&adev->mes.pasid_idr, pasid); amdgpu_mes_unlock(&adev->mes); @@ -404,7 +401,6 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid) amdgpu_bo_free_kernel(&process->proc_ctx_bo, &process->proc_ctx_gpu_addr, &process->proc_ctx_cpu_ptr); - kfree(process->doorbell_bitmap); kfree(process); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h index e7e9dfe44c99..0c659ade527c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -145,8 +145,10 @@ struct amdgpu_mes_process { uint64_t process_quantum; struct list_head gang_list; uint32_t doorbell_index; - unsigned long *doorbell_bitmap; struct mutex doorbell_lock; + + /* process doorbells */ + struct amdgpu_doorbell_obj proc_doorbells; }; struct amdgpu_mes_gang { @@ -364,14 +366,6 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev, int amdgpu_mes_self_test(struct amdgpu_device *adev); -int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev, - unsigned int *doorbell_index); -void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev, - unsigned int doorbell_index); -unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar( - struct amdgpu_device *adev, - uint32_t doorbell_index, - unsigned int doorbell_id); int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev); /* -- 2.40.0