On Thu, Jul 9, 2026 at 3:09 AM Prike Liang <[email protected]> wrote:
>
> Setup the MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE MES firmware
> command request, and get the MES11 process/gang contex size.
>
> Signed-off-by: Prike Liang <[email protected]>
> ---
> drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 79 +++++++++++++++++++
> drivers/gpu/drm/amd/include/mes_v11_api_def.h | 61 ++++++++++++--
> 2 files changed, 132 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
> b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
> index c721a90051e9..195dc3b4058d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
> @@ -832,6 +832,58 @@ static int mes_v11_0_query_sched_status(struct
> amdgpu_mes *mes)
> offsetof(union MESAPI__QUERY_MES_STATUS, api_status));
> }
>
> +/**
> + * QUERY_SCHEDULER_STATUS: get proc/gang context array sizes
> + */
> +static int mes_v11_0_query_ctx_array_sizes(struct amdgpu_mes *mes)
> +{
> + struct amdgpu_device *adev = mes->adev;;
> + union MESAPI__QUERY_MES_STATUS mes_query_pkt;
> + int r;
> +
> + if (!mes->ctx_array_size_cpu_ptr)
> + return -EINVAL;
> +
> + /* Clear the output buffer */
> + mes->ctx_array_size_cpu_ptr[0] = 0; /* proc_ctx_array_size */
> + mes->ctx_array_size_cpu_ptr[1] = 0; /* gang_ctx_array_size */
> +
> + memset(&mes_query_pkt, 0, sizeof(mes_query_pkt));
> +
> + mes_query_pkt.header.type = MES_API_TYPE_SCHEDULER;
> + mes_query_pkt.header.opcode = MES_SCH_API_QUERY_SCHEDULER_STATUS;
> + mes_query_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
> +
> + mes_query_pkt.subopcode = MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE;
> +
> + /*
> + * MES FW will write the array sizes to these GPU addresses:
> + * proc_ctx_array_size_addr -> uint32_t N (e.g., 50)
> + * gang_ctx_array_size_addr -> uint32_t M (e.g., 300)
> + */
> + mes_query_pkt.ctx_array_size.proc_ctx_array_size_addr =
> + mes->ctx_array_size_gpu_addr;
> + mes_query_pkt.ctx_array_size.gang_ctx_array_size_addr =
> + mes->ctx_array_size_gpu_addr + sizeof(uint32_t);
> +
> + mes_query_pkt.api_status.api_completion_fence_addr =
> + mes->ring[0].fence_drv.gpu_addr;
> + mes_query_pkt.api_status.api_completion_fence_value =
> + ++mes->ring[0].fence_drv.sync_seq;
> +
> + r = mes_v11_0_submit_pkt_and_poll_completion(mes,
> + &mes_query_pkt, sizeof(mes_query_pkt),
> + offsetof(union MESAPI__QUERY_MES_STATUS, api_status));
> + if (r) {
> + dev_err(adev->dev,
> + "MES QUERY_SCHEDULER_STATUS (GET_CTX_ARRAY_SIZE)
> failed, r=%d\n", r);
> + return r;
> + }
> +
> + /* MES has written the sizes - now set up bitmaps */
> + return amdgpu_mes_rs64mem_setup_bitmaps(mes);
> +}
> +
> static int mes_v11_0_misc_op(struct amdgpu_mes *mes,
> struct mes_misc_op_input *input)
> {
> @@ -1907,10 +1959,33 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block
> *ip_block)
> if (r)
> goto failure;
>
> + /* Allocate GPU buffer for array size query results */
> + r = amdgpu_mes_rs64mem_init(&adev->mes);
> + if (r)
> + dev_warn(adev->dev,
> + "RS64 local memory init failed (%d), "
> + "falling back to system memory path\n", r);
> +
> r = mes_v11_0_set_hw_resources(&adev->mes);
> +
> if (r)
> goto failure;
>
> + /*
> + * QUERY_SCHEDULER_STATUS to get array sizes (N, M).
> + * MES writes the sizes to the GPU buffer, then we allocate bitmaps.
> + */
> + if (adev->mes.use_rs64mem) {
> + r = mes_v11_0_query_ctx_array_sizes(&adev->mes);
> + if (r) {
> + dev_warn(adev->dev,
> + "Failed to query ctx array sizes (%d), "
> + "disabling RS64 local memory\n", r);
> + /* Continue without optimization - not fatal */
> + }
> + }
> +
> +
> if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x52) {
> r = mes_v11_0_set_hw_resources_1(&adev->mes);
> if (r) {
> @@ -1948,6 +2023,10 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block
> *ip_block)
>
> static int mes_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
> {
> + struct amdgpu_device *adev = ip_block->adev;
> +
> + if (adev->mes.use_rs64mem)
> + amdgpu_mes_rs64mem_fini(&adev->mes);
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/amd/include/mes_v11_api_def.h
> b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
> index b06412ac8583..dfc27be4454d 100644
> --- a/drivers/gpu/drm/amd/include/mes_v11_api_def.h
> +++ b/drivers/gpu/drm/amd/include/mes_v11_api_def.h
> @@ -329,6 +329,7 @@ union MESAPI__ADD_QUEUE {
> uint32_t pipe_id;
> uint32_t queue_id;
> uint32_t alignment_mode_setting;
> + uint32_t full_sh_mem_config_data;
> uint64_t unmap_flag_addr;
> };
>
> @@ -358,6 +359,7 @@ union MESAPI__REMOVE_QUEUE {
> uint32_t tf_data;
>
> enum MES_QUEUE_TYPE queue_type;
> + uint64_t timestamp;
> };
>
> uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
> @@ -516,14 +518,57 @@ union MESAPI__SET_LOGGING_BUFFER {
> uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
> };
>
> -union MESAPI__QUERY_MES_STATUS {
> - struct {
> - union MES_API_HEADER header;
> - bool mes_healthy; /* 0 - not healthy, 1 -
> healthy */
> - struct MES_API_STATUS api_status;
> - };
> -
> - uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
> +enum MES_API_QUERY_MES_OPCODE
> +{
> + MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE,
> + MES_API_QUERY_MES__GET_CAPS = MES_API_QUERY_MES__GET_CTX_ARRAY_SIZE,
> + MES_API_QUERY_MES__CHECK_HEALTHY,
> + MES_API_QUERY_MES__MAX,
> +};
> +
> +enum { QUERY_MES_MAX_SIZE_IN_DWORDS = 20 };
> +
> +/**
> + * Obsolete
> + * to be removed once KMD stopped refering to it.
> + * use MES_API_QUERY_MES__CAPS instead
> +*/
> +struct MES_API_QUERY_MES__CTX_ARRAY_SIZE
> +{
> + uint64_t proc_ctx_array_size_addr;
> + uint64_t gang_ctx_array_size_addr;
> +};
> +
> +struct MES_API_QUERY_MES__HEALTHY_CHECK
> +{
> + uint64_t healthy_addr;
> +};
> +
> +struct MES_API_QUERY_MES__CAPS
> +{
> + uint64_t proc_ctx_array_size_addr;
> + uint64_t gang_ctx_array_size_addr;
> + uint64_t features_enablement_addr;
> +};
> +
> +union MESAPI__QUERY_MES_STATUS
> +{
> + struct
> + {
> + union MES_API_HEADER header;
> + enum MES_API_QUERY_MES_OPCODE subopcode;
> + struct MES_API_STATUS api_status;
> + uint64_t timestamp;
> + union
> + {
> + struct MES_API_QUERY_MES__CTX_ARRAY_SIZE ctx_array_size;
> + struct MES_API_QUERY_MES__CAPS caps;
> + struct MES_API_QUERY_MES__HEALTHY_CHECK healthy_check;
> + uint32_t data[QUERY_MES_MAX_SIZE_IN_DWORDS];
> + };
> + };
> +
> + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS];
> };
>
Presumably we need a firmware version check to determine when this is
available? What about mes 12?
Alex
> union MESAPI__PROGRAM_GDS {
> --
> 2.34.1
>