This series is a follow up to the earlier drm_gpusvm_pages decoupling
series [1], and follows the direction Matt suggested [2].
drm_gpusvm_get_pages() does two things at once: the MM level HMM fault
of the CPU range, and the device DMA mapping of the faulted pages. When
one CPU range is mirrored on several devices, every device has to call
get_pages() and redo the HMM fault. Matt suggested [2] passing an array
of drm_gpusvm_pages plus a count so the fault is taken once and shared,
while the notifier retry loop stays in common code so drivers never open
code it.
The series builds up to that in small steps, no functional change until
the last two patches:
- patch 1 moves the dma_addr allocation out of the notifier locked
section, so the mapping step becomes self contained.
- patch 2 pulls the per-device mapping loop into
drm_gpusvm_dma_map_pages(). Code motion only.
- patch 3 makes get_pages() take an array of drm_gpusvm_pages plus a
count: fault once, then DMA map each instance, one per owning
drm_device, under a single notifier retry gate. Instances that are
already mapped are skipped, so an -EAGAIN retry does not redo them.
The common 1:1 case passes count == 1 and is unchanged.
- patch 4 adds a no_dma_map context flag so a driver that only needs
the CPU pages faulted in can skip the device DMA mapping.
Patch 4 has no in-tree user yet, AMDXDNA is the intended consumer but
that conversion is not ready. It is independent of patches 1-3, happy to
drop it and repost it together with its user.
v2:
- Rebased on drm-tip. Matt asked for Stanislav's
hmm_range_fault_unlocked_timeout() patch [3] to be carried at the
base of this series, it has since landed in drm-tip, so this version
is just rebased on top of it.
- Dropped v1 patch 1 ("drm/gpusvm: extract drm_gpusvm_hmm_fault()
helper"), it is part of [3] now.
- patch 3: drm_gpusvm_pages_valid_unlocked() takes the array and the
count itself, instead of get_pages() open coding an all_valid loop.
- patch 3: fixed the N:1 doc example, it used the wrong union member
when the count is 1. Added a driver_pages() accessor.
- patch 3: documented that on error the instances mapped before the
failing one stay mapped, the caller must unmap and free all of them.
- patch 4: reject no_dma_map together with devmem_only, without the
DMA mapping step there is no page type check to enforce it.
- patch 4: documented that no_dma_map only returns a snapshot, the
caller must recheck mmu_interval_read_retry() itself.
tests:
AMDGPU:
SVM:DRM N:1 multi device support is work in progress on top of this
series. The single device (1:1) path was tested with the amdgpu SVM
adaptation on top. Based on amdgpu SVM [4].
Tested on gfx943 (MI300X) and gfx906 (MI60) with XNACK on/off:
- KFD test: SVM all passed except the get attr refactor.
- ROCR test: all passed.
- HIP catch test: gfx943 (MI300X): 99% passed.
gfx906 (MI60): 99% passed.
links:
[1] drm_gpusvm_pages decoupling series:
https://lore.kernel.org/amd-gfx/[email protected]/
[2] Matt's suggested direction:
https://lore.kernel.org/amd-gfx/[email protected]/
[3] drm/gpusvm: use hmm_range_fault_unlocked_timeout() for range faults:
https://lore.kernel.org/[email protected]
[4] amdgpu SVM:
https://lore.kernel.org/amd-gfx/[email protected]/
Honglei Huang (4):
drm/gpusvm: move dma_addr allocation before the notifier lock
drm/gpusvm: extract drm_gpusvm_dma_map_pages() helper
drm/gpusvm: let drm_gpusvm_get_pages() map an array of pages
drm/gpusvm: make the DMA mapping step in get_pages() optional
drivers/gpu/drm/drm_gpusvm.c | 336 +++++++++++++++++++++-----------
drivers/gpu/drm/xe/xe_svm.c | 2 +-
drivers/gpu/drm/xe/xe_userptr.c | 2 +-
include/drm/drm_gpusvm.h | 10 +
4 files changed, 239 insertions(+), 111 deletions(-)
base-commit: c8420bcb1802510e5411ea4c98e2e07bdb43d74e
--
2.34.1