normal syncobj can be unified to timeline syncobj. The thingking is: a. singal op always append to sinal list tail. b. wait op always wait on last sinal point. the driver indeed be simplified more. Signed-off-by: Chunming Zhou <david1.zhou@xxxxxxx> --- drivers/gpu/drm/drm_syncobj.c | 113 ++++++++++++++++------------------ 1 file changed, 52 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index e0d89a84359f..ff0b1fdfd9a8 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -56,6 +56,9 @@ #include "drm_internal.h" #include <drm/drm_syncobj.h> +/* merge normal syncobj to timeline syncobj, the point interval is 1 */ +#define DRM_SYNCOBJ_NORMAL_POINT 1 + struct drm_syncobj_stub_fence { struct dma_fence base; spinlock_t lock; @@ -333,32 +336,17 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, u64 point, struct dma_fence *fence) { - struct dma_fence *old_fence; - struct drm_syncobj_cb *cur, *tmp; - if (syncobj->type == DRM_SYNCOBJ_TYPE_TIMELINE) { drm_syncobj_timeline_create_signal_pt(syncobj, fence, point); return; + } else if (syncobj->type == DRM_SYNCOBJ_TYPE_NORMAL) { + u64 pt_value = syncobj->syncobj_timeline.signal_point + + DRM_SYNCOBJ_NORMAL_POINT; + drm_syncobj_timeline_create_signal_pt(syncobj, fence, pt_value); + return; + } else { + DRM_ERROR("the syncobj type isn't support\n"); } - if (fence) - dma_fence_get(fence); - - spin_lock(&syncobj->lock); - - old_fence = rcu_dereference_protected(syncobj->fence, - lockdep_is_held(&syncobj->lock)); - rcu_assign_pointer(syncobj->fence, fence); - - if (fence != old_fence) { - list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { - list_del_init(&cur->node); - cur->func(syncobj, cur); - } - } - - spin_unlock(&syncobj->lock); - - dma_fence_put(old_fence); } EXPORT_SYMBOL(drm_syncobj_replace_fence); @@ -452,7 +440,7 @@ drm_syncobj_timeline_create_wait_pt(struct drm_syncobj *syncobj, u64 point) } static struct dma_fence * -drm_syncobj_timeline_point_get(struct drm_syncobj *syncobj, u64 point, u64 flag) +drm_syncobj_timeline_point_get(struct drm_syncobj *syncobj, u64 point, u64 flags) { struct drm_syncobj_wait_pt *wait_pt; @@ -481,13 +469,15 @@ drm_syncobj_timeline_point_get(struct drm_syncobj *syncobj, u64 point, u64 flag) } if (wait_pt) { struct dma_fence *fence; - int ret = - wait_event_interruptible_timeout(syncobj->syncobj_timeline.wq, - wait_pt->value <= syncobj->syncobj_timeline.signal_point, - msecs_to_jiffies(10000)); /* wait 10s */ - - if (ret <= 0) - return NULL; + int ret = 0; + + if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { + ret = wait_event_interruptible_timeout(syncobj->syncobj_timeline.wq, + wait_pt->value <= syncobj->syncobj_timeline.signal_point, + msecs_to_jiffies(10000)); /* wait 10s */ + if (ret <= 0) + return NULL; + } rcu_read_lock(); fence = dma_fence_get_rcu(&wait_pt->base.base); rcu_read_unlock(); @@ -510,23 +500,26 @@ drm_syncobj_timeline_point_get(struct drm_syncobj *syncobj, u64 point, u64 flag) * contains a reference to the fence, which must be released by calling * dma_fence_put(). */ -int drm_syncobj_find_fence(struct drm_file *file_private, - u32 handle, u64 point, - struct dma_fence **fence) +static int drm_syncobj_search_fence(struct drm_syncobj *syncobj, u64 point, + u64 flags, struct dma_fence **fence) { - struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); int ret = 0; if (!syncobj) return -ENOENT; if (syncobj->type == DRM_SYNCOBJ_TYPE_NORMAL) { + u64 tail_pt_value = syncobj->syncobj_timeline.signal_point; + + if (tail_pt_value == 0) + tail_pt_value += DRM_SYNCOBJ_NORMAL_POINT; /* NORMAL syncobj doesn't care point value */ WARN_ON(point != 0); - *fence = drm_syncobj_fence_get(syncobj); + *fence = drm_syncobj_timeline_point_get(syncobj, tail_pt_value, + flags); } else if (syncobj->type == DRM_SYNCOBJ_TYPE_TIMELINE) { *fence = drm_syncobj_timeline_point_get(syncobj, point, - DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT); + flags); } else { DRM_ERROR("Don't support this type syncobj\n"); *fence = NULL; @@ -537,6 +530,15 @@ int drm_syncobj_find_fence(struct drm_file *file_private, drm_syncobj_put(syncobj); return ret; } +int drm_syncobj_find_fence(struct drm_file *file_private, + u32 handle, u64 point, + struct dma_fence **fence) { + struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); + + return drm_syncobj_search_fence(syncobj, point, + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, + fence); +} EXPORT_SYMBOL(drm_syncobj_find_fence); static void drm_syncobj_timeline_fini(struct drm_syncobj *syncobj, @@ -578,7 +580,6 @@ void drm_syncobj_free(struct kref *kref) struct drm_syncobj *syncobj = container_of(kref, struct drm_syncobj, refcount); - drm_syncobj_replace_fence(syncobj, 0, NULL); drm_syncobj_timeline_fini(syncobj, &syncobj->syncobj_timeline); kfree(syncobj); } @@ -1031,14 +1032,11 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, signaled_count = 0; for (i = 0; i < count; ++i) { entries[i].task = current; - entries[i].fence = drm_syncobj_fence_get(syncobjs[i]); + ret = drm_syncobj_search_fence(syncobjs[i], 0, 0, + &entries[i].fence); if (!entries[i].fence) { - if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { - continue; - } else { - ret = -EINVAL; - goto cleanup_entries; - } + ret = -EINVAL; + goto cleanup_entries; } if (dma_fence_is_signaled(entries[i].fence)) { @@ -1066,15 +1064,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, * fallthough and try a 0 timeout wait! */ - if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { - for (i = 0; i < count; ++i) { - drm_syncobj_fence_get_or_add_callback(syncobjs[i], - &entries[i].fence, - &entries[i].syncobj_cb, - syncobj_wait_syncobj_func); - } - } - do { set_current_state(TASK_INTERRUPTIBLE); @@ -1122,13 +1111,10 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, cleanup_entries: for (i = 0; i < count; ++i) { - if (entries[i].syncobj_cb.func) - drm_syncobj_remove_callback(syncobjs[i], - &entries[i].syncobj_cb); + dma_fence_put(entries[i].fence); if (entries[i].fence_cb.func) dma_fence_remove_callback(entries[i].fence, &entries[i].fence_cb); - dma_fence_put(entries[i].fence); } kfree(entries); @@ -1303,12 +1289,17 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, if (ret < 0) return ret; - for (i = 0; i < args->count_handles; i++) - drm_syncobj_replace_fence(syncobjs[i], 0, NULL); - + for (i = 0; i < args->count_handles; i++) { + if (syncobjs[i]->type == DRM_SYNCOBJ_TYPE_TIMELINE) { + DRM_ERROR("timeline syncobj cannot reset!\n"); + ret = -EINVAL; + goto out; + } + } +out: drm_syncobj_array_free(syncobjs, args->count_handles); - return 0; + return ret; } int -- 2.17.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel