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

index 7c7a0314a7563f46a62b1ef4f156aba7615ebc03..d96b2b6898a3739b220633b4a711955f2a385e76 100644 (file)
@@ -11,6 +11,7 @@ config DRM_MSM
        select TMPFS
        select QCOM_SCM
        select SND_SOC_HDMI_CODEC if SND_SOC
+       select SYNC_FILE
        default y
        help
          DRM/KMS driver for MSM/snapdragon.
index 0b96d85d99f95f5b645b6e15b55627d835e38dbe..3a4a8ddeb1db88d1eb432e3e2f1bbdf7e211be21 100644 (file)
@@ -15,6 +15,8 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/sync_file.h>
+
 #include "msm_drv.h"
 #include "msm_gpu.h"
 #include "msm_gem.h"
@@ -361,6 +363,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        struct msm_file_private *ctx = file->driver_priv;
        struct msm_gem_submit *submit;
        struct msm_gpu *gpu = priv->gpu;
+       struct fence *in_fence = NULL;
        unsigned i;
        int ret;
 
@@ -394,9 +397,32 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        if (ret)
                goto out;
 
-       ret = submit_fence_sync(submit);
-       if (ret)
-               goto out;
+       if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
+               in_fence = sync_file_get_fence(args->fence_fd);
+
+               if (!in_fence) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               /* TODO if we get an array-fence due to userspace merging multiple
+                * fences, we need a way to determine if all the backing fences
+                * are from our own context..
+                */
+
+               if (in_fence->context != gpu->fctx->context) {
+                       ret = fence_wait(in_fence, true);
+                       if (ret)
+                               goto out;
+               }
+
+       }
+
+       if (!(args->fence & MSM_SUBMIT_NO_IMPLICIT)) {
+               ret = submit_fence_sync(submit);
+               if (ret)
+                       goto out;
+       }
 
        ret = submit_pin_objects(submit);
        if (ret)
@@ -467,6 +493,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        args->fence = submit->fence->seqno;
 
 out:
+       if (in_fence)
+               fence_put(in_fence);
        submit_cleanup(submit);
        if (ret)
                msm_gem_submit_free(submit);
index 913e08cd5cebc5d150455d86b9efcf1650ce8b91..0402994cdbb7bf7559a75ffa72e77cdb774a5568 100644 (file)
@@ -185,8 +185,12 @@ struct drm_msm_gem_submit_bo {
 };
 
 /* Valid submit ioctl flags: */
-/* to start, nothing.. */
-#define MSM_SUBMIT_FLAGS 0
+#define MSM_SUBMIT_NO_IMPLICIT   0x80000000 /* disable implicit sync */
+#define MSM_SUBMIT_FENCE_FD_IN   0x40000000 /* enable input fence_fd */
+#define MSM_SUBMIT_FLAGS                ( \
+               MSM_SUBMIT_NO_IMPLICIT   | \
+               MSM_SUBMIT_FENCE_FD_IN   | \
+               0)
 
 /* Each cmdstream submit consists of a table of buffers involved, and
  * one or more cmdstream buffers.  This allows for conditional execution
@@ -199,6 +203,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) */
 };
 
 /* The normal way to synchronize with the GPU is just to CPU_PREP on