Those helpers allocates/frees slots from bitmaps for process_context_array_index processed by MES firmware.
Signed-off-by: Prike Liang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 46 ++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 5 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 2 + drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 9 ++++- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 1 + 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index f65f2a30154d..db9c46ece2a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -1035,6 +1035,52 @@ int amdgpu_mes_rs64mem_setup_bitmaps(struct amdgpu_mes *mes) return 0; } +/** + * amdgpu_mes_alloc_proc_ctx_index - allocate a process context slot + * + * @mes: MES instance + * + * Returns 0 on success, -ENOSPC if all slots are used (caller should + * fall back to system memory path). + */ +int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes *mes, + struct amdgpu_usermode_queue *queue) +{ + unsigned long bit; + + if (!mes->use_rs64mem || !mes->proc_ctx_bitmap) + return -EOPNOTSUPP; + + amdgpu_mes_lock(mes); + bit = find_first_zero_bit(mes->proc_ctx_bitmap, + mes->proc_ctx_array_size); + if (bit >= mes->proc_ctx_array_size) { + amdgpu_mes_unlock(mes); + return -ENOSPC; + } + set_bit(bit, mes->proc_ctx_bitmap); + queue->proc_ctx_array_index = (uint32_t)bit; + amdgpu_mes_unlock(mes); + + return 0; +} + +/** + * amdgpu_mes_free_proc_ctx_index - free a process context slot + */ +void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes *mes, + struct amdgpu_usermode_queue *queue) +{ + if (!mes->use_rs64mem || !mes->proc_ctx_bitmap) + return; + if (queue->proc_ctx_array_index >= mes->proc_ctx_array_size) + return; + + amdgpu_mes_lock(mes); + clear_bit(queue->proc_ctx_array_index, mes->proc_ctx_bitmap); + amdgpu_mes_unlock(mes); +} + #if defined(CONFIG_DEBUG_FS) static int amdgpu_debugfs_mes_event_log_show(struct seq_file *m, void *unused) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h index 5c50bc9616b7..33a426f58e72 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -279,6 +279,7 @@ struct mes_add_queue_input { uint32_t exclusively_scheduled; uint32_t sh_mem_config_data; uint32_t vm_cntx_cntl; + uint32_t process_context_array_index; }; struct mes_remove_queue_input { @@ -631,4 +632,8 @@ int amdgpu_mes_update_enforce_isolation(struct amdgpu_device *adev); int amdgpu_mes_rs64mem_init(struct amdgpu_mes *mes); void amdgpu_mes_rs64mem_fini(struct amdgpu_mes *mes); int amdgpu_mes_rs64mem_setup_bitmaps(struct amdgpu_mes *mes); +int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes *mes, + struct amdgpu_usermode_queue *queue); +void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes *mes, + struct amdgpu_usermode_queue *queue); #endif /* __AMDGPU_MES_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h index 61e5f8a06eb2..8bb0d3213abf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h @@ -100,6 +100,8 @@ struct amdgpu_usermode_queue { } va; u64 va_array[6]; } userq_vas; + + uint32_t proc_ctx_array_index; }; struct amdgpu_userq_funcs { diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index 0bcc5afc9e84..e1ff0f22a6e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -121,6 +121,7 @@ static int mes_userq_map(struct amdgpu_usermode_queue *queue) struct amdgpu_userq_obj *ctx = &queue->fw_obj; struct amdgpu_mqd_prop *userq_props = queue->userq_prop; struct mes_add_queue_input queue_input; + struct amdgpu_mes *mes = &adev->mes; int r; memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input)); @@ -146,7 +147,10 @@ static int mes_userq_map(struct amdgpu_usermode_queue *queue) queue_input.doorbell_offset = userq_props->doorbell_index; queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo); queue_input.wptr_mc_addr = queue->wptr_obj.gpu_addr; - + if (mes->use_rs64mem) { + amdgpu_mes_alloc_proc_ctx_index(mes, queue); + queue_input.process_context_array_index = queue->proc_ctx_array_index; + } amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input); amdgpu_mes_unlock(&adev->mes); @@ -165,6 +169,7 @@ static int mes_userq_unmap(struct amdgpu_usermode_queue *queue) struct amdgpu_device *adev = uq_mgr->adev; struct mes_remove_queue_input queue_input; struct amdgpu_userq_obj *ctx = &queue->fw_obj; + struct amdgpu_mes *mes = &adev->mes; int r; memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input)); @@ -175,6 +180,8 @@ static int mes_userq_unmap(struct amdgpu_usermode_queue *queue) amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input); amdgpu_mes_unlock(&adev->mes); + if (mes->use_rs64mem) + amdgpu_mes_free_proc_ctx_index(mes, queue); if (r) DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r); return r; diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c index 195dc3b4058d..db09f63ec1ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -335,6 +335,7 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes, mes_add_queue_pkt.process_va_end = input->process_va_end; mes_add_queue_pkt.process_quantum = input->process_quantum; mes_add_queue_pkt.process_context_addr = input->process_context_addr; + mes_add_queue_pkt.process_context_array_index = input->process_context_array_index; mes_add_queue_pkt.gang_quantum = input->gang_quantum; mes_add_queue_pkt.gang_context_addr = input->gang_context_addr; mes_add_queue_pkt.inprocess_gang_priority = -- 2.34.1
