RE: [PATCH v2] drm/amdgpu/mes12: fix dropped dispatches under queue oversubscription

"Liu, Shaoyun" <[email protected]> Tue, 4 Aug 2026 16:09:10 +0000
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <SN7PR12MB78563D0DF1F03F847EF8AF97F4D42@SN7PR12MB7856.namprd12.prod.outlook.com>
AMD General

Looks good to me .
Please add me as RB .

Shaoyun.liu

-----Original Message-----
From: amd-gfx <[email protected]> On Behalf Of Jesse Zh=
ang
Sent: Tuesday, August 4, 2026 3:24 AM
To: [email protected]
Cc: Deucher, Alexander <[email protected]>; Koenig, Christian <Chri=
[email protected]>; Liu, Shaoyun <[email protected]>; Chen, Michael <M=
[email protected]>; Zhang, Jesse(Jie) <[email protected]>
Subject: [PATCH v2] drm/amdgpu/mes12: fix dropped dispatches under queue ov=
ersubscription

On gfx12, when more queues are ready than there are HQD slots (oversubscrip=
tion), MES keeps queues unmapped and maps a queue to an HQD on demand when =
its doorbell rings; a queue is only refetched once its per-queue work_done =
is cleared.

Historically oversubscription was handled via the aggregated doorbell, but =
that is a shared level-wide signal: MES cannot tell which queue rang and ne=
ver clears a queue's work_done, so it relies on the coarse oversubscription=
 timer to rescan. gfx12 therefore drives GFX/compute through the per-queue =
unmapped-doorbell path instead (the aggregated doorbell now only serves SDM=
A), which can pinpoint the ringing queue and lets MES stay idle otherwise.

But with unmapped-doorbell mode 1 (basic) a ring only sets a coarse level-w=
ide ready flag and does not read the per-queue bitmap or clear the ringing =
queue's work_done. A queue still marked done from a prior dispatch is skipp=
ed and its new work is never fetched: the completion never signals, while q=
ueue creation succeeds and no dmesg error is reported.

Switch to mode 2 (basic+): MES reads the per-queue CP_UNMAPPED_QUEUE bitmap=
, identifies which queue rang, and clears its work_done so it is reschedule=
d promptly. This affects every queue MES schedules on gfx12 (KFD and DRM us=
er queues), which share the one MES instance and this global setting.

Tested on gfx1201: concurrent multi-queue dispatch that intermittently stal=
led under mode 1 now passes on both the KFD and DRM userq paths.

v2: update commit message: describe the oversubscription case, why the
    aggregated doorbell is not used for GFX/compute on gfx12, and why
    basic+ (not basic) is required.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/a=
mdgpu/mes_v12_0.c
index 8d1d1bf9091c..cda83e6533cd 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -1015,10 +1015,16 @@ static int mes_v12_0_set_hw_resources(struct amdgpu=
_mes *mes, int pipe)
        /*
         * Keep oversubscribe timer for sdma . When we have unmapped doorbe=
ll
         * handling support, other queue will not use the oversubscribe tim=
er.
-        * handling  mode - 0: disabled; 1: basic version; 2: basic+ versio=
n
+        * handling  mode - 0: disabled; 1: basic; 2: basic+; 3: basic++
+        *
+        * Use basic+ (2): on an unmapped-queue doorbell ring MES reads the
+        * per-queue CP_UNMAPPED_QUEUE bitmap and clears the ringing queue'=
s
+        * work_done so it is rescheduled. basic (1) only sets a coarse
+        * level-wide ready flag without clearing work_done, so a queue tha=
t
+        * rings after work_done was set is skipped and its work is lost.
         */
        mes_set_hw_res_pkt.oversubscription_timer =3D mes_rev < 0x8b ? 0 : =
50;
-       mes_set_hw_res_pkt.unmapped_doorbell_handling =3D 1;
+       mes_set_hw_res_pkt.unmapped_doorbell_handling =3D 2;

        if (amdgpu_mes_log_enable) {
                mes_set_hw_res_pkt.enable_mes_event_int_logging =3D 1;
--
2.49.0