Add DRM_IOCTL_SYNCOBJ_QUERY_ERROR to allow userspace to query the error status of a fence held by a timeline/binary syncobj.
Signed-off-by: Yicong Hui <[email protected]> --- drivers/gpu/drm/drm_internal.h | 2 ++ drivers/gpu/drm/drm_ioctl.c | 2 ++ drivers/gpu/drm/drm_syncobj.c | 22 ++++++++++++++++++++++ include/uapi/drm/drm.h | 13 +++++++++++++ 4 files changed, 39 insertions(+) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index f893b1e3a596..d4d722983544 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -285,6 +285,8 @@ int drm_syncobj_timeline_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); +int drm_syncobj_query_error_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 ff193155129e..61b114a6a65f 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -732,6 +732,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY_ERROR, drm_syncobj_query_error_ioctl, + DRM_RENDER_ALLOW), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE(drm_ioctls) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 2d4ab745fdad..2152cd029070 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1717,3 +1717,25 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, return ret; } + +int drm_syncobj_query_error_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private) +{ + struct drm_syncobj_error *args = data; + struct dma_fence *fence; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + return -EOPNOTSUPP; + + ret = drm_syncobj_find_fence(file_private, args->handle, args->point, 0, &fence); + + if (ret) + return ret; + + args->error = fence->error; + + dma_fence_put(fence); + + return 0; +} diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 27cc159c1d27..087c0f2120ec 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -1051,6 +1051,11 @@ struct drm_syncobj_timeline_array { __u32 flags; }; +struct drm_syncobj_error { + __u32 handle; + __s32 error; + __u64 point; +}; /* Query current scanout sequence number */ struct drm_crtc_get_sequence { @@ -1363,6 +1368,14 @@ extern "C" { */ #define DRM_IOCTL_GEM_CHANGE_HANDLE DRM_IOWR(0xD2, struct drm_gem_change_handle) +/** + * DRM_IOCTL_SYNCOBJ_QUERY_ERROR - Query the error code from a failed drm_syncobj + * + * This ioctl provides userspace a way to query the error code of a binary and + * timeline drm_syncobj in the case that the submission fails. + */ +#define DRM_IOCTL_SYNCOBJ_QUERY_ERROR DRM_IOWR(0xD3, struct drm_syncobj_error) + /* * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f. -- 2.53.0
