The user queue UAPI permits the WPTR at any 8-byte aligned offset within a BO. amdgpu_userq_fence_read_wptr() locates the mapping containing the WPTR address, but amdgpu_bo_kmap() returns the start of the BO, so the code read the first u64 regardless of the WPTR offset. USERQ_SIGNAL uses this value as the exported fence seqno, so a wrong read makes the fence signal early (or never), breaking dependency synchronization.
Translate the WPTR GPU address to a byte offset within the BO, accounting for the VA mapping start and the mapping's BO offset, before reading it. Signed-off-by: Jesse Zhang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index c270635c907b..b885e90ec5f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -372,7 +372,7 @@ static int amdgpu_userq_fence_read_wptr(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping; struct amdgpu_bo *bo; struct drm_exec exec; - u64 addr, *ptr; + u64 addr, offset, *ptr; int ret; addr = queue->userq_prop->wptr_gpu_addr; @@ -404,7 +404,10 @@ static int amdgpu_userq_fence_read_wptr(struct amdgpu_device *adev, goto lock_error; } - *wptr = le64_to_cpu(*ptr); + /* The WPTR can be anywhere within the BO's VA mapping. */ + offset = addr - (mapping->start << AMDGPU_GPU_PAGE_SHIFT); + offset += mapping->offset; + *wptr = le64_to_cpu(ptr[offset / sizeof(*ptr)]); amdgpu_bo_kunmap(bo); drm_exec_fini(&exec); -- 2.49.0
