Repository navigation
drm/asahi: g17: five small fixes (soft faults, recovery blame, torn snapshots, signalled fences, HIGH priority) - #391
Merged
RyanTheTide merged 5 commits intoOct 23, 2026
Conversation
DRM_ASAHI_FEATURE_SOFT_FAULTS was set whenever the fault_control module parameter kept its default, but the G17 runtime never programs fault_control into the firmware, so unmapped GPU reads are not guaranteed to return zero. Mesa trusts the bit: it points out-of-bounds vec3/vec4 vertex fetches at address 0 and skips the bounds check on bounded constant loads. On the M4 Pro those reads returned non-zero data and every robustness2 rgba32 vertex_attribute_fetch case failed; they pass with soft faults disabled in Mesa. Ask the GPU backend instead; G17 reports none. Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Assisted-by: LLM
poll() knows that individually sampled cursor words can straddle a firmware update: an implausible snapshot gets one immediate reread, and a second implausible one is only a retry. poll_observed(), which finishes a snapshot taken while the pair was borrowed, returned the plausibility check's EIO directly, so one torn sample quarantined the pair and the client saw a lost device. Under load (a Vulkan conformance run beside the desktop) this failed innocent clients, the compositor's full-screen composite among them, with no GPU fault and no recovery. Fall back to poll() when the borrowed snapshot does not pass. Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Assisted-by: LLM
GPU recovery classifies guilt from the firmware's recovery table and its blamed QID, and attribution can move that blame: a blamed render that had not started while other renders had (or with no culprit at all) is innocent. service() still failed the blamed render's oldest packet with EIO. On the M4 Pro the firmware blamed the compositor's not-yet-started full-screen render while a Vulkan test faulted in another process: the compositor saw a lost device and aborted, taking the session down. classify() now also returns whether the blamed QID is still guilty after attribution; only then is its render failed. Otherwise its work is spared like every other innocent VM's. Log each recovery's reason, blamed queue and decision. Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Assisted-by: LLM
Almost every desktop render carries input fences, nearly all of them buffer fences that signalled long before the submit. Each one still became a scheduler dependency, so the render went through the drm_sched worker instead of inline publication: 0.25-0.5 ms before the GPU started, against about 0.07 ms for the submit ioctl itself. A fence that signalled without error orders nothing and has no error left to consume, exactly like the completed frontier producers the loop already skips. Skip it; a pending or failed input is kept and checked as before. Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Assisted-by: LLM
queue_create refused DRM_ASAHI_PRIORITY_HIGH with EINVAL (a TODO to allow it with CAP_SYS_NICE), and the G17 scheduling table had no HIGH profile. Mesa works around it: the GL driver advertises HIGH context priority but creates a MEDIUM queue, and the Vulkan driver refuses HIGH global priority until the kernel accepts it. Allow HIGH for callers with CAP_SYS_NICE or the DRM master, as amdgpu and panthor do for raised queue priority, and refuse it with EACCES otherwise so userspace can fall back. REALTIME stays reserved. Add drm::File::is_current_master() for the check. On G17 HIGH maps to firmware priority class 1, the class the G13 tables use for HIGH, with the policy word of the user classes; its work rings are already set up at boot. The check is in the common queue_create, so the G13 and G14 SoCs accept HIGH too and submit it on their existing priority-1 pipes. That is untested there. Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Assisted-by: LLM
This was referenced Oct 23, 2026
Closed
Closed
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.
Five small G17 fixes that are not specific to any SoC. We found them running the M4 Pro (T6040, 25G83 firmware) on the G17 backend in our own tree; none of them touches T6040 code, and they apply to the T8140 path as it is on integration/aurora.
DRM_ASAHI_FEATURE_SOFT_FAULTSwas set whenever thefault_controlparameter kept its default, but the G17 runtime never programsfault_controlinto the firmware (only the G13/G14 init data does). Mesa trusts the bit: it points out-of-bounds vec3/vec4 vertex fetches at address 0 and skips bounds checks on bounded constant loads. On the M4 Pro those reads returned non-zero data, and every robustness2 rgba32vertex_attribute_fetchcase failed. A newGpu::supports_soft_faults()keeps the old answer for G13/G14; G17 says no.poll()already gives a snapshot that straddles a firmware cursor update one reread and then a retry.poll_observed(), which finishes a snapshot taken while the pair was borrowed, returned the EIO directly, so one torn sample quarantined the pair and the client saw a lost device. It now falls back topoll(), which takes a fresh snapshot.service()still failed the blamed render's oldest packet with EIO. On the M4 Pro the firmware blamed the compositor's not-yet-started full-screen render while a Vulkan test faulted in another process; the compositor aborted and took the session down.classify()now also returns whether the blamed QID is still guilty, and only then is its render failed. Where ownership is unknown, the old behaviour stays. Each recovery logs its reason, blamed queue and decision.drm::File::is_current_master(). Today Mesa's GL driver advertises HIGH but creates MEDIUM, and the Vulkan driver refuses HIGH; both can follow once this is in.Hardware tested on: Apple MacBook Pro (16-inch, M4 Pro, 2024), J616s / T6040, 25G83 GPU firmware, on our daily tree, which runs the T6040 on this G17 backend (that support is not part of this PR). All five commits have been in our daily kernel since 2026-10-19/20, and on Linux 7.3 (integration/aurora ed55042 plus our series) since 2026-10-22.
How tested:
vertex_attribute_fetchcases failed with the bit set and pass with soft faults off.Not tested / limits:
queue_create, so G13/G14 accept HIGH too and use their existing priority-1 pipes.classify(): the recovery attribution path has none today, and I can't run KUnit here.Relation to other PRs: based on integration/aurora (1fb1fa9), which includes #377. Merges cleanly with #390 (checked with
git merge-treeagainst its head 8744e94). Our T6040 GPU support itself is not in this PR; it waits for #367.Build and checks: W=1 build of drivers/gpu/drm/asahi with
defconfig+asahi.config(LLVM=1): no new warnings (the sixfetch_updatedeprecation notices are in the base).checkpatch --strict: clean except one 117-column line, the existingclassify()signature, which only changes its return type and stays in the file's style. rustfmt leaves the changed g17 files' formatting as in the base.🤖 Generated with Claude Code