user mode can query timeline payload. Signed-off-by: Chunming Zhou <david1.zhou at amd.com> --- drivers/gpu/drm/drm_internal.h | 2 ++ drivers/gpu/drm/drm_ioctl.c | 2 ++ drivers/gpu/drm/drm_syncobj.c | 53 ++++++++++++++++++++++++++++++++++ include/uapi/drm/drm.h | 3 ++ 4 files changed, 60 insertions(+) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 40179c5fc6b8..cd57a7ba8bf6 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -182,6 +182,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); +int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private); /* drm_framebuffer.c */ void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index ea10e9a26aad..af98663ea252 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -673,6 +673,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl, + DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 4e43c62ab432..92216cd9f959 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1348,3 +1348,56 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, return ret; } + +static void drm_syncobj_timeline_query(struct drm_syncobj *syncobj, + uint64_t *point) +{ + if (syncobj->type != DRM_SYNCOBJ_TYPE_TIMELINE) { + DRM_ERROR("Normal syncobj cann't be queried!"); + *point = 0; + return; + } + *point = syncobj->syncobj_timeline.signal_point; +} + +int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private) +{ + struct drm_syncobj_array *args = data; + struct drm_syncobj **syncobjs; + uint64_t *points; + uint32_t i; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + return -ENODEV; + + if (args->count_handles == 0) + return -EINVAL; + + ret = drm_syncobj_array_find(file_private, + u64_to_user_ptr(args->handles), + args->count_handles, + &syncobjs); + if (ret < 0) + return ret; + + + points = kmalloc_array(args->count_handles, sizeof(*points), + GFP_KERNEL); + if (points == NULL) { + ret = -ENOMEM; + goto out; + } + for (i = 0; i < args->count_handles; i++) { + drm_syncobj_timeline_query(syncobjs[i], &points[i]); + copy_to_user(u64_to_user_ptr(args->points), points, + sizeof(uint64_t) * args->count_handles); + } + + kfree(points); +out: + drm_syncobj_array_free(syncobjs, args->count_handles); + + return ret; +} diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 4420c7604690..6b64ce1fdfe5 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -752,6 +752,8 @@ struct drm_syncobj_wait { struct drm_syncobj_array { __u64 handles; + /* points are timeline syncobjs payloads returned by query ioctl */ + __u64 points; __u32 count_handles; __u32 pad; }; @@ -912,6 +914,7 @@ extern "C" { #define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease) #define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease) +#define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCA, struct drm_syncobj_array) /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. -- 2.17.1