Since the seq64 mapping of a VM only gets its page tables updated by the
CS ioctl, a process which only uses user queues never has its seq64
memory mapped. USERQ_WAIT hands out the seq64 address of user queue
fences for the GPU to wait on, so a queue waiting for an earlier job
faults on it and hangs.
A GFX user queue waiting with FENCE_WAIT_MULTI for the
already signaled fence of its previous job (va 0xffffffffffc00000 from
USERQ_WAIT) never gets past the wait:
amdgpu 0000:03:00.0: [gfxhub] page fault (src_id:0 ring:24 vmid:8 pasid:13)
amdgpu 0000:03:00.0: Faulty UTCL2 client ID: CPG (0x6)
Update the seq64 mapping where the user queues get their VM restored,
which also happens before the first queue of a file is mapped, once the
page tables are validated again, and wait for it like for the other
page table updates. Only do it when the PTEs aren't there yet or were
cleared, so that restoring after every eviction doesn't write them again.
Fixes: ae05e3f3d02b ("drm/amdgpu: move amdgpu_vm_bo_update() call into correct
location")
Signed-off-by: Jesse Zhang <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 4dca1ab48410..94b9e6890f91 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -1070,6 +1070,12 @@ amdgpu_userq_vm_validate_and_restore_queue(struct
amdgpu_userq_mgr *uq_mgr)
if (unlikely(ret))
goto unlock_all;
+ /* The pinned seq64 BO only needs a slot for the rearm */
+ ret = drm_exec_prepare_obj(&exec, &adev->seq64.sbo->tbo.base,
1);
+ drm_exec_retry_on_contention(&exec);
+ if (unlikely(ret))
+ goto unlock_all;
+
/* This validates PDs, PTs and per VM BOs */
ret = amdgpu_vm_validate(adev, vm, NULL,
amdgpu_userq_validate_vm,
@@ -1140,6 +1146,18 @@ amdgpu_userq_vm_validate_and_restore_queue(struct
amdgpu_userq_mgr *uq_mgr)
if (ret)
goto unlock_all;
+ /*
+ * The seq64 mapping is kept up to date by the CS path only, but the
+ * queues wait for user queue fences through their seq64 address. Its
+ * PTEs only need writing when they aren't there yet or were cleared,
+ * e.g. by amdgpu_vm_handle_moved() after a VRAM loss.
+ */
+ if (!list_empty(&fpriv->seq64_va->invalids) ||
fpriv->seq64_va->cleared) {
+ ret = amdgpu_vm_bo_update(adev, fpriv->seq64_va, false);
+ if (ret)
+ goto unlock_all;
+ }
+
key = 0;
/* Validate User Ptr BOs */
list_for_each_entry(bo_va, &vm->always_valid.idle, base.vm_status) {
@@ -1203,6 +1221,7 @@ amdgpu_userq_vm_validate_and_restore_queue(struct
amdgpu_userq_mgr *uq_mgr)
* it explicitly (as the CS path syncs it) before restarting queues.
*/
dma_fence_wait(fpriv->prt_va->last_pt_update, false);
+ dma_fence_wait(fpriv->seq64_va->last_pt_update, false);
dma_fence_wait(vm->last_update, false);
xa_for_each(&uq_mgr->userq_xa, tmp_key, queue) {
--
2.50.1