From: John Stultz <john.stultz@linaro.org>
To: lkml <linux-kernel@vger.kernel.org>
Cc: Erik Gilling <konkers@android.com>,
Maarten Lankhorst <maarten.lankhorst@canonical.com>,
Daniel Vetter <daniel.vetter@ffwll.ch>,
Rob Clark <robclark@gmail.com>,
Sumit Semwal <sumit.semwal@linaro.org>,
Greg KH <gregkh@linuxfoundation.org>,
dri-devel@lists.freedesktop.org,
Android Kernel Team <kernel-team@android.com>,
John Stultz <john.stultz@linaro.org>
Subject: [PATCH 09/30] staging: sync: Allow async waits to be canceled
Date: Thu, 28 Feb 2013 16:43:05 -0800 [thread overview]
Message-ID: <1362098606-26469-10-git-send-email-john.stultz@linaro.org> (raw)
In-Reply-To: <1362098606-26469-1-git-send-email-john.stultz@linaro.org>
From: Erik Gilling <konkers@android.com>
In order to allow drivers to cleanly handled teardown we need to allow them
to cancel pending async waits. To do this cleanly, we move allocation of
sync_fence_waiter to the driver calling sync_async_wait().
Cc: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Cc: Erik Gilling <konkers@android.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Rob Clark <robclark@gmail.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: dri-devel@lists.freedesktop.org
Cc: Android Kernel Team <kernel-team@android.com>
Signed-off-by: Erik Gilling <konkers@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
drivers/staging/android/sync.c | 46 +++++++++++++++++++++++++++-------------
drivers/staging/android/sync.h | 36 +++++++++++++++++++++++++------
2 files changed, 60 insertions(+), 22 deletions(-)
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 9e35ea3..54f84d9 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -421,33 +421,22 @@ static void sync_fence_signal_pt(struct sync_pt *pt)
container_of(pos, struct sync_fence_waiter,
waiter_list);
- waiter->callback(fence, waiter->callback_data);
list_del(pos);
- kfree(waiter);
+ waiter->callback(fence, waiter);
}
wake_up(&fence->wq);
}
}
int sync_fence_wait_async(struct sync_fence *fence,
- void (*callback)(struct sync_fence *, void *data),
- void *callback_data)
+ struct sync_fence_waiter *waiter)
{
- struct sync_fence_waiter *waiter;
unsigned long flags;
int err = 0;
- waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL);
- if (waiter == NULL)
- return -ENOMEM;
-
- waiter->callback = callback;
- waiter->callback_data = callback_data;
-
spin_lock_irqsave(&fence->waiter_list_lock, flags);
if (fence->status) {
- kfree(waiter);
err = fence->status;
goto out;
}
@@ -459,6 +448,34 @@ out:
return err;
}
+int sync_fence_cancel_async(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter)
+{
+ struct list_head *pos;
+ struct list_head *n;
+ unsigned long flags;
+ int ret = -ENOENT;
+
+ spin_lock_irqsave(&fence->waiter_list_lock, flags);
+ /*
+ * Make sure waiter is still in waiter_list because it is possible for
+ * the waiter to be removed from the list while the callback is still
+ * pending.
+ */
+ list_for_each_safe(pos, n, &fence->waiter_list_head) {
+ struct sync_fence_waiter *list_waiter =
+ container_of(pos, struct sync_fence_waiter,
+ waiter_list);
+ if (list_waiter == waiter) {
+ list_del(pos);
+ ret = 0;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+ return ret;
+}
+
int sync_fence_wait(struct sync_fence *fence, long timeout)
{
int err;
@@ -739,8 +756,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
container_of(pos, struct sync_fence_waiter,
waiter_list);
- seq_printf(s, "waiter %pF %p\n", waiter->callback,
- waiter->callback_data);
+ seq_printf(s, "waiter %pF\n", waiter->callback);
}
spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
}
diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index 4f19938..943f414 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -159,6 +159,10 @@ struct sync_fence {
struct list_head sync_fence_list;
};
+struct sync_fence_waiter;
+typedef void (*sync_callback_t)(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter);
+
/**
* struct sync_fence_waiter - metadata for asynchronous waiter on a fence
* @waiter_list: membership in sync_fence.waiter_list_head
@@ -168,10 +172,15 @@ struct sync_fence {
struct sync_fence_waiter {
struct list_head waiter_list;
- void (*callback)(struct sync_fence *fence, void *data);
- void *callback_data;
+ sync_callback_t callback;
};
+static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
+ sync_callback_t callback)
+{
+ waiter->callback = callback;
+}
+
/*
* API for sync_timeline implementers
*/
@@ -284,16 +293,29 @@ void sync_fence_install(struct sync_fence *fence, int fd);
/**
* sync_fence_wait_async() - registers and async wait on the fence
* @fence: fence to wait on
- * @callback: callback
- * @callback_data data to pass to the callback
+ * @waiter: waiter callback struck
*
* Returns 1 if @fence has already signaled.
*
- * Registers a callback to be called when @fence signals or has an error
+ * Registers a callback to be called when @fence signals or has an error.
+ * @waiter should be initialized with sync_fence_waiter_init().
*/
int sync_fence_wait_async(struct sync_fence *fence,
- void (*callback)(struct sync_fence *, void *data),
- void *callback_data);
+ struct sync_fence_waiter *waiter);
+
+/**
+ * sync_fence_cancel_async() - cancels an async wait
+ * @fence: fence to wait on
+ * @waiter: waiter callback struck
+ *
+ * returns 0 if waiter was removed from fence's async waiter list.
+ * returns -ENOENT if waiter was not found on fence's async waiter list.
+ *
+ * Cancels a previously registered async wait. Will fail gracefully if
+ * @waiter was never registered or if @fence has already signaled @waiter.
+ */
+int sync_fence_cancel_async(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter);
/**
* sync_fence_wait() - wait on fence
--
1.7.10.4
next prev parent reply other threads:[~2013-03-01 0:49 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-01 0:42 [RFC][PATCH 00/30] staging: Android sync driver John Stultz
2013-03-01 0:42 ` [PATCH 01/30] staging: sync: Add synchronization framework John Stultz
2013-03-01 0:42 ` [PATCH 02/30] staging: sw_sync: Add cpu based sync driver John Stultz
2013-03-01 0:42 ` [PATCH 03/30] staging: sync: Add timestamps to sync_pts John Stultz
2013-03-01 0:43 ` [PATCH 04/30] staging: sync: Add debugfs support John Stultz
2013-03-01 0:43 ` [PATCH 05/30] staging: sw_sync: Add debug support John Stultz
2013-03-01 0:43 ` [PATCH 06/30] staging: sync: Add ioctl to get fence data John Stultz
2013-03-01 0:43 ` [PATCH 07/30] staging: sw_sync: Add fill_driver_data support John Stultz
2013-03-01 0:43 ` [PATCH 08/30] staging: sync: Add poll support John Stultz
2013-03-01 0:43 ` John Stultz [this message]
2013-03-01 0:43 ` [PATCH 10/30] staging: sync: Export sync API symbols John Stultz
2013-03-01 2:00 ` Greg KH
2013-03-01 3:59 ` John Stultz
2013-03-01 8:21 ` Erik Gilling
2013-03-01 13:55 ` Greg KH
2013-03-01 16:30 ` Erik Gilling
2013-03-01 22:47 ` Erik Gilling
2013-03-01 0:43 ` [PATCH 11/30] staging: sw_sync: Export sw_sync API John Stultz
2013-03-01 0:43 ` [PATCH 12/30] staging: sync: Reorder sync_fence_release John Stultz
2013-03-01 0:43 ` [PATCH 13/30] staging: sync: Optimize fence merges John Stultz
2013-03-01 0:43 ` [PATCH 14/30] staging: sync: Add internal refcounting to fences John Stultz
2013-03-01 0:43 ` [PATCH 15/30] staging: sync: Add reference counting to timelines John Stultz
2013-03-01 0:43 ` [PATCH 16/30] staging: sync: Fix error paths John Stultz
2013-03-01 0:43 ` [PATCH 17/30] staging: sw_sync: " John Stultz
2013-03-01 0:43 ` [PATCH 18/30] staging: sync: Change wait timeout to mirror poll semantics John Stultz
2013-03-01 0:43 ` [PATCH 19/30] staging: sync: Dump sync state to console on timeout John Stultz
2013-03-01 0:43 ` [PATCH 20/30] staging: sync: Improve timeout dump messages John Stultz
2013-03-01 0:43 ` [PATCH 21/30] staging: sync: Dump sync state on fence errors John Stultz
2013-03-01 0:43 ` [PATCH 22/30] staging: sync: Protect unlocked access to fence status John Stultz
2013-03-01 0:43 ` [PATCH 23/30] staging: sync: Update new fence status with sync_fence_signal_pt John Stultz
2013-03-01 0:43 ` [PATCH 24/30] staging: sync: Use proper barriers when waiting indefinitely John Stultz
2013-03-01 0:43 ` [PATCH 25/30] staging: sync: Refactor sync debug printing John Stultz
2013-03-01 0:43 ` [PATCH 26/30] staging: sw_sync: Convert to use new value_str debug ops John Stultz
2013-03-01 0:43 ` [PATCH 27/30] staging: sync: Add tracepoint support John Stultz
2013-03-01 0:43 ` [PATCH 28/30] staging: sync: Fix race condition between merge and signal John Stultz
2013-03-01 0:43 ` [PATCH 29/30] staging: sync: Don't log wait timeouts when timeout = 0 John Stultz
2013-03-01 0:43 ` [PATCH 30/30] staging: sync: Fix timeout = 0 wait behavior John Stultz
2013-03-01 1:59 ` [RFC][PATCH 00/30] staging: Android sync driver Greg KH
2013-03-01 16:20 ` Erik Gilling
2013-03-03 18:42 ` Daniel Vetter
2013-03-03 18:52 ` animelovin
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=1362098606-26469-10-git-send-email-john.stultz@linaro.org \
--to=john.stultz@linaro.org \
--cc=daniel.vetter@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=gregkh@linuxfoundation.org \
--cc=kernel-team@android.com \
--cc=konkers@android.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@canonical.com \
--cc=robclark@gmail.com \
--cc=sumit.semwal@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome