Re: [PATCH 6/8] drm/amdgpu: Map userqueue into HW
On 07/02/2023 08:20, Christian König wrote: Am 03.02.23 um 22:54 schrieb Shashank Sharma: From: Shashank Sharma This patch adds new fptrs to prepare the usermode queue to be mapped or unmapped into the HW. After this mapping, the queue will be ready to accept the workload. V1: Addressed review comments from Alex on the RFC patch series - Map/Unmap should be IP specific. Cc: Alex Deucher Cc: Christian Koenig Signed-off-by: Shashank Sharma --- drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 57 +++ .../amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c | 47 +++ .../gpu/drm/amd/include/amdgpu_userqueue.h | 2 + 3 files changed, 106 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c index 18281b3a51f1..cbfe2608c040 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c @@ -42,6 +42,53 @@ static struct amdgpu_usermode_queue return idr_find(&uq_mgr->userq_idr, qid); } +static void +amdgpu_userqueue_unmap(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ + int r; + struct amdgpu_device *adev = uq_mgr->adev; + struct mes_remove_queue_input remove_request; + + uq_mgr->userq_mqd_funcs->prepare_unmap(uq_mgr, queue, (void *)&remove_request); + + amdgpu_mes_lock(&adev->mes); + r = adev->mes.funcs->remove_hw_queue(&adev->mes, &remove_request); + amdgpu_mes_unlock(&adev->mes); + if (r) { + DRM_ERROR("Failed to unmap usermode queue %d\n", queue->queue_id); + return; + } + + DRM_DEBUG_DRIVER("Usermode queue %d unmapped\n", queue->queue_id); +} + +static int +amdgpu_userqueue_map(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ + int r; + struct amdgpu_device *adev = uq_mgr->adev; + struct mes_add_queue_input add_request; + + r = uq_mgr->userq_mqd_funcs->prepare_map(uq_mgr, queue, (void *)&add_request); + if (r) { + DRM_ERROR("Failed to map userqueue\n"); + return r; + } + + amdgpu_mes_lock(&adev->mes); + r = adev->mes.funcs->add_hw_queue(&adev->mes, &add_request); + amdgpu_mes_unlock(&adev->mes); + if (r) { + DRM_ERROR("Failed to map queue in HW, err (%d)\n", r); + return r; + } + + DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id); + return 0; +} + static void amdgpu_userqueue_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue) @@ -170,12 +217,21 @@ static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq goto free_mqd; } + r = amdgpu_userqueue_map(uq_mgr, queue); + if (r) { + DRM_ERROR("Failed to map userqueue\n"); + goto free_ctx; + } + list_add_tail(&queue->userq_node, &uq_mgr->userq_list); args->out.q_id = queue->queue_id; args->out.flags = 0; mutex_unlock(&uq_mgr->userq_mutex); return 0; +free_ctx: + amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue); + free_mqd: amdgpu_userqueue_destroy_mqd(uq_mgr, queue); @@ -201,6 +257,7 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id) } mutex_lock(&uq_mgr->userq_mutex); + amdgpu_userqueue_unmap(uq_mgr, queue); amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue); amdgpu_userqueue_destroy_mqd(uq_mgr, queue); amdgpu_userqueue_free_index(uq_mgr, queue->queue_id); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c index 687f90a587e3..d317bb600fd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c @@ -24,6 +24,7 @@ #include "amdgpu_userqueue.h" #include "v11_structs.h" #include "amdgpu_mes.h" +#include "mes_api_def.h" #include "gc/gc_11_0_0_offset.h" #include "gc/gc_11_0_0_sh_mask.h" @@ -239,6 +240,50 @@ static void amdgpu_userq_gfx_v11_ctx_destroy(struct amdgpu_userq_mgr *uq_mgr, &pctx->cpu_ptr); } +static int +amdgpu_userq_gfx_v11_prepare_map(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue, + void *q_input) +{ + struct amdgpu_device *adev = uq_mgr->adev; + struct mes_add_queue_input *queue_input = q_input; + + memset(queue_input, 0x0, sizeof(struct mes_add_queue_input)); + + queue_input->process_va_start = 0; + queue_input->process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT; + queue_input->process_quantum = 10; /* 10ms */ + queue_input->gang_quantum = 1; /* 1ms */ + queue_input->paging = false; + + queue_input->gang_context_addr = queue->gang_ctx.gpu_addr; + queue_input->pro
Re: [PATCH 6/8] drm/amdgpu: Map userqueue into HW
Am 03.02.23 um 22:54 schrieb Shashank Sharma: From: Shashank Sharma This patch adds new fptrs to prepare the usermode queue to be mapped or unmapped into the HW. After this mapping, the queue will be ready to accept the workload. V1: Addressed review comments from Alex on the RFC patch series - Map/Unmap should be IP specific. Cc: Alex Deucher Cc: Christian Koenig Signed-off-by: Shashank Sharma --- drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 57 +++ .../amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c | 47 +++ .../gpu/drm/amd/include/amdgpu_userqueue.h| 2 + 3 files changed, 106 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c index 18281b3a51f1..cbfe2608c040 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c @@ -42,6 +42,53 @@ static struct amdgpu_usermode_queue return idr_find(&uq_mgr->userq_idr, qid); } +static void +amdgpu_userqueue_unmap(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ +int r; +struct amdgpu_device *adev = uq_mgr->adev; +struct mes_remove_queue_input remove_request; + +uq_mgr->userq_mqd_funcs->prepare_unmap(uq_mgr, queue, (void *)&remove_request); + +amdgpu_mes_lock(&adev->mes); +r = adev->mes.funcs->remove_hw_queue(&adev->mes, &remove_request); +amdgpu_mes_unlock(&adev->mes); +if (r) { +DRM_ERROR("Failed to unmap usermode queue %d\n", queue->queue_id); +return; +} + +DRM_DEBUG_DRIVER("Usermode queue %d unmapped\n", queue->queue_id); +} + +static int +amdgpu_userqueue_map(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ +int r; +struct amdgpu_device *adev = uq_mgr->adev; +struct mes_add_queue_input add_request; + +r = uq_mgr->userq_mqd_funcs->prepare_map(uq_mgr, queue, (void *)&add_request); +if (r) { +DRM_ERROR("Failed to map userqueue\n"); +return r; +} + +amdgpu_mes_lock(&adev->mes); +r = adev->mes.funcs->add_hw_queue(&adev->mes, &add_request); +amdgpu_mes_unlock(&adev->mes); +if (r) { +DRM_ERROR("Failed to map queue in HW, err (%d)\n", r); +return r; +} + +DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id); +return 0; +} + static void amdgpu_userqueue_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue) @@ -170,12 +217,21 @@ static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq goto free_mqd; } +r = amdgpu_userqueue_map(uq_mgr, queue); +if (r) { +DRM_ERROR("Failed to map userqueue\n"); +goto free_ctx; +} + list_add_tail(&queue->userq_node, &uq_mgr->userq_list); args->out.q_id = queue->queue_id; args->out.flags = 0; mutex_unlock(&uq_mgr->userq_mutex); return 0; +free_ctx: +amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue); + free_mqd: amdgpu_userqueue_destroy_mqd(uq_mgr, queue); @@ -201,6 +257,7 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id) } mutex_lock(&uq_mgr->userq_mutex); +amdgpu_userqueue_unmap(uq_mgr, queue); amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue); amdgpu_userqueue_destroy_mqd(uq_mgr, queue); amdgpu_userqueue_free_index(uq_mgr, queue->queue_id); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c index 687f90a587e3..d317bb600fd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c @@ -24,6 +24,7 @@ #include "amdgpu_userqueue.h" #include "v11_structs.h" #include "amdgpu_mes.h" +#include "mes_api_def.h" #include "gc/gc_11_0_0_offset.h" #include "gc/gc_11_0_0_sh_mask.h" @@ -239,6 +240,50 @@ static void amdgpu_userq_gfx_v11_ctx_destroy(struct amdgpu_userq_mgr *uq_mgr, &pctx->cpu_ptr); } +static int +amdgpu_userq_gfx_v11_prepare_map(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue, + void *q_input) +{ +struct amdgpu_device *adev = uq_mgr->adev; +struct mes_add_queue_input *queue_input = q_input; + +memset(queue_input, 0x0, sizeof(struct mes_add_queue_input)); + +queue_input->process_va_start = 0; +queue_input->process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT; +queue_input->process_quantum = 10; /* 10ms */ +queue_input->gang_quantum = 1; /* 1ms */ +queue_input->paging = false; + +queue_input->gang_context_addr = queue->gang_ctx.gpu_addr; +queue_input->process_context_addr = queue->proc_ctx.gpu_addr; +
[PATCH 6/8] drm/amdgpu: Map userqueue into HW
From: Shashank Sharma This patch adds new fptrs to prepare the usermode queue to be mapped or unmapped into the HW. After this mapping, the queue will be ready to accept the workload. V1: Addressed review comments from Alex on the RFC patch series - Map/Unmap should be IP specific. Cc: Alex Deucher Cc: Christian Koenig Signed-off-by: Shashank Sharma --- drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 57 +++ .../amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c | 47 +++ .../gpu/drm/amd/include/amdgpu_userqueue.h| 2 + 3 files changed, 106 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c index 18281b3a51f1..cbfe2608c040 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c @@ -42,6 +42,53 @@ static struct amdgpu_usermode_queue return idr_find(&uq_mgr->userq_idr, qid); } +static void +amdgpu_userqueue_unmap(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ +int r; +struct amdgpu_device *adev = uq_mgr->adev; +struct mes_remove_queue_input remove_request; + +uq_mgr->userq_mqd_funcs->prepare_unmap(uq_mgr, queue, (void *)&remove_request); + +amdgpu_mes_lock(&adev->mes); +r = adev->mes.funcs->remove_hw_queue(&adev->mes, &remove_request); +amdgpu_mes_unlock(&adev->mes); +if (r) { +DRM_ERROR("Failed to unmap usermode queue %d\n", queue->queue_id); +return; +} + +DRM_DEBUG_DRIVER("Usermode queue %d unmapped\n", queue->queue_id); +} + +static int +amdgpu_userqueue_map(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue) +{ +int r; +struct amdgpu_device *adev = uq_mgr->adev; +struct mes_add_queue_input add_request; + +r = uq_mgr->userq_mqd_funcs->prepare_map(uq_mgr, queue, (void *)&add_request); +if (r) { +DRM_ERROR("Failed to map userqueue\n"); +return r; +} + +amdgpu_mes_lock(&adev->mes); +r = adev->mes.funcs->add_hw_queue(&adev->mes, &add_request); +amdgpu_mes_unlock(&adev->mes); +if (r) { +DRM_ERROR("Failed to map queue in HW, err (%d)\n", r); +return r; +} + +DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id); +return 0; +} + static void amdgpu_userqueue_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue) @@ -170,12 +217,21 @@ static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq goto free_mqd; } +r = amdgpu_userqueue_map(uq_mgr, queue); +if (r) { +DRM_ERROR("Failed to map userqueue\n"); +goto free_ctx; +} + list_add_tail(&queue->userq_node, &uq_mgr->userq_list); args->out.q_id = queue->queue_id; args->out.flags = 0; mutex_unlock(&uq_mgr->userq_mutex); return 0; +free_ctx: +amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue); + free_mqd: amdgpu_userqueue_destroy_mqd(uq_mgr, queue); @@ -201,6 +257,7 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id) } mutex_lock(&uq_mgr->userq_mutex); +amdgpu_userqueue_unmap(uq_mgr, queue); amdgpu_userqueue_destroy_ctx_space(uq_mgr, queue); amdgpu_userqueue_destroy_mqd(uq_mgr, queue); amdgpu_userqueue_free_index(uq_mgr, queue->queue_id); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c index 687f90a587e3..d317bb600fd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue_mqd_gfx_v11.c @@ -24,6 +24,7 @@ #include "amdgpu_userqueue.h" #include "v11_structs.h" #include "amdgpu_mes.h" +#include "mes_api_def.h" #include "gc/gc_11_0_0_offset.h" #include "gc/gc_11_0_0_sh_mask.h" @@ -239,6 +240,50 @@ static void amdgpu_userq_gfx_v11_ctx_destroy(struct amdgpu_userq_mgr *uq_mgr, &pctx->cpu_ptr); } +static int +amdgpu_userq_gfx_v11_prepare_map(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_usermode_queue *queue, + void *q_input) +{ +struct amdgpu_device *adev = uq_mgr->adev; +struct mes_add_queue_input *queue_input = q_input; + +memset(queue_input, 0x0, sizeof(struct mes_add_queue_input)); + +queue_input->process_va_start = 0; +queue_input->process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT; +queue_input->process_quantum = 10; /* 10ms */ +queue_input->gang_quantum = 1; /* 1ms */ +queue_input->paging = false; + +queue_input->gang_context_addr = queue->gang_ctx.gpu_addr; +queue_input->process_context_addr = queue->proc_ctx.gpu_addr; +queue_input->inprocess_gang_priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL; +queue_input->