All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maarten Lankhorst <maarten.lankhorst@canonical.com>
To: Colin Cross <ccross@google.com>
Cc: "linaro-mm-sig@lists.linaro.org" <linaro-mm-sig@lists.linaro.org>,
	Android Kernel Team <kernel-team@android.com>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>
Subject: Re: [Linaro-mm-sig] thoughts of looking at android fences
Date: Mon, 04 Nov 2013 11:31:26 +0100	[thread overview]
Message-ID: <5277777E.5060904@canonical.com> (raw)
In-Reply-To: <CAMbhsRQ67B+MLLp-YhYhegDrOWp9AYN8eAaZnjdTc-wuwnM9vA@mail.gmail.com>

op 02-11-13 22:36, Colin Cross schreef:
> On Wed, Oct 30, 2013 at 5:17 AM, Maarten Lankhorst
> <maarten.lankhorst@canonical.com> wrote:
>> op 24-10-13 14:13, Maarten Lankhorst schreef:
>>> So I actually tried to implement it now. I killed all the deprecated members and assumed a linear timeline.
>>> This means that syncpoints can only be added at the end, not in between. In particular it means sw_sync
>>> might be slightly broken.
>>>
>>> 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:
>>>
>>> http://cgit.freedesktop.org/~mlankhorst/linux
>>>
>>> the "rfc: convert android to fence api" has all the changes from my dma-fence proposal to what android would need,
>>> it also converts the userspace fence api to use the dma-fence api.
>>>
>>> sync_pt is implemented as fence too. This meant not having to convert all of android right away, though I did make some changes.
>>> I killed the deprecated members and made all the fence calls forward to the sync_timeline_ops. dup and compare are no longer used.
>>>
>>> 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.
>>>
>>> ~Maarten
>>>
>>> PS: The nomenclature is very confusing. I want to rename dma-fence to syncpoint, but I want some feedback from the android devs first. :)
>>>
>> Come on, any feedback? I want to move the discussion forward.
>>
>> ~Maarten
> I experimented with it a little on a device that uses sync and came
> across a few bugs:
> 1.  sync_timeline_signal needs to call __fence_signal on all signaled
> points on the timeline, not just the first
> 2.  fence_add_callback doesn't always initialize cb.node
> 3.  sync_fence_wait should take ms
> 4.  sync_print_pt status printing was incorrect
> 5.  there is a deadlock:
>    sync_print_obj takes obj->child_list_lock
>    sync_print_pt
>    fence_is_signaled
>    fence_signal takes fence->lock == obj->child_list_lock
> 6.  freeing a timeline before all the fences holding points on that
> timeline have timed out results in a crash
>
> With the attached patch to fix these issues, our libsync and sync_test
> give the same results as with our sync code.  I haven't tested against
> the full Android framework yet.
>
> The compare op and timeline ordering is critical to the efficiency of
> sync points on Android.  The compare op is used when merging fences to
> drop all but the latest point on the same timeline.  This is necessary
> for example when the same buffer is submitted to the display on
> multiple frames, like when there is a live wallpaper in the background
> updating at 60 fps and a static screen of widgets on top of it.  The
> static widget buffer is submitted on every frame, returning a new
> fence each time.  The compositor merges the new fence with the fence
> for the previous buffer, and because they are on the same timeline it
> merges down to a single point.  I experimented with disabling the
> merge optimization on a Nexus 10, and found that leaving the screen on
> running a live wallpaper eventually resulted in 100k outstanding sync
> points.

Well, here I did the same for dma-fence, can you take a look?

---

diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 2c7fd3f2ab23..d1d89f1f8553 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -232,39 +232,62 @@ void sync_fence_install(struct sync_fence *fence, int fd)
 }
 EXPORT_SYMBOL(sync_fence_install);
 
+static void sync_fence_add_pt(struct sync_fence *fence, int *i, struct fence *pt) {
+	fence->cbs[*i].sync_pt = pt;
+	fence->cbs[*i].fence = fence;
+
+	if (!fence_add_callback(pt, &fence->cbs[*i].cb, fence_check_cb_func)) {
+		fence_get(pt);
+		(*i)++;
+	}
+}
+
 struct sync_fence *sync_fence_merge(const char *name,
 				    struct sync_fence *a, struct sync_fence *b)
 {
 	int num_fences = a->num_fences + b->num_fences;
 	struct sync_fence *fence;
-	int i;
+	int i, i_a, i_b;
 
 	fence = sync_fence_alloc(offsetof(struct sync_fence, cbs[num_fences]), name);
 	if (fence == NULL)
 		return NULL;
 
-	fence->num_fences = num_fences;
 	atomic_set(&fence->status, num_fences);
 
-	for (i = 0; i < a->num_fences; ++i) {
-		struct fence *pt = a->cbs[i].sync_pt;
-
-		fence_get(pt);
-		fence->cbs[i].sync_pt = pt;
-		fence->cbs[i].fence = fence;
-		if (fence_add_callback(pt, &fence->cbs[i].cb, fence_check_cb_func))
-			atomic_dec(&fence->status);
+	/*
+	 * Assume sync_fence a and b are both ordered and have no
+	 * duplicates with the same context.
+	 *
+	 * If a sync_fence can only be created with sync_fence_merge
+	 * and sync_fence_create, this is a reasonable assumption.
+	 */
+	for (i = i_a = i_b = 0; i_a < a->num_fences || i_b < b->num_fences; ) {
+		struct fence *pt_a = i_a < a->num_fences ? a->cbs[i_a].sync_pt : NULL;
+		struct fence *pt_b = i_b < b->num_fences ? b->cbs[i_b].sync_pt : NULL;
+
+		if (!pt_b || pt_a->context < pt_b->context) {
+			sync_fence_add_pt(fence, &i, pt_a);
+
+			i_a++;
+		} else if (!pt_a || pt_a->context > pt_b->context) {
+			sync_fence_add_pt(fence, &i, pt_b);
+
+			i_b++;
+		} else {
+			if (pt_a->seqno - pt_b->seqno <= INT_MAX)
+				sync_fence_add_pt(fence, &i, pt_a);
+			else
+				sync_fence_add_pt(fence, &i, pt_b);
+
+			i_a++;
+			i_b++;
+		}
 	}
 
-	for (i = 0; i < b->num_fences; ++i) {
-		struct fence *pt = b->cbs[i].sync_pt;
-
-		fence_get(pt);
-		fence->cbs[a->num_fences + i].sync_pt = pt;
-		fence->cbs[a->num_fences + i].fence = fence;
-		if (fence_add_callback(pt, &fence->cbs[a->num_fences + i].cb, fence_check_cb_func))
-			atomic_dec(&fence->status);
-	}
+	if (num_fences > i)
+		atomic_sub(num_fences - i, &fence->status);
+	fence->num_fences = i;
 
 	sync_fence_debug_add(fence);
 	return fence;

  parent reply	other threads:[~2013-11-04 10:31 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-02  7:35 thoughts of looking at android fences Maarten Lankhorst
2013-10-02 18:13 ` [Linaro-mm-sig] " Erik Gilling
2013-10-08 17:37   ` John Stultz
2013-10-08 18:56     ` Rob Clark
2013-10-09 14:39     ` Maarten Lankhorst
2013-10-24 12:13       ` Maarten Lankhorst
2013-10-30 12:17         ` Maarten Lankhorst
2013-11-01 21:03           ` Rom Lemarchand
2013-11-02 21:36           ` Colin Cross
2013-11-03  6:31             ` Maarten Lankhorst
2013-11-04  9:36             ` Maarten Lankhorst
2013-11-04 10:31             ` Maarten Lankhorst [this message]
2013-11-07 21:11               ` Rom Lemarchand
2013-11-08 10:43                 ` Maarten Lankhorst
2013-11-08 11:43                 ` Maarten Lankhorst
2013-11-08 14:35                   ` Rom Lemarchand
2013-11-12  1:53                   ` Rom Lemarchand
2013-10-08 18:47   ` Rob Clark

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5277777E.5060904@canonical.com \
    --to=maarten.lankhorst@canonical.com \
    --cc=ccross@google.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kernel-team@android.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.