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 <[email protected]>
---
 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

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to