Repository navigation
drm/asahi: skip G17 event-pass housekeeping for completion records alone - #494
Merged
Merged
Conversation
Every completion notification queues an event pass, and every pass ran the full housekeeping after retiring the records: render linger expiry, drained-pair reclaim, compute exit settlement, compute pool recycling and vacating, evicted render pool vacating, heap shrinking and teardown. Each of these scans every compute queue, render entry or pool, so with around 40000 passes a second in light rows the scans took a large part of the event worker's time on the IRQ CPU, while retiring a completion and signalling its fence needs none of them. Run that housekeeping only when a pass is requested through queue_events(), on recovery, while a teardown is pending, while anything waits for channels, progress, queue slots or render capacity, when no work remains in flight, and at the latest on the first pass 1 ms after the last full one. The firmware's event notification, records that arrive during a pass and render events missed while a pair was on loan queue a pass for the records alone. Every other caller keeps getting a full pass. Measured on Neo in the same boot against every pass running the housekeeping, alternating, four rounds (medians): event pass, sync.signal + render.light procs 8.2 -> 6.2 us event worker share of CPU0, all rows 24.9% -> 20.8% compute.light procs d2 36.80 -> 34.81 us compute.light queues d2 36.76 -> 34.96 us submit.empty queue d2 1.78 -> 1.69 us compute.light queue d1/d2/d64, queues d4, render.light d1/d32 and queues d4/d8, render.light procs d2, sync.signal binary/timeline, concurrent.cr and the cross-queue pair stay within 2%.
DjDeveloperr
changed the base branch from
perf/g17-doorbell-tail-20261026
to
integration/aurora
October 27, 2026 05:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #468 (the base is its branch, so only this commit shows). It retargets to integration/aurora when #468 merges.
Summary
Every completion notification queues a G17 event pass. Every pass ran the full housekeeping after retiring its records:
Each of these scans every compute queue, render entry or pool. Light rows run about 40,000 passes a second, so the scans took a large part of the event worker's time on the IRQ CPU, and with AIC2 routing that is always CPU 0. Retiring a completion and signalling its fence needs none of them.
The housekeeping now runs only when one of these holds:
queue_events();Three paths queue a pass for the records alone: the firmware's event notification, records that arrive during a pass, and render events missed while a pair was on loan. Every other caller still gets a full pass. Retirement, fence signalling, replay, render observation, the polling scan and render-waiter notification still run on every pass, and so do the firmware trace and statistics ring drains.
I also tried moving the event work off the IRQ CPU: an unbound high-priority workqueue, the submitter's CPU, or the other P-core. Every option was slower, by up to +86% on compute d2 and the hop rows, because of the cross-CPU wakeup and the slower E-cores. So the work stays where it is, and this cuts its cost instead.
Measurements
Neo, same boot, against every pass running the housekeeping. Alternating, four rounds, medians:
compute.light queue d1/d2/d64 and queues d4, render.light d1/d32 and queues d4/d8, render.light procs d2, sync.signal binary/timeline, concurrent.cr and the cross-queue pair all stay within 2%.
Testing
Exit settlement and pool recycling under live traffic can now wait up to 1 ms. Recovery and pending teardowns always get full passes.