Skip to content

drm/asahi: g17: fix the 25G83 tiler growth hang - #518

Merged
RyanTheTide merged 2 commits into
aurora-silicon:integration/aurorafrom
jgoyvaerts:g17-25g83-growth-hang
Oct 28, 2026
Merged

RyanTheTide merged 2 commits into
aurora-silicon:integration/aurorafrom
jgoyvaerts:g17-25g83-growth-hang

Conversation

@jgoyvaerts

Copy link
Copy Markdown
Contributor

On the M4 Pro firmware (25G83), an ordinary render pass that outgrows its tiler heap hangs the render queue: the firmware's forward-progress watchdog fails it (recovery reason 0). Two things on the out-of-memory path differ from macOS. This series makes both match:

  1. fragment_busy (TA+0x7a4). 25G83 reads it only in its out-of-memory lane. When it is non-zero, the lane resumes the stopped tiling pass without adding memory and the tiler stops silently. macOS always writes 0. Adds Variant::fragment_busy, cleared for V25G83.
  2. FragmentBarrier (tag 4). 0d9efa5 (mine) led every 25G83 fragment descriptor with it. macOS never sends it, and it deadlocks a partial render against its own tiling pass. Removed; InitBufferManager stays.

V26A428 (A18 Pro) is unchanged: it has no lead commands and keeps fragment_busy as before.

Supersedes #460

#460 pre-sized the tiler heap to 256 blocks on 25G83 to avoid growth. With growth fixed it is no longer needed, and this series leaves the heap at its normal tile-count size. I'll close #460.

Testing

J616s (T6040, 25G83). Tree = integration 9cbdd07 + this series, plus our board/display enablement and two VM-reservation locking patches (no changes to the render, publication or growth code). Tiler heap at its tile-count size, so heavy ordinary passes must grow.

  • dEQP-VK.memory.pipeline_barrier.graphics.all_device.1048576_vertex_buffer_stride_2, 3 runs: 0 firmware recoveries (7 before the series and 4 with patch 1 alone, measured on our earlier tree)
  • vk-default 1/2000 slice: 769 pass / 0 fail / 0 crash
  • Desktop compositor and GL clients render as before.
  • Each commit builds on integration with no new warnings; KUnit (asahi): 147/147 pass.

Rebased onto integration 5ca226e with no conflicts; patches unchanged. The overnight G17 merges (#494-#513) change submission, retirement and teardown, not the growth path. Build and KUnit rerun on the new base.

Evidence

The firmware behaviour is from a static disassembly of the 25G83 firmware and the macOS AGXG16X kext: the item tags macOS stores per fragment submission (1, 0xc, 0xe, 0xf, 0x10; never 4), the out-of-memory lane's reads of TA+0x7a4, and the tag-4 handler that holds the item ring until the tiling stamp. Happy to share the notes.

@RyanTheTide could you give it a run on your J616s? Neo shouldn't see any change.

Assisted-by: LLM

The 25G83 firmware reads the tiling descriptor's fragment_busy word
(TA+0x7a4) only in its out-of-memory lane, at the first out-of-memory
stop of a pass. When it is non-zero the firmware compares the pass-seq
byte of the last completed fragment kick on that queue with the lane's
copy of TA+0x7b0. On a mismatch it resumes the stopped TA with the
resume-after-grow register write but without adding memory, and retires
the lane: the tiler then stops silently with no further out-of-memory
stop and no completion, and the forward-progress watchdog fires
(reason 0).

We set fragment_busy whenever the previous fragment kick had not
completed at publish, which is common in a pipelined stream. macOS
always writes 0 there on this firmware. Add Variant::fragment_busy and
clear it for V25G83, so the out-of-memory lane takes the path macOS
takes. Renders that fit their tiler heap never reach that lane, so they
are unaffected. V26A428 keeps its current behaviour.

The firmware behaviour above is from a static disassembly of the 25G83
firmware and the macOS AGXG16X kext.

In our testing on a J616s (T6040, 25G83), with the tiler heap at its
tile-count size so ordinary heavy passes must grow, this alone took
dEQP-VK.memory.pipeline_barrier.graphics.all_device.1048576_vertex_buffer_stride_2
from 7 firmware recoveries over three runs to 4; the next change
removes the rest.

Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com>
Assisted-by: LLM
Commit 0d9efa5 ("drm/asahi: g17: render lead commands for the 25G83
firmware") led every 25G83 fragment descriptor with a FragmentBarrier
(tag 4) that waits for the paired tiling stamp. macOS does not send
that item: its fragment submission stores item tags 1, 0xc, 0xe, 0xf
and 0x10 only, and keeps fragment-after-tiling ordering in the kick
entry's dependency 0, which we already set.

The barrier deadlocks a pass that runs out of tiler memory. The
firmware's item-ring loop stops at an item whose handler returns 0, and
the tag-4 handler returns 0 until the tiling stamp is reached, so the
fragment kick's AddKicks is only processed after its tiling pass
completes. A partial render needs that fragment kick announced while
the tiling pass is stopped (the firmware releases it in out-of-memory
state 7 by clearing the kick entry's dependency 0), so the tiling pass
waits for the partial render and the partial render waits for the
tiling pass.

Remove FragmentBarrier and write only InitBufferManager as a lead
command. V26A428 has no lead commands and is unaffected.

The firmware behaviour above is from a static disassembly of the 25G83
firmware and the macOS AGXG16X kext.

On a J616s (T6040, 25G83), with the tiler heap left at its tile-count
size so ordinary heavy passes must grow, this and the previous change
take dEQP-VK.memory.pipeline_barrier.graphics.all_device.1048576_vertex_buffer_stride_2
from 7 firmware recoveries over three runs to none. A 1/2000
vk-default slice is 769 pass / 0 fail / 0 crash, and the desktop and
GL clients render as before.

Fixes: 0d9efa5 ("drm/asahi: g17: render lead commands for the 25G83 firmware")
Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com>
Assisted-by: LLM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants