Skip to content

drm/asahi: g17: stop withholding compute doorbells - #278

Merged
scottjones merged 1 commit into
integration/aurorafrom
mirror/g17-stop-withholding-compute-doorbells
Oct 31, 2026
Merged

scottjones merged 1 commit into
integration/aurorafrom
mirror/g17-stop-withholding-compute-doorbells

Conversation

@DjDeveloperr

Copy link
Copy Markdown
Collaborator

Mirror of aurora-silicon/linux#573 by @jgoyvaerts, merged there as 9db30ff.

This removes the G17 compute-doorbell withholding (1a3fd7f and its five follow-ups). A withheld doorbell is only rung by the compute scan of a later event pass, and nothing guarantees one comes. When none does, the firmware sits idle on a command it was never told about. Every waiter on that command stalls, and the GPU stalls as a whole, until unrelated firmware traffic runs the scan. On a J616s it showed as 330–400 ms GPU-wide freezes under DXVK in a muvm guest, about ten a minute. The full analysis is in the original PR.

The cherry-pick (-x) needed one conflict resolved: aurora's recovery.rs has a KUnit stub for announce_withheld that this tree doesn't, so that hunk was dropped. The reverted commits are named by their omacom hashes.

Testing:

  • On this tree: KUnit asahi* under QEMU arm64, 136/136 passed; it builds with no new warnings.
  • On J700 (Neo), on the aurora side (drm/asahi: g17: stop withholding compute doorbells aurora-silicon/linux#573, same change): regression gate PASS; targeted CTS 4687/0 failures; CTS synchronization 28647/0 and synchronization2 36516/0; gpubench-stress --all with no stalls or timeouts (its only failures are the known teardown log lines); queue.depth pass.

The stall reproduces on J700 (Neo). A tool that times every GPU compute wait found 14–17 ms waits on multi-command submits (fill + clear-only render pass + fill, like DXVK), about 1 in 10,000 bursts, with withholding. With this change the worst wait is under 2 ms, and median waits move by only +0.5–2.4%. On the Neo some ~60 Hz event rescues the lost wakeup within one frame; on the J616s nothing did for 330–400 ms.

A compute publication with two or more unretired commands of its queue
ahead of it withholds its doorbell. Only the compute scan of a later
event pass rings it, once at most one command ahead lacks a completion
record. Nothing guarantees that such a pass comes: if the last event
pass for the commands ahead runs before that condition holds, the
firmware sits idle on a command it was never told about, and every
waiter on that command stalls until an unrelated firmware message runs
the scan.

Under a Vulkan game in a muvm guest (DXVK on Honeykrisp, which runs
buffer copies as compute) this shows up as GPU-wide stalls of 330 to
400 ms, about ten a minute under steady input. Probes on the GPU mailbox
show the firmware sending nothing for the whole stall. Each one opens
right after a compute publication and ends when the compute scan rings
a withheld compute doorbell, after which the queued work runs at once.
The compositor's own frames stall with it.

The follow-up commits closed some of the ways into this state (job
timeouts, recovery, a record waiting for its stamp) but not the lost
wakeup itself. Remove the withholding and everything built on it, so
that every compute publication rings its doorbell again. This gives
back the few microseconds per hop the withholding saved in a
cross-queue semaphore ping-pong.

This reverts:
  1a3fd7f ("drm/asahi: withhold G17 compute doorbells behind two unretired commands")
  26ee6b9 ("drm/asahi: drop G17 compute doorbells that another doorbell announced")
  118c3b4 ("drm/asahi: announce withheld G17 compute doorbells whenever retirement stalls")
  045f59c ("drm/asahi: announce withheld G17 compute doorbells after a recovery")
  fbb7695 ("drm/asahi: keep withholding G17 compute doorbells while a stamp is awaited")
  1e11df2 ("drm/asahi: restart a withheld G17 compute doorbell another doorbell covered")

Fixes: 1a3fd7f ("drm/asahi: withhold G17 compute doorbells behind two unretired commands")
Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com>
Assisted-by: LLM
(cherry picked from commit f5ca23b)

@scottjones scottjones left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We read this against the six commits it reverts and against the tree merged with #275 and #264, and it looks correct to us: the withholding code is fully gone, nothing in those PRs relied on it, and the mirror of f5ca23b is faithful. It only touches G17.

We're building a kernel with this plus #275, #276, #264 and #277 and will run it on our Neo (queue.depth, the stress suite and the synchronization CTS), since this exact form hasn't been on hardware yet. We'll report back here before approving.

@scottjones scottjones left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We read this against the six commits it reverts (all six are ancestors of integration/aurora) and against the tree merged with #275 and #264. We read source only. We then ran it only as part of the Neo stack run described below.

It does what it says. Every publication rings at g17/queue/compute.rs:2285, after the same SeqCst fence as before. withheld, due_doorbell, notify_compute, compute_written and compute_announced are gone from drivers/gpu/drm/asahi, on this head and in the merged tree. timeout_compute, cancel_compute and recovery's service() only lose the step that rang what was withheld, and now there's nothing withheld to ring. The fields settling() read all keep other users. We found nothing in #275 or #264 that relied on the removed code.

The mirror is faithful. Against f5ca23b the only hunk that differs is the dropped announce_withheld KUnit stub, which this tree doesn't have, as the body says. The other differences are context lines (demand in Port, report_blamed_render). The six reverted hashes are the right omacom ones.

Scope is g17 only, so T8140 and T6040. g15, m3 and the legacy paths don't use port.rs, queue/compute.rs or the g17 runtime, and mmu.rs isn't touched.

Two things to note:

  • The Neo numbers came from aurora with AsahiLinux#570, AsahiLinux#571 and AsahiLinux#572 underneath (aeae3d9), and the J616s result from that team's daily kernel. This tree has none of those three yet, so aurora's numbers aren't from this form; ours below are, with four other PRs. Since it restores the doorbell behaviour from before 10-25, we don't think that should hold it.
  • This should land before #277. #277 makes a stamp wait for its node to drain, and a withheld doorbell can keep a node from draining. The aurora thread also saw a signal_order case killed by the 30 s watchdog on AsahiLinux#570 to AsahiLinux#572 without this change. It was one run, but the mechanism fits.

Small one, not blocking: the cherry-pick has no Signed-off-by from its committer, unlike #264's. Worth adding if the branch gets touched again.

We ran the stack on a Neo through a lab job: integration/aurora 1358ab0 plus #278, #275, #276, #264, #277 (our build, clang 22, not the release toolchain), mesa-aurora 20261029 (672657e05e), gpubench db3fec6. CTS synchronization 28647 pass and synchronization2 36516 pass, 0 fail, every case reporting a result. No ETIMEDOUT, GPU recovery or lost device, and no stampless retirement, in the kernel log of the whole run. Nothing in that run points at this change. We then ran queue.depth (5 times) and sparse.churn (3 times) at 60 s each, on the same Neo and the same private Honeykrisp with omacom/mesa#20 (18ff4cdc9a), once on the stack and once on the kernel without it (7.2.11-10-1). Stack: queue.depth passed 5 of 5, about 810k-880k completions in the deep 128+64 phase per run (roughly 35k/s) with 0 errors and a worst latency of 45 ms; sparse.churn passed 3 of 3; no flagged kernel line. Without the stack: queue.depth lost the device in run 1 after 6.4 s (ETIMEDOUT at g17/runtime.rs:1291). Run 2, started right after on the same GPU, failed at 2.3 s with 0 checks, so it is the same failure and not a second sample. Then "GPU runtime stopped, device lost", and every later client got ENODEV until reboot. That's one job each on one Neo, with our clang 22 build rather than the release toolchain. It tests the five PRs together, so it doesn't separate them, and #278, #275 and #276 without #264 and #277 hasn't run anywhere on this tree. The other kernel is the 7.2.11-10-1 release, 88 commits behind 1358ab0; its only g17 difference is a logging commit. Throughput fell across the five runs (deep 880k to 811k, mixed 73k to 65k), which may be thermal on a fanless Mac. That failing run also logged an RTKit "failed buffer request for 0x2000 bytes (-22)" that the stack run didn't, and we don't know whether it matters. It says nothing about T6040.

It's a pure removal, it fixes a real lost wakeup, CI is green, and it fits the RC. We'd merge it first of the G17 stack.

@scottjones

Copy link
Copy Markdown
Collaborator

Update on the line above that says this set hadn't run alone: it has now. We ran #278, #275 and #276 without #264 and #277 on a Neo, on integration/aurora 2dd4aab (our build, clang 22), with the private omacom/mesa#20 driver: queue.depth 5 of 5 at 60 s, sparse.churn 3 of 3, and no ETIMEDOUT, GPU recovery, lost device or stampless retirement in the kernel log. One job on one Mac, and no CTS on this set.

@scottjones
scottjones added this pull request to the merge queue Oct 31, 2026
Merged via the queue into integration/aurora with commit add690d Oct 31, 2026
14 checks passed
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.

3 participants