drm/msm: submit support for out-fences
authorRob Clark <robdclark@gmail.com>
Thu, 16 Jun 2016 20:43:49 +0000 (16:43 -0400)
committerRob Clark <robdclark@gmail.com>
Thu, 15 Sep 2016 21:47:40 +0000 (17:47 -0400)
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/msm_gem_submit.c
include/uapi/drm/msm_drm.h

index 65284febb2f93749197d84c1f2ab7609603d6c79..3ac14cd1e5b9a023666a3b576a8ed73de312dc0d 100644 (file)
@@ -364,6 +364,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        struct msm_gem_submit *submit;
        struct msm_gpu *gpu = priv->gpu;
        struct fence *in_fence = NULL;
+       struct sync_file *sync_file = NULL;
+       int out_fence_fd = -1;
        unsigned i;
        int ret;
 
@@ -383,6 +385,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        if (ret)
                return ret;
 
+       if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
+               if (out_fence_fd < 0) {
+                       ret = out_fence_fd;
+                       goto out_unlock;
+               }
+       }
+
        submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds);
        if (!submit) {
                ret = -ENOMEM;
@@ -495,10 +505,23 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
                goto out;
        }
 
+       if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               sync_file = sync_file_create(submit->fence);
+               if (!sync_file) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+       }
+
        msm_gpu_submit(gpu, submit, ctx);
 
        args->fence = submit->fence->seqno;
 
+       if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+               fd_install(out_fence_fd, sync_file->file);
+               args->fence_fd = out_fence_fd;
+       }
+
 out:
        if (in_fence)
                fence_put(in_fence);
@@ -506,6 +529,8 @@ out:
        if (ret)
                msm_gem_submit_free(submit);
 out_unlock:
+       if (ret && (out_fence_fd >= 0))
+               put_unused_fd(out_fence_fd);
        mutex_unlock(&dev->struct_mutex);
        return ret;
 }
index 0402994cdbb7bf7559a75ffa72e77cdb774a5568..8c51e8a0df891e4583c6e18718e64265d33ce1dc 100644 (file)
@@ -187,9 +187,11 @@ struct drm_msm_gem_submit_bo {
 /* Valid submit ioctl flags: */
 #define MSM_SUBMIT_NO_IMPLICIT   0x80000000 /* disable implicit sync */
 #define MSM_SUBMIT_FENCE_FD_IN   0x40000000 /* enable input fence_fd */
+#define MSM_SUBMIT_FENCE_FD_OUT  0x20000000 /* enable output fence_fd */
 #define MSM_SUBMIT_FLAGS                ( \
                MSM_SUBMIT_NO_IMPLICIT   | \
                MSM_SUBMIT_FENCE_FD_IN   | \
+               MSM_SUBMIT_FENCE_FD_OUT  | \
                0)
 
 /* Each cmdstream submit consists of a table of buffers involved, and
@@ -203,7 +205,7 @@ struct drm_msm_gem_submit {
        __u32 nr_cmds;        /* in, number of submit_cmd's */
        __u64 __user bos;     /* in, ptr to array of submit_bo's */
        __u64 __user cmds;    /* in, ptr to array of submit_cmd's */
-       __s32 fence_fd;       /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN) */
+       __s32 fence_fd;       /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */
 };
 
 /* The normal way to synchronize with the GPU is just to CPU_PREP on