Repository navigation
drm/asahi: lock only the VM reservation for VM queries and VA updates - #521
Merged
RyanTheTide merged 2 commits intoOct 31, 2026
Merged
RyanTheTide merged 2 commits into
RyanTheTide merged 2 commits into
Conversation
Submit validation (covers_ranges_batch and friends), translate_offset, vm_context_mask, new_execution_context and capacity only read VmInner, but took the full GPUVM exec lock: the VM reservation plus every external BO's reservation. Each submit therefore cost O(external BOs). Under virtio-gpu every guest BO is external (libkrun maps blobs through dma-buf export), so a game with ~15k BOs spent 12-20 ms per submit in drm_gpuvm_prepare_objects and was capped at single-digit fps. Every page-table and mapping change already holds the VM reservation, so readers need only that lock; use GpuVm::lock_inner() for them. Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Assisted-by: LLM
Every map and unmap (user VM_BIND, kernel mappings such as each G17 submission's completion record, object teardown) took GpuVm::exec_lock(), i.e. drm_gpuvm_exec_lock(): the VM reservation plus the reservation of every external object. Under virtio-gpu every guest BO is external, so with ~15k BOs each bind and each submit spent around a millisecond in drm_gpuvm_prepare_objects(). This VM is IMMEDIATE_MODE and RESV_PROTECTED: VA updates need the VM reservation and each object's gpuva lock, which the link and unlink paths take themselves. Backing is pinned and its segments copied before any reservation is taken, no caller adds fences, and the driver already unmaps under the VM reservation alone on its low-memory path. Add GpuVm::exec_lock_vm(), which runs the drm_exec loop over the VM reservation (and an external obj, if given) without drm_gpuvm_prepare_objects(), and use it for all VA updates. Signed-off-by: Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com> Assisted-by: LLM
Contributor
|
Merged into integration/aurora. Hardware: passed on the M2, M1 Pro and Neo in the integration candidate (integration/aurora with this, #556 and the ISP recovery series), GPU compute and readback plus glmark2 clean and no new err-level lines. J616s on aurora-wip with the same three: 4 glmark2 runs around 7000 with a second client submitting a hanging dispatch alongside, no GPU faults, journalctl -k -p 3 empty, no WARN or DART faults. Thanks! |
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.
The asahi VM takes
GpuVm::exec_lock()(drm_gpuvm_exec_lock()) for read-only VM queries and for every map and unmap. That locks the VM reservation plus the reservation of every external object, so each call costs O(external objects).Under virtio-gpu (muvm/libkrun) every guest BO is external, because blobs are mapped through dma-buf export. With a game holding ~15k BOs, each submit spent 12-20 ms in
drm_gpuvm_prepare_objects()validating its ranges, and each bind about a millisecond more. CS2 under FEX/muvm was capped at single-digit fps by that alone.This VM is
IMMEDIATE_MODEandDRM_GPUVM_RESV_PROTECTED. VA updates need the VM reservation (extobj list, VM data) and each object's gpuva lock (which the link and unlink paths take). The driver never validates, adds fences through GPUVM, or callsdrm_gpuvm_bo_evict(), the paths that need an object's own reservation.covers_range*,translate_offset,vm_context_mask,new_execution_context,capacity) takeGpuVm::lock_inner(), the VM reservation alone. Every page-table and mapping change holds it, so readers see a consistent snapshot.map_in_range_with_mode,map_at,bind_object,map_io,unmap_range_commit,drop_mappings_now, the user bind batch) take the newGpuVm::exec_lock_vm(). It is thedrm_exec_until_all_locked()loop ofdrm_gpuvm_exec_lock()withoutdrm_gpuvm_prepare_objects(): the VM reservation, plusobjif it is external. Backing is pinned and its segments copied before any reservation is taken. The low-memory unmap path already ran under the VM reservation alone.Residency restoration and the other
lock_vm()users keep the full lock.Testing
J616s (T6040, 25G83). Both commits have been in our daily kernel since 2026-10-26, on integration
9cbdd0734d9and then5ca226e3c40(patch-identical; this branch is one3a9c0a58):drm_gpuvm_prepare_objects(). Without these commits the game was capped in single digits; with them the menu is GPU-bound (~22 fps at 1440p, the GPU queue busy 97% of the time).Not tested with lockdep enabled.
Assisted-by: LLM