From: Rob Clark <robdcl...@chromium.org>

We'll be re-using these for the VM_BIND ioctl.

Also, rename a few things in the uapi header to reflect that syncobj use
is not specific to the submit ioctl.

Signed-off-by: Rob Clark <robdcl...@chromium.org>
---
 drivers/gpu/drm/msm/Makefile         |   1 +
 drivers/gpu/drm/msm/msm_gem_submit.c | 192 ++-------------------------
 drivers/gpu/drm/msm/msm_syncobj.c    | 172 ++++++++++++++++++++++++
 drivers/gpu/drm/msm/msm_syncobj.h    |  37 ++++++
 include/uapi/drm/msm_drm.h           |  26 ++--
 5 files changed, 235 insertions(+), 193 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/msm_syncobj.c
 create mode 100644 drivers/gpu/drm/msm/msm_syncobj.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 5df20cbeafb8..8af34f87e0c8 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -128,6 +128,7 @@ msm-y += \
        msm_rd.o \
        msm_ringbuffer.o \
        msm_submitqueue.o \
+       msm_syncobj.o \
        msm_gpu_tracepoints.o \
 
 msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
index 375d89f23cd1..552ff2d57294 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -16,6 +16,7 @@
 #include "msm_gpu.h"
 #include "msm_gem.h"
 #include "msm_gpu_trace.h"
+#include "msm_syncobj.h"
 
 /* For userspace errors, use DRM_UT_DRIVER.. so that userspace can enable
  * error msgs for debugging, but we don't spam dmesg by default
@@ -477,173 +478,6 @@ void msm_submit_retire(struct msm_gem_submit *submit)
        }
 }
 
-struct msm_submit_post_dep {
-       struct drm_syncobj *syncobj;
-       uint64_t point;
-       struct dma_fence_chain *chain;
-};
-
-static struct drm_syncobj **msm_parse_deps(struct msm_gem_submit *submit,
-                                           struct drm_file *file,
-                                           uint64_t in_syncobjs_addr,
-                                           uint32_t nr_in_syncobjs,
-                                           size_t syncobj_stride)
-{
-       struct drm_syncobj **syncobjs = NULL;
-       struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
-       int ret = 0;
-       uint32_t i, j;
-
-       syncobjs = kcalloc(nr_in_syncobjs, sizeof(*syncobjs),
-                          GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
-       if (!syncobjs)
-               return ERR_PTR(-ENOMEM);
-
-       for (i = 0; i < nr_in_syncobjs; ++i) {
-               uint64_t address = in_syncobjs_addr + i * syncobj_stride;
-
-               if (copy_from_user(&syncobj_desc,
-                                  u64_to_user_ptr(address),
-                                  min(syncobj_stride, sizeof(syncobj_desc)))) {
-                       ret = -EFAULT;
-                       break;
-               }
-
-               if (syncobj_desc.point &&
-                   !drm_core_check_feature(submit->dev, 
DRIVER_SYNCOBJ_TIMELINE)) {
-                       ret = SUBMIT_ERROR(EOPNOTSUPP, submit, "syncobj 
timeline unsupported");
-                       break;
-               }
-
-               if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) {
-                       ret = SUBMIT_ERROR(EINVAL, submit, "invalid syncobj 
flags: %x", syncobj_desc.flags);
-                       break;
-               }
-
-               ret = drm_sched_job_add_syncobj_dependency(&submit->base, file,
-                                                          syncobj_desc.handle, 
syncobj_desc.point);
-               if (ret)
-                       break;
-
-               if (syncobj_desc.flags & MSM_SUBMIT_SYNCOBJ_RESET) {
-                       syncobjs[i] =
-                               drm_syncobj_find(file, syncobj_desc.handle);
-                       if (!syncobjs[i]) {
-                               ret = SUBMIT_ERROR(EINVAL, submit, "invalid 
syncobj handle: %u", i);
-                               break;
-                       }
-               }
-       }
-
-       if (ret) {
-               for (j = 0; j <= i; ++j) {
-                       if (syncobjs[j])
-                               drm_syncobj_put(syncobjs[j]);
-               }
-               kfree(syncobjs);
-               return ERR_PTR(ret);
-       }
-       return syncobjs;
-}
-
-static void msm_reset_syncobjs(struct drm_syncobj **syncobjs,
-                               uint32_t nr_syncobjs)
-{
-       uint32_t i;
-
-       for (i = 0; syncobjs && i < nr_syncobjs; ++i) {
-               if (syncobjs[i])
-                       drm_syncobj_replace_fence(syncobjs[i], NULL);
-       }
-}
-
-static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
-                                                       struct drm_file *file,
-                                                       uint64_t syncobjs_addr,
-                                                       uint32_t nr_syncobjs,
-                                                       size_t syncobj_stride)
-{
-       struct msm_submit_post_dep *post_deps;
-       struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
-       int ret = 0;
-       uint32_t i, j;
-
-       post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps),
-                           GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
-       if (!post_deps)
-               return ERR_PTR(-ENOMEM);
-
-       for (i = 0; i < nr_syncobjs; ++i) {
-               uint64_t address = syncobjs_addr + i * syncobj_stride;
-
-               if (copy_from_user(&syncobj_desc,
-                                  u64_to_user_ptr(address),
-                                  min(syncobj_stride, sizeof(syncobj_desc)))) {
-                       ret = -EFAULT;
-                       break;
-               }
-
-               post_deps[i].point = syncobj_desc.point;
-
-               if (syncobj_desc.flags) {
-                       ret = UERR(EINVAL, dev, "invalid syncobj flags");
-                       break;
-               }
-
-               if (syncobj_desc.point) {
-                       if (!drm_core_check_feature(dev,
-                                                   DRIVER_SYNCOBJ_TIMELINE)) {
-                               ret = UERR(EOPNOTSUPP, dev, "syncobj timeline 
unsupported");
-                               break;
-                       }
-
-                       post_deps[i].chain = dma_fence_chain_alloc();
-                       if (!post_deps[i].chain) {
-                               ret = -ENOMEM;
-                               break;
-                       }
-               }
-
-               post_deps[i].syncobj =
-                       drm_syncobj_find(file, syncobj_desc.handle);
-               if (!post_deps[i].syncobj) {
-                       ret = UERR(EINVAL, dev, "invalid syncobj handle");
-                       break;
-               }
-       }
-
-       if (ret) {
-               for (j = 0; j <= i; ++j) {
-                       dma_fence_chain_free(post_deps[j].chain);
-                       if (post_deps[j].syncobj)
-                               drm_syncobj_put(post_deps[j].syncobj);
-               }
-
-               kfree(post_deps);
-               return ERR_PTR(ret);
-       }
-
-       return post_deps;
-}
-
-static void msm_process_post_deps(struct msm_submit_post_dep *post_deps,
-                                  uint32_t count, struct dma_fence *fence)
-{
-       uint32_t i;
-
-       for (i = 0; post_deps && i < count; ++i) {
-               if (post_deps[i].chain) {
-                       drm_syncobj_add_point(post_deps[i].syncobj,
-                                             post_deps[i].chain,
-                                             fence, post_deps[i].point);
-                       post_deps[i].chain = NULL;
-               } else {
-                       drm_syncobj_replace_fence(post_deps[i].syncobj,
-                                                 fence);
-               }
-       }
-}
-
 int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
                struct drm_file *file)
 {
@@ -654,7 +488,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        struct msm_gpu *gpu = priv->gpu;
        struct msm_gpu_submitqueue *queue;
        struct msm_ringbuffer *ring;
-       struct msm_submit_post_dep *post_deps = NULL;
+       struct msm_syncobj_post_dep *post_deps = NULL;
        struct drm_syncobj **syncobjs_to_reset = NULL;
        int out_fence_fd = -1;
        unsigned i;
@@ -730,10 +564,10 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
*data,
        }
 
        if (args->flags & MSM_SUBMIT_SYNCOBJ_IN) {
-               syncobjs_to_reset = msm_parse_deps(submit, file,
-                                                  args->in_syncobjs,
-                                                  args->nr_in_syncobjs,
-                                                  args->syncobj_stride);
+               syncobjs_to_reset = msm_syncobj_parse_deps(dev, &submit->base,
+                                                          file, 
args->in_syncobjs,
+                                                          args->nr_in_syncobjs,
+                                                          
args->syncobj_stride);
                if (IS_ERR(syncobjs_to_reset)) {
                        ret = PTR_ERR(syncobjs_to_reset);
                        goto out_unlock;
@@ -741,10 +575,10 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
*data,
        }
 
        if (args->flags & MSM_SUBMIT_SYNCOBJ_OUT) {
-               post_deps = msm_parse_post_deps(dev, file,
-                                               args->out_syncobjs,
-                                               args->nr_out_syncobjs,
-                                               args->syncobj_stride);
+               post_deps = msm_syncobj_parse_post_deps(dev, file,
+                                                       args->out_syncobjs,
+                                                       args->nr_out_syncobjs,
+                                                       args->syncobj_stride);
                if (IS_ERR(post_deps)) {
                        ret = PTR_ERR(post_deps);
                        goto out_unlock;
@@ -887,10 +721,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
*data,
        args->fence = submit->fence_id;
        queue->last_fence = submit->fence_id;
 
-       msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);
-       msm_process_post_deps(post_deps, args->nr_out_syncobjs,
-                             submit->user_fence);
-
+       msm_syncobj_reset(syncobjs_to_reset, args->nr_in_syncobjs);
+       msm_syncobj_process_post_deps(post_deps, args->nr_out_syncobjs, 
submit->user_fence);
 
 out:
        submit_cleanup(submit, !!ret);
diff --git a/drivers/gpu/drm/msm/msm_syncobj.c 
b/drivers/gpu/drm/msm/msm_syncobj.c
new file mode 100644
index 000000000000..4baa9f522c54
--- /dev/null
+++ b/drivers/gpu/drm/msm/msm_syncobj.c
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2020 Google, Inc */
+
+#include "drm/drm_drv.h"
+
+#include "msm_drv.h"
+#include "msm_syncobj.h"
+
+struct drm_syncobj **
+msm_syncobj_parse_deps(struct drm_device *dev,
+                      struct drm_sched_job *job,
+                      struct drm_file *file,
+                      uint64_t in_syncobjs_addr,
+                      uint32_t nr_in_syncobjs,
+                      size_t syncobj_stride)
+{
+       struct drm_syncobj **syncobjs = NULL;
+       struct drm_msm_syncobj syncobj_desc = {0};
+       int ret = 0;
+       uint32_t i, j;
+
+       syncobjs = kcalloc(nr_in_syncobjs, sizeof(*syncobjs),
+                          GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+       if (!syncobjs)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < nr_in_syncobjs; ++i) {
+               uint64_t address = in_syncobjs_addr + i * syncobj_stride;
+
+               if (copy_from_user(&syncobj_desc,
+                                  u64_to_user_ptr(address),
+                                  min(syncobj_stride, sizeof(syncobj_desc)))) {
+                       ret = -EFAULT;
+                       break;
+               }
+
+               if (syncobj_desc.point &&
+                   !drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) {
+                       ret = UERR(EOPNOTSUPP, dev, "syncobj timeline 
unsupported");
+                       break;
+               }
+
+               if (syncobj_desc.flags & ~MSM_SYNCOBJ_FLAGS) {
+                       ret = UERR(EINVAL, dev, "invalid syncobj flags: %x", 
syncobj_desc.flags);
+                       break;
+               }
+
+               ret = drm_sched_job_add_syncobj_dependency(job, file,
+                                                  syncobj_desc.handle,
+                                                  syncobj_desc.point);
+               if (ret)
+                       break;
+
+               if (syncobj_desc.flags & MSM_SYNCOBJ_RESET) {
+                       syncobjs[i] = drm_syncobj_find(file, 
syncobj_desc.handle);
+                       if (!syncobjs[i]) {
+                               ret = UERR(EINVAL, dev, "invalid syncobj 
handle: %u", i);
+                               break;
+                       }
+               }
+       }
+
+       if (ret) {
+               for (j = 0; j <= i; ++j) {
+                       if (syncobjs[j])
+                               drm_syncobj_put(syncobjs[j]);
+               }
+               kfree(syncobjs);
+               return ERR_PTR(ret);
+       }
+       return syncobjs;
+}
+
+void
+msm_syncobj_reset(struct drm_syncobj **syncobjs, uint32_t nr_syncobjs)
+{
+       uint32_t i;
+
+       for (i = 0; syncobjs && i < nr_syncobjs; ++i) {
+               if (syncobjs[i])
+                       drm_syncobj_replace_fence(syncobjs[i], NULL);
+       }
+}
+
+struct msm_syncobj_post_dep *
+msm_syncobj_parse_post_deps(struct drm_device *dev,
+                           struct drm_file *file,
+                           uint64_t syncobjs_addr,
+                           uint32_t nr_syncobjs,
+                           size_t syncobj_stride)
+{
+       struct msm_syncobj_post_dep *post_deps;
+       struct drm_msm_syncobj syncobj_desc = {0};
+       int ret = 0;
+       uint32_t i, j;
+
+       post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps),
+                           GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+       if (!post_deps)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < nr_syncobjs; ++i) {
+               uint64_t address = syncobjs_addr + i * syncobj_stride;
+
+               if (copy_from_user(&syncobj_desc,
+                                  u64_to_user_ptr(address),
+                                  min(syncobj_stride, sizeof(syncobj_desc)))) {
+                       ret = -EFAULT;
+                       break;
+               }
+
+               post_deps[i].point = syncobj_desc.point;
+
+               if (syncobj_desc.flags) {
+                       ret = UERR(EINVAL, dev, "invalid syncobj flags");
+                       break;
+               }
+
+               if (syncobj_desc.point) {
+                       if (!drm_core_check_feature(dev,
+                                                   DRIVER_SYNCOBJ_TIMELINE)) {
+                               ret = UERR(EOPNOTSUPP, dev, "syncobj timeline 
unsupported");
+                               break;
+                       }
+
+                       post_deps[i].chain = dma_fence_chain_alloc();
+                       if (!post_deps[i].chain) {
+                               ret = -ENOMEM;
+                               break;
+                       }
+               }
+
+               post_deps[i].syncobj =
+                       drm_syncobj_find(file, syncobj_desc.handle);
+               if (!post_deps[i].syncobj) {
+                       ret = UERR(EINVAL, dev, "invalid syncobj handle");
+                       break;
+               }
+       }
+
+       if (ret) {
+               for (j = 0; j <= i; ++j) {
+                       dma_fence_chain_free(post_deps[j].chain);
+                       if (post_deps[j].syncobj)
+                               drm_syncobj_put(post_deps[j].syncobj);
+               }
+
+               kfree(post_deps);
+               return ERR_PTR(ret);
+       }
+
+       return post_deps;
+}
+
+void
+msm_syncobj_process_post_deps(struct msm_syncobj_post_dep *post_deps,
+                             uint32_t count, struct dma_fence *fence)
+{
+       uint32_t i;
+
+       for (i = 0; post_deps && i < count; ++i) {
+               if (post_deps[i].chain) {
+                       drm_syncobj_add_point(post_deps[i].syncobj,
+                                             post_deps[i].chain,
+                                             fence, post_deps[i].point);
+                       post_deps[i].chain = NULL;
+               } else {
+                       drm_syncobj_replace_fence(post_deps[i].syncobj,
+                                                 fence);
+               }
+       }
+}
diff --git a/drivers/gpu/drm/msm/msm_syncobj.h 
b/drivers/gpu/drm/msm/msm_syncobj.h
new file mode 100644
index 000000000000..bcaa15d01da0
--- /dev/null
+++ b/drivers/gpu/drm/msm/msm_syncobj.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2020 Google, Inc */
+
+#ifndef __MSM_GEM_SYNCOBJ_H__
+#define __MSM_GEM_SYNCOBJ_H__
+
+#include "drm/drm_device.h"
+#include "drm/drm_syncobj.h"
+#include "drm/gpu_scheduler.h"
+
+struct msm_syncobj_post_dep {
+       struct drm_syncobj *syncobj;
+       uint64_t point;
+       struct dma_fence_chain *chain;
+};
+
+struct drm_syncobj **
+msm_syncobj_parse_deps(struct drm_device *dev,
+                      struct drm_sched_job *job,
+                      struct drm_file *file,
+                      uint64_t in_syncobjs_addr,
+                      uint32_t nr_in_syncobjs,
+                      size_t syncobj_stride);
+
+void msm_syncobj_reset(struct drm_syncobj **syncobjs, uint32_t nr_syncobjs);
+
+struct msm_syncobj_post_dep *
+msm_syncobj_parse_post_deps(struct drm_device *dev,
+                           struct drm_file *file,
+                           uint64_t syncobjs_addr,
+                           uint32_t nr_syncobjs,
+                           size_t syncobj_stride);
+
+void msm_syncobj_process_post_deps(struct msm_syncobj_post_dep *post_deps,
+                                  uint32_t count, struct dma_fence *fence);
+
+#endif /* __MSM_GEM_SYNCOBJ_H__ */
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 1bccc347945c..2c2fc4b284d0 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -220,6 +220,17 @@ struct drm_msm_gem_cpu_fini {
  * Cmdstream Submission:
  */
 
+#define MSM_SYNCOBJ_RESET 0x00000001 /* Reset syncobj after wait. */
+#define MSM_SYNCOBJ_FLAGS ( \
+               MSM_SYNCOBJ_RESET | \
+               0)
+
+struct drm_msm_syncobj {
+       __u32 handle;     /* in, syncobj handle. */
+       __u32 flags;      /* in, from MSM_SUBMIT_SYNCOBJ_FLAGS */
+       __u64 point;      /* in, timepoint for timeline syncobjs. */
+};
+
 /* The value written into the cmdstream is logically:
  *
  *   ((relocbuf->gpuaddr + reloc_offset) << shift) | or
@@ -309,17 +320,6 @@ struct drm_msm_gem_submit_bo {
                MSM_SUBMIT_FENCE_SN_IN   | \
                0)
 
-#define MSM_SUBMIT_SYNCOBJ_RESET 0x00000001 /* Reset syncobj after wait. */
-#define MSM_SUBMIT_SYNCOBJ_FLAGS        ( \
-               MSM_SUBMIT_SYNCOBJ_RESET | \
-               0)
-
-struct drm_msm_gem_submit_syncobj {
-       __u32 handle;     /* in, syncobj handle. */
-       __u32 flags;      /* in, from MSM_SUBMIT_SYNCOBJ_FLAGS */
-       __u64 point;      /* in, timepoint for timeline syncobjs. */
-};
-
 /* Each cmdstream submit consists of a table of buffers involved, and
  * one or more cmdstream buffers.  This allows for conditional execution
  * (context-restore), and IB buffers needed for per tile/bin draw cmds.
@@ -333,8 +333,8 @@ struct drm_msm_gem_submit {
        __u64 cmds;           /* in, ptr to array of submit_cmd's */
        __s32 fence_fd;       /* in/out fence fd (see 
MSM_SUBMIT_FENCE_FD_IN/OUT) */
        __u32 queueid;        /* in, submitqueue id */
-       __u64 in_syncobjs;    /* in, ptr to array of drm_msm_gem_submit_syncobj 
*/
-       __u64 out_syncobjs;   /* in, ptr to array of drm_msm_gem_submit_syncobj 
*/
+       __u64 in_syncobjs;    /* in, ptr to array of drm_msm_syncobj */
+       __u64 out_syncobjs;   /* in, ptr to array of drm_msm_syncobj */
        __u32 nr_in_syncobjs; /* in, number of entries in in_syncobj */
        __u32 nr_out_syncobjs; /* in, number of entries in out_syncobj. */
        __u32 syncobj_stride; /* in, stride of syncobj arrays. */
-- 
2.49.0

Reply via email to