drm/amdgpu: Add input fence to sync bo map/unmap
authorArvind Yadav <arvind.yadav@amd.com>
Wed, 25 Sep 2024 16:10:41 +0000 (18:10 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 8 Apr 2025 20:48:17 +0000 (16:48 -0400)
This patch adds input fences to VM_IOCTL for buffer object.
The kernel will map/unmap the BO only when the fence is signaled.
The UAPI for the same has been approved here:
https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/392

V2: Bug fix (Arvind)
V3: Bug fix (Arvind)
V4: Rename UAPI objects as per UAPI review (Marek)
V5: Addressed review comemnts from Christian
     - function should return error.
     - Add 'TODO' comment
     - The input fence should be independent of the operation.
V6: Addressed review comemnts from Christian
    - Release the memory allocated by memdup_user().
V7: Addressed review comemnts from Christian
    - Drop the debug print and add "return r;" for the error handling.

V11: Rebase
v12: Fix 32-bit holes issue in sturct drm_amdgpu_gem_va.
v13: Fix deadlock issue.
v14: Fix merge conflict.
v15: Fix review comment by renaming syncobj handles.

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
include/uapi/drm/amdgpu_drm.h

index 542a1b70f2ee9768e38bae7295aa9dca65254970..bdf46cb4327fbe8005e6be7c046a7536d9afe413 100644 (file)
 #include "amdgpu_xgmi.h"
 #include "amdgpu_vm.h"
 
+static int
+amdgpu_gem_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 0;
+
+       syncobj_handles = memdup_user(u64_to_user_ptr(syncobj_handles_array),
+                                     sizeof(uint32_t) * num_syncobj_handles);
+       if (IS_ERR(syncobj_handles))
+               return PTR_ERR(syncobj_handles);
+
+       for (i = 0; i < num_syncobj_handles; i++) {
+
+               if (!syncobj_handles[i]) {
+                       ret = -EINVAL;
+                       goto free_memdup;
+               }
+
+               ret = drm_syncobj_find_fence(filp, syncobj_handles[i], 0, 0, &fence);
+               if (ret)
+                       goto free_memdup;
+
+               dma_fence_wait(fence, false);
+
+               /* TODO: optimize async handling */
+               dma_fence_put(fence);
+       }
+
+free_memdup:
+       kfree(syncobj_handles);
+       return ret;
+}
+
 static int
 amdgpu_gem_update_timeline_node(struct drm_file *filp,
                                uint32_t syncobj_handle,
@@ -854,6 +893,12 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
                abo = NULL;
        }
 
+       r = amdgpu_gem_add_input_fence(filp,
+                                      args->input_fence_syncobj_handles,
+                                      args->num_syncobj_handles);
+       if (r)
+               goto error_put_gobj;
+
        drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
                      DRM_EXEC_IGNORE_DUPLICATES, 0);
        drm_exec_until_all_locked(&exec) {
@@ -928,6 +973,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
 
 error:
        drm_exec_fini(&exec);
+error_put_gobj:
        drm_gem_object_put(gobj);
        return r;
 }
index 02cf03e811d5f6e5f4eec122af5f9150d9e48216..0910a6f8c5f2c7434664e5b69b1207b027342325 100644 (file)
@@ -884,6 +884,10 @@ struct drm_amdgpu_gem_va {
         * at vm_timeline_point.
         */
        __u32 vm_timeline_syncobj_out;
+       /** the number of syncobj handles in @input_fence_syncobj_handles */
+       __u32 num_syncobj_handles;
+       /** Array of sync object handle to wait for given input fences */
+       __u64 input_fence_syncobj_handles;
 };
 
 #define AMDGPU_HW_IP_GFX          0