在 2018/12/7 19:31, Christian König 写道: > Am 07.12.18 um 10:56 schrieb Chunming Zhou: >> Signed-off-by: Chunming Zhou <david1.zhou@xxxxxxx> >> --- >> drivers/gpu/drm/drm_internal.h | 2 + >> drivers/gpu/drm/drm_ioctl.c | 2 + >> drivers/gpu/drm/drm_syncobj.c | 70 ++++++++++++++++++++++++++++++++++ >> include/uapi/drm/drm.h | 1 + >> 4 files changed, 75 insertions(+) >> >> diff --git a/drivers/gpu/drm/drm_internal.h >> b/drivers/gpu/drm/drm_internal.h >> index ecbe3d51a702..149c2f589ec9 100644 >> --- a/drivers/gpu/drm/drm_internal.h >> +++ b/drivers/gpu/drm/drm_internal.h >> @@ -188,6 +188,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_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); >> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c >> index 6b417e3c3ea5..d05586601eb5 100644 >> --- a/drivers/gpu/drm/drm_ioctl.c >> +++ b/drivers/gpu/drm/drm_ioctl.c >> @@ -687,6 +687,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_TIMELINE_SIGNAL, >> drm_syncobj_timeline_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), >> diff --git a/drivers/gpu/drm/drm_syncobj.c >> b/drivers/gpu/drm/drm_syncobj.c >> index cf4daa670252..238ed89593a7 100644 >> --- a/drivers/gpu/drm/drm_syncobj.c >> +++ b/drivers/gpu/drm/drm_syncobj.c >> @@ -1165,6 +1165,76 @@ drm_syncobj_signal_ioctl(struct drm_device >> *dev, void *data, >> return ret; >> } >> +int >> +drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, >> + struct drm_file *file_private) >> +{ >> + struct drm_syncobj_timeline_array *args = data; >> + struct drm_syncobj **syncobjs; >> + struct dma_fence_chain *chains; >> + uint64_t *points; >> + uint32_t i, j, timeline_count = 0; >> + int ret; >> + >> + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) >> + return -EOPNOTSUPP; >> + >> + if (args->pad != 0) >> + return -EINVAL; >> + >> + 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) { >> + ret = -ENOMEM; >> + goto out; >> + } >> + if (!u64_to_user_ptr(args->points)) { >> + memset(points, 0, args->count_handles * sizeof(uint64_t)); >> + } else if (copy_from_user(points, u64_to_user_ptr(args->points), >> + sizeof(uint64_t) * args->count_handles)) { >> + ret = -EFAULT; >> + goto err_points; >> + } >> + >> + >> + for (i = 0; i < args->count_handles; i++) { >> + if (points[i]) >> + timeline_count++; >> + } >> + chains = kmalloc_array(timeline_count, sizeof(*chains), >> GFP_KERNEL); > > I don't think that this will work. We need individually allocated > chain objects. Yeah, I shouldn't use &chains[i] to get address, how about using cast like "(struct dma_fence_chain *)chains[i]". btw, I will add a test case for signal array in igt. -David > > Apart from that this looks good to me, > Christian. > >> + if (!chains) { >> + ret = -ENOMEM; >> + goto err_points; >> + } >> + >> + for (i = 0, j = 0; i < args->count_handles; i++) { >> + if (points[i]) { >> + struct dma_fence *fence = dma_fence_get_stub(); >> + >> + drm_syncobj_add_point(syncobjs[i], &chains[j++], >> + fence, points[i]); >> + dma_fence_put(fence); >> + } else >> + drm_syncobj_assign_null_handle(syncobjs[i]); >> + } >> +err_points: >> + kfree(points); >> +out: >> + drm_syncobj_array_free(syncobjs, args->count_handles); >> + >> + return ret; >> +} >> + >> int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, >> struct drm_file *file_private) >> { >> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h >> index 88d6129d4a18..9a5fa3c26f22 100644 >> --- a/include/uapi/drm/drm.h >> +++ b/include/uapi/drm/drm.h >> @@ -943,6 +943,7 @@ extern "C" { >> #define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct >> drm_syncobj_timeline_array) >> #define DRM_IOCTL_SYNCOBJ_BINARY_TO_TIMELINE DRM_IOWR(0xCC, >> struct drm_syncobj_transfer) >> #define DRM_IOCTL_SYNCOBJ_TIMELINE_TO_BINARY DRM_IOWR(0xCD, >> struct drm_syncobj_transfer) >> +#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCE, struct >> drm_syncobj_timeline_array) >> /** >> * Device specific ioctls should only be in their respective headers > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel