This makes the logic from drm_syncobj_query_ioctl available to callers
that already have an array of drm_syncobj.

Signed-off-by: Julian Orth <[email protected]>
---
 drivers/gpu/drm/drm_syncobj.c | 32 +++++++++++++++++++++++++++-----
 include/drm/drm_syncobj.h     |  2 ++
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 948084f56c32..9b7ecc2978f5 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1773,8 +1773,6 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void 
*data,
 {
        struct drm_syncobj_timeline_array *args = data;
        struct drm_syncobj **syncobjs;
-       uint64_t __user *points = u64_to_user_ptr(args->points);
-       uint32_t i;
        int ret;
 
        if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
@@ -1793,7 +1791,31 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void 
*data,
        if (ret < 0)
                return ret;
 
-       for (i = 0; i < args->count_handles; i++) {
+       ret = drm_syncobj_query(syncobjs, args->points,
+                               args->count_handles, args->flags);
+
+       drm_syncobj_array_free(syncobjs, args->count_handles);
+
+       return ret;
+}
+
+/**
+ * drm_syncobj_query - query timeline points of syncobjs
+ * @syncobjs: array of syncobjs
+ * @user_points: user pointer to array of timeline points
+ * @count: number of syncobjs
+ * @flags: DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED or 0
+ *
+ * Queries the timeline point of each syncobj and writes it to @points.
+ */
+int drm_syncobj_query(struct drm_syncobj **syncobjs, u64 user_points,
+                     u32 count, u32 flags)
+{
+       uint64_t __user *points = u64_to_user_ptr(user_points);
+       uint32_t i;
+       int ret = 0;
+
+       for (i = 0; i < count; i++) {
                struct dma_fence_chain *chain;
                struct dma_fence *fence;
                uint64_t point;
@@ -1804,7 +1826,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void 
*data,
                        struct dma_fence *iter, *last_signaled =
                                dma_fence_get(fence);
 
-                       if (args->flags &
+                       if (flags &
                            DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
                                point = fence->seqno;
                        } else {
@@ -1832,7 +1854,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void 
*data,
                if (ret)
                        break;
        }
-       drm_syncobj_array_free(syncobjs, args->count_handles);
 
        return ret;
 }
+EXPORT_SYMBOL(drm_syncobj_query);
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index a9216ea07946..da237ca3e61f 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -141,6 +141,8 @@ int drm_syncobj_transfer(struct drm_syncobj *src, u64 
src_point,
                         u32 flags);
 int drm_syncobj_timeline_signal(struct drm_syncobj **syncobjs,
                                u64 user_points, u32 count);
+int drm_syncobj_query(struct drm_syncobj **syncobjs, u64 user_points,
+                     u32 count, u32 flags);
 void drm_syncobj_free(struct kref *kref);
 int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
                       struct dma_fence *fence);

-- 
2.54.0

Reply via email to