From: Arvind Yadav <Arvind.Yadav@xxxxxxx> This patch adds input fences to VM_IOCTL for unmapping an object. The kernel will unmap the BO only when the fence is signaled. V2: Bug fix (Arvind) V3: Bug fix (Arvind) V4: Rename UAPI objects as per UAPI review (Marek) Cc: Alex Deucher <alexander.deucher@xxxxxxx> Cc: Christian Koenig <christian.koenig@xxxxxxx> Signed-off-by: Arvind Yadav <arvind.yadav@xxxxxxx> Signed-off-by: Shashank Sharma <shashank.sharma@xxxxxxx> Change-Id: Ib1572da97b640d80e39d73c9c166fa1759d720b5 --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 41 +++++++++++++++++++++++++ include/uapi/drm/amdgpu_drm.h | 4 +++ 2 files changed, 45 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index c9b4a6ce3f14..7823faa3dbaa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -36,6 +36,7 @@ #include <drm/drm_exec.h> #include <drm/drm_gem_ttm_helper.h> #include <drm/ttm/ttm_tt.h> +#include <drm/drm_syncobj.h> #include "amdgpu.h" #include "amdgpu_display.h" @@ -45,6 +46,39 @@ static const struct drm_gem_object_funcs amdgpu_gem_object_funcs; +static void amdgpu_userqueue_add_input_fence(struct drm_file *filp, + uint64_t syncobj_handles_array, + uint32_t num_syncobj_handles) +{ + struct dma_fence *fence; + uint32_t *syncobj_handles; + int ret, i; + + if (!num_syncobj_handles) + return; + + syncobj_handles = memdup_user(u64_to_user_ptr(syncobj_handles_array), + sizeof(uint32_t) * num_syncobj_handles); + if (IS_ERR(syncobj_handles)) { + DRM_ERROR("Failed to get the syncobj handles err = %ld\n", + PTR_ERR(syncobj_handles)); + return; + } + + for (i = 0; i < num_syncobj_handles; i++) { + + if (!syncobj_handles[i]) + continue; + + ret = drm_syncobj_find_fence(filp, syncobj_handles[i], 0, 0, &fence); + if (ret) + continue; + + dma_fence_wait(fence, false); + dma_fence_put(fence); + } +} + static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf) { struct ttm_buffer_object *bo = vmf->vma->vm_private_data; @@ -809,6 +843,13 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, bo_va = NULL; } + if (args->operation == AMDGPU_VA_OP_UNMAP || + args->operation == AMDGPU_VA_OP_CLEAR || + args->operation == AMDGPU_VA_OP_REPLACE) + amdgpu_userqueue_add_input_fence(filp, + args->input_fence_syncobj_array_in, + args->num_syncobj_handles_in); + switch (args->operation) { case AMDGPU_VA_OP_MAP: va_flags = amdgpu_gem_va_map_flags(adev, args->flags); diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 1dc1dba6b024..8dd0d1808e37 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -840,6 +840,10 @@ struct drm_amdgpu_gem_va { __u32 timeline_syncobj_out; /** Timeline point */ __u64 timeline_point_in; + /** Array of sync object handle to wait for given input fences */ + __u64 input_fence_syncobj_array_in; + /** the number of syncobj handles in @input_fence_syncobj_array_in */ + __u32 num_syncobj_handles_in; }; #define AMDGPU_HW_IP_GFX 0 -- 2.45.1