On gfx12, concurrent dispatch from multiple AQL compute user queues in one
process can intermittently stall one queue's first dispatch: its completion
never signals, while queue creation succeeds and no obvious dmesg error is
reported.

With unmapped-doorbell mode 1 (basic), a doorbell hit only sets a coarse
level-wide hasReadyQueues flag. Queue-level selection can still be filtered by
work_done/is_queue_ready, so under concurrency the ringing queue may be
skipped and its new dispatch not fetched in time.

Switch mes12 to mode 2 (basic+). In this mode, MES consumes per-queue
CP_UNMAPPED_QUEUE bitmaps, identifies the ringing queue, and clears that
queue's work_done in the unmapped-doorbell path so it is reconsidered
promptly by scheduling.

Tested on the amd-unified-interface branch on gfx1201: multiple
concurrent AQL compute queues now pass repeatedly.

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

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index 04465804c254..5f9e28f8f007 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -990,10 +990,21 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes 
*mes, int pipe)
        /*
         * Keep oversubscribe timer for sdma . When we have unmapped doorbell
         * handling support, other queue will not use the oversubscribe timer.
-        * handling  mode - 0: disabled; 1: basic version; 2: basic+ version
+        * 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 to identify exactly which queue(s)
+        * rang and clears their work_done so the scheduler re-maps them. The
+        * basic (1) mode only sets a coarse level-wide "ready" flag without
+        * clearing the ringing queue's work_done, so a concurrent AQL compute
+        * queue whose doorbell rings after work_done was set gets skipped by 
the
+        * scheduler and its dispatch is silently lost (intermittent hang with
+        * multiple concurrent queues). basic++ (3) additionally map_gang()s in
+        * the interrupt handler for lower latency, but basic+ is sufficient and
+        * touches less state.
         */
        mes_set_hw_res_pkt.oversubscription_timer = mes_rev < 0x8b ? 0 : 50;
-       mes_set_hw_res_pkt.unmapped_doorbell_handling = 1;
+       mes_set_hw_res_pkt.unmapped_doorbell_handling = 2;
 
        if (amdgpu_mes_log_enable) {
                mes_set_hw_res_pkt.enable_mes_event_int_logging = 1;
-- 
2.49.0

Reply via email to