<div dir="ltr">Sorry about the delay.<div>Hopefully other people from Android will also chime in.</div><div>We need the ability to merge sync fences and keep the sync_pt ordered: the idea behind sync timelines is that we promise an ordering of operations.</div>
<div><br></div><div>Our reference device is Nexus 10: we need to make sure that any new implementation satisfies the same requirements.</div><div><br></div><div>You can find sample use-cases here, we also use it in our hardware composer libraries:</div>

<div><a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/libsync/" target="_blank">https://android.googlesource.com/platform/system/core/+/refs/heads/master/libsync/</a><br></div><div><a href="https://android.googlesource.com/platform/frameworks/native/+/master/libs/ui/Fence.cpp" target="_blank">https://android.googlesource.com/platform/frameworks/native/+/master/libs/ui/Fence.cpp</a><br>

</div><div><br></div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Oct 30, 2013 at 5:17 AM, Maarten Lankhorst <span dir="ltr"><<a href="mailto:maarten.lankhorst@canonical.com" target="_blank">maarten.lankhorst@canonical.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">op 24-10-13 14:13, Maarten Lankhorst schreef:<br>
<div><div class="h5">> op 09-10-13 16:39, Maarten Lankhorst schreef:<br>
>> Hey,<br>
>><br>
>>  op 08-10-13 19:37, John Stultz schreef:<br>
>>> On Wed, Oct 2, 2013 at 11:13 AM, Erik Gilling <<a href="mailto:konkers@android.com">konkers@android.com</a>> wrote:<br>
>>>> On Wed, Oct 2, 2013 at 12:35 AM, Maarten Lankhorst<br>
>>>> <<a href="mailto:maarten.lankhorst@canonical.com">maarten.lankhorst@canonical.com</a>> wrote:<br>
>>>>> Depending on feedback I'll try reflashing my nexus 7 to stock android, and work on trying to convert android<br>
>>>>> syncpoints to dma-fence, which I'll probably rename to syncpoints.<br>
>>>> I thought the plan decided at plumbers was to investigate backing<br>
>>>> dma_buf with the android sync solution not the other way around.  It<br>
>>>> doesn't make sense to me to take a working, tested, end-to-end<br>
>>>> solution with a released compositing system built around it, throw it<br>
>>>> out, and replace it with new un-tested code to<br>
>>>> support a system which is not yet built.<br>
>>> Hey Erik,<br>
>>>   Thanks for the clarifying points in your email, your insights and<br>
>>> feedback are critical, and I think having you and Maarten continue to<br>
>>> work out the details here will make this productive.<br>
>>><br>
>>> My recollection from the discussion was that Rob was ok with trying to<br>
>>> pipe the sync arguments through the various interfaces in order to<br>
>>> support the explicit sync, but I think he did suggest having it backed<br>
>>> by the dma-buf fences underneath.<br>
>>><br>
>>> I know this can be frustrating to watch things be reimplemented when<br>
>>> you have a pre-baked solution, but some compromise will be needed to<br>
>>> get things merged (and Maarten is taking the initiative here), but its<br>
>>> important to keep discussing this so the *right* compromises are made<br>
>>> that don't hurt performance, etc.<br>
>>><br>
>>> My hope is Maarten's approach of getting the dma-fence core<br>
>>> integrated, and then moving the existing Android sync interface over<br>
>>> to the shared back-end, will allow for proper apples-to-apples<br>
>>> comparisons of the same interface. And if the functionality isn't<br>
>>> sufficient we can hold off on merging the sync interface conversion<br>
>>> until that gets resolved.<br>
>>><br>
>> Yeah, I'm trying to understand the android side too. I think a unified interface would benefit both. I'm<br>
>> toying a bit with the sw_sync driver in staging because it's the easiest to try out on my desktop.<br>
>><br>
>> The timeline stuff looks like it could be simplified. The main difference that there seems to be is that<br>
>> I didn't want to create a separate timeline struct for synchronization but let the drivers handle it.<br>
>><br>
>> If you use rcu for reference lifetime management of timeline, the kref can be dropped. Signalling all<br>
>> syncpts on timeline destroy to a new destroyed state would kill the need for a destroyed member.<br>
>> The active list is unneeded and can be killed if only a linear progression of child_list is allowed.<br>
>><br>
>> Which probably leaves this nice structure:<br>
>> struct sync_timeline {<br>
>>     const struct sync_timeline_ops    *ops;<br>
>>     char            name[32];<br>
>><br>
>>     struct list_head    child_list_head;<br>
>>     spinlock_t        child_list_lock;<br>
>><br>
>>     struct list_head    sync_timeline_list;<br>
>> };<br>
>><br>
>> Where name, and sync_timeline_list are nice for debugging, but I guess not necessarily required. so that<br>
>> could be split out into a separate debugfs thing if required. I've moved the pointer to ops to the fence<br>
>> for dma-fence, which leaves this..<br>
>><br>
>> struct sync_timeline {<br>
>>     struct list_head    child_list_head;<br>
>>     spinlock_t        child_list_lock;<br>
>><br>
>>     struct  sync_timeline_debug {<br>
>>         struct list_head    sync_timeline_list;<br>
>>         char name[32];<br>
>>     };<br>
>> };<br>
>><br>
>> Hm, this looks familiar, the drm drivers had some structure for protecting the active fence list that has<br>
>> an identical definition, but with a slightly different list offset..<br>
>><br>
>> struct __wait_queue_head {<br>
>>     spinlock_t lock;<br>
>>     struct list_head task_list;<br>
>> };<br>
>><br>
>> typedef struct __wait_queue_head wait_queue_head_t;<br>
>><br>
>> This is nicer to convert the existing drm drivers, which already implement synchronous wait with a waitqueue.<br>
>> The default wait op is in fact<br>
>><br>
>> Ok enough of this little excercise. I just wanted to see how different the 2 are. I think even if the<br>
>> fence interface will end up being incompatible it wouldn't be too hard to convert android..<br>
>><br>
>> Main difference is the ops, android has a lot more than what I used for dma-fence:<br>
>><br>
>> struct fence_ops {<br>
>>      bool (*enable_signaling)(struct fence *fence); // required, callback called with fence->lock held,<br>
>>      // fence->lock is a pointer passed to __fence_init. Callback should make sure that the fence will<br>
>>      // be signaled asap.<br>
>>      bool (*signaled)(struct fence *fence); // optional, but if set to NULL fence_is_signaled is not<br>
>>      // required to ever return true, unless enable_signaling is called, similar to has_signaled<br>
>>      long (*wait)(struct fence *fence, bool intr, signed long timeout); // required, but it can be set<br>
>>      // to the default fence_default_wait implementation which is recommended. It calls enable_signaling<br>
>>      // and appends itself to async callback list. Identical semantics to wait_event_interruptible_timeout.<br>
>>      void (*release)(struct fence *fence); // free_pt<br>
>> };<br>
>><br>
>> Because every fence has a stamp, there is no need for a compare op.<br>
>><br>
>> struct sync_timeline_ops {<br>
>>      const char *driver_name;<br>
>><br>
>>      /* required */<br>
>>      struct sync_pt *(*dup)(struct sync_pt *pt);<br>
>><br>
>>      /* required */<br>
>>      int (*has_signaled)(struct sync_pt *pt);<br>
>><br>
>>      /* required */<br>
>>      int (*compare)(struct sync_pt *a, struct sync_pt *b);<br>
>><br>
>>      /* optional */<br>
>>      void (*free_pt)(struct sync_pt *sync_pt);<br>
>><br>
>>      /* optional */<br>
>>      void (*release_obj)(struct sync_timeline *sync_timeline);<br>
>><br>
>>      /* deprecated */<br>
>>      void (*print_obj)(struct seq_file *s,<br>
>>                        struct sync_timeline *sync_timeline);<br>
>><br>
>>      /* deprecated */<br>
>>      void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);<br>
>><br>
>>      /* optional */<br>
>>      int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);<br>
>><br>
>>      /* optional */<br>
>>      void (*timeline_value_str)(struct sync_timeline *timeline, char *str,<br>
>>                                 int size);<br>
>><br>
>>      /* optional */<br>
>>      void (*pt_value_str)(struct sync_pt *pt, char *str, int size);<br>
>> };<br>
>><br>
>> The dup is weird, I have nothing like that. I do allow multiple callbacks to be added to the same<br>
>> dma-fence, and allow callbacks to be aborted, provided you still hold a refcount.<br>
>><br>
>> So from the ops it looks like what's mostly missing is print_pt, fill_driver_data,<br>
>> timeline_value_str and pt_value_str.<br>
>><br>
>> I have no idea how much of this is inaccurate. This is just an assessment based on me looking at<br>
>> the stuff in drivers/staging/android/sync for an afternoon and the earlier discussions. :)<br>
>><br>
> So I actually tried to implement it now. I killed all the deprecated members and assumed a linear timeline.<br>
> This means that syncpoints can only be added at the end, not in between. In particular it means sw_sync<br>
> might be slightly broken.<br>
><br>
> I only tested it with a simple program I wrote called ufence.c, it's in drivers/staging/android/ufence.c in the following tree:<br>
><br>
> <a href="http://cgit.freedesktop.org/~mlankhorst/linux" target="_blank">http://cgit.freedesktop.org/~mlankhorst/linux</a><br>
><br>
> the "rfc: convert android to fence api" has all the changes from my dma-fence proposal to what android would need,<br>
> it also converts the userspace fence api to use the dma-fence api.<br>
><br>
> sync_pt is implemented as fence too. This meant not having to convert all of android right away, though I did make some changes.<br>
> I killed the deprecated members and made all the fence calls forward to the sync_timeline_ops. dup and compare are no longer used.<br>
><br>
> I haven't given this a spin on a full android kernel, only with the components that are in mainline kernel under staging and my dumb test program.<br>
><br>
> ~Maarten<br>
><br>
> PS: The nomenclature is very confusing. I want to rename dma-fence to syncpoint, but I want some feedback from the android devs first. :)<br>
><br>
</div></div>Come on, any feedback? I want to move the discussion forward.<br>
<span class="HOEnZb"><font color="#888888"><br>
~Maarten<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
dri-devel mailing list<br>
<a href="mailto:dri-devel@lists.freedesktop.org">dri-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/dri-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/dri-devel</a><br>
</div></div></blockquote></div><br></div>