Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/virtio: exbuf->fence_fd unmodified on interrupted wait

An interrupted dma_fence_wait() becomes an -ERESTARTSYS returned
to userspace ioctl(DRM_IOCTL_VIRTGPU_EXECBUFFER) calls, prompting to
retry the ioctl(), but the passed exbuf->fence_fd has been reset to -1,
making the retry attempt fail at sync_file_get_fence().

The uapi for DRM_IOCTL_VIRTGPU_EXECBUFFER is changed to retain the
passed value for exbuf->fence_fd when returning anything besides a
successful result from the ioctl.

Fixes: 2cd7b6f08bc4 ("drm/virtio: add in/out fence support for explicit synchronization")
Signed-off-by: Ryan Neph <ryanneph@chromium.org>
Reviewed-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230203233345.2477767-1-ryanneph@chromium.org

authored by

Ryan Neph and committed by
Dmitry Osipenko
8f20660f 9f8b3706

+2 -4
+1 -4
drivers/gpu/drm/virtio/virtgpu_ioctl.c
··· 126 126 void __user *user_bo_handles = NULL; 127 127 struct virtio_gpu_object_array *buflist = NULL; 128 128 struct sync_file *sync_file; 129 - int in_fence_fd = exbuf->fence_fd; 130 129 int out_fence_fd = -1; 131 130 void *buf; 132 131 uint64_t fence_ctx; ··· 151 152 ring_idx = exbuf->ring_idx; 152 153 } 153 154 154 - exbuf->fence_fd = -1; 155 - 156 155 virtio_gpu_create_context(dev, file); 157 156 if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) { 158 157 struct dma_fence *in_fence; 159 158 160 - in_fence = sync_file_get_fence(in_fence_fd); 159 + in_fence = sync_file_get_fence(exbuf->fence_fd); 161 160 162 161 if (!in_fence) 163 162 return -EINVAL;
+1
include/uapi/drm/virtgpu_drm.h
··· 64 64 __u32 pad; 65 65 }; 66 66 67 + /* fence_fd is modified on success if VIRTGPU_EXECBUF_FENCE_FD_OUT flag is set. */ 67 68 struct drm_virtgpu_execbuffer { 68 69 __u32 flags; 69 70 __u32 size;