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.
Unified · Split
| @@ -45,6 +45,45 @@ · 44 unmodified lines | |||
| 45 | #include "amdgpu_xgmi.h" | 45 | #include "amdgpu_xgmi.h" |
| 46 | #include "amdgpu_vm.h" | 46 | #include "amdgpu_vm.h" |
| 47 | 47 | ||
| 48 | static int | ||
| 49 | amdgpu_gem_add_input_fence(struct drm_file *filp, | ||
| 50 | uint64_t syncobj_handles_array, | ||
| 51 | uint32_t num_syncobj_handles) | ||
| 52 | { | ||
| 53 | struct dma_fence *fence; | ||
| 54 | uint32_t *syncobj_handles; | ||
| 55 | int ret, i; | ||
| 56 | |||
| 57 | if (!num_syncobj_handles) | ||
| 58 | return 0; | ||
| 59 | |||
| 60 | syncobj_handles = memdup_user(u64_to_user_ptr(syncobj_handles_array), | ||
| 61 | sizeof(uint32_t) * num_syncobj_handles); | ||
| 62 | if (IS_ERR(syncobj_handles)) | ||
| 63 | return PTR_ERR(syncobj_handles); | ||
| 64 | |||
| 65 | for (i = 0; i < num_syncobj_handles; i++) { | ||
| 66 | |||
| 67 | if (!syncobj_handles[i]) { | ||
| 68 | ret = -EINVAL; | ||
| 69 | goto free_memdup; | ||
| 70 | } | ||
| 71 | |||
| 72 | ret = drm_syncobj_find_fence(filp, syncobj_handles[i], 0, 0, &fence); | ||
| 73 | if (ret) | ||
| 74 | goto free_memdup; | ||
| 75 | |||
| 76 | dma_fence_wait(fence, false); | ||
| 77 | |||
| 78 | /* TODO: optimize async handling */ | ||
| 79 | dma_fence_put(fence); | ||
| 80 | } | ||
| 81 | |||
| 82 | free_memdup: | ||
| 83 | kfree(syncobj_handles); | ||
| 84 | return ret; | ||
| 85 | } | ||
| 86 | |||
| 48 | static int | 87 | static int |
| 49 | amdgpu_gem_update_timeline_node(struct drm_file *filp, | 88 | amdgpu_gem_update_timeline_node(struct drm_file *filp, |
| 50 | uint32_t syncobj_handle, | 89 | uint32_t syncobj_handle, |
| @@ -854,6 +893,12 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, · 803 unmodified lines | |||
| 854 | abo = NULL; | 893 | abo = NULL; |
| 855 | } | 894 | } |
| 856 | 895 | ||
| 896 | r = amdgpu_gem_add_input_fence(filp, | ||
| 897 | args->input_fence_syncobj_handles, | ||
| 898 | args->num_syncobj_handles); | ||
| 899 | if (r) | ||
| 900 | goto error_put_gobj; | ||
| 901 | |||
| 857 | drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | | 902 | drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | |
| 858 | DRM_EXEC_IGNORE_DUPLICATES, 0); | 903 | DRM_EXEC_IGNORE_DUPLICATES, 0); |
| 859 | drm_exec_until_all_locked(&exec) { | 904 | drm_exec_until_all_locked(&exec) { |
| @@ -928,6 +973,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, · 68 unmodified lines | |||
| 928 | 973 | ||
| 929 | error: | 974 | error: |
| 930 | drm_exec_fini(&exec); | 975 | drm_exec_fini(&exec); |
| 976 | error_put_gobj: | ||
| 931 | drm_gem_object_put(gobj); | 977 | drm_gem_object_put(gobj); |
| 932 | return r; | 978 | return r; |
| 933 | } | 979 | } |
| @@ -884,6 +884,10 @@ struct drm_amdgpu_gem_va { · 883 unmodified lines | |||
| 884 | * at vm_timeline_point. | 884 | * at vm_timeline_point. |
| 885 | */ | 885 | */ |
| 886 | __u32 vm_timeline_syncobj_out; | 886 | __u32 vm_timeline_syncobj_out; |
| 887 | /** the number of syncobj handles in @input_fence_syncobj_handles */ | ||
| 888 | __u32 num_syncobj_handles; | ||
| 889 | /** Array of sync object handle to wait for given input fences */ | ||
| 890 | __u64 input_fence_syncobj_handles; | ||
| 887 | }; | 891 | }; |
| 888 | 892 | ||
| 889 | #define AMDGPU_HW_IP_GFX 0 | 893 | #define AMDGPU_HW_IP_GFX 0 |