drm/amdgpu: Add input fence to sync bo map/unmap

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>
This commit is contained in:
Arvind Yadav 2024-09-25 18:10:41 +02:00 committed by Alex Deucher
parent 189ee986b0
commit 38c67ec9aa
2 changed files with 50 additions and 0 deletions

View File

@ -45,6 +45,45 @@
#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;
}

View 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