From: Arvind Yadav <arvind.ya...@amd.com>

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.deuc...@amd.com>
Cc: Christian Koenig <christian.koe...@amd.com>
Signed-off-by: Arvind Yadav <arvind.ya...@amd.com>
Signed-off-by: Shashank Sharma <shashank.sha...@amd.com>
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

Reply via email to