[RFC 27/29] dma-buf/fence: add .cleanup() callback

From: Gustavo Padovan
Date: Fri Jan 15 2016 - 09:58:15 EST


From: Gustavo Padovan <gustavo.padovan@xxxxxxxxxxxxxxx>

Called when the fence_timeline is destroyed so users can cleanup routines
on fences.

Signed-off-by: Gustavo Padovan <gustavo.padovan@xxxxxxxxxxxxxxx>
---
drivers/dma-buf/fence.c | 24 ++++++++++++++++++++++++
include/linux/fence.h | 4 ++++
2 files changed, 28 insertions(+)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 26f5f0f..3973b35 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -140,6 +140,9 @@ EXPORT_SYMBOL(fence_timeline_put);
*/
void fence_timeline_destroy(struct fence_timeline *timeline)
{
+ unsigned long flags;
+ struct fence *fence, *next;
+
timeline->destroyed = true;
/*
* Ensure timeline is marked as destroyed before
@@ -147,6 +150,15 @@ void fence_timeline_destroy(struct fence_timeline *timeline)
*/
smp_wmb();

+ spin_lock_irqsave(&timeline->lock, flags);
+ list_for_each_entry_safe(fence, next, &timeline->active_list_head,
+ active_list) {
+ if (fence->ops->cleanup)
+ fence->ops->cleanup(fence, fence->priv);
+ list_del_init(&fence->active_list);
+ }
+ spin_unlock_irqrestore(&timeline->lock, flags);
+
fence_timeline_put(timeline);
}
EXPORT_SYMBOL(fence_timeline_destroy);
@@ -839,3 +851,15 @@ fence_init(struct fence *fence, const struct fence_ops *ops,
trace_fence_init(fence);
}
EXPORT_SYMBOL(fence_init);
+
+/**
+ * fence_add_user_data - add private user data
+ * @fence: [in] the fence to use
+ * @user_data: [in] the private data to store
+ *
+ * This function adds a private user data point to struct fence.
+ */
+void fence_add_user_data(struct fence *fence, void *user_data)
+{
+ fence->priv = user_data;
+}
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 32a26ab..59eabe3 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -116,6 +116,7 @@ struct fence {
int status;
struct list_head child_list;
struct list_head active_list;
+ void *priv;
};

enum fence_flag_bits {
@@ -146,6 +147,7 @@ struct fence_cb {
* @enable_signaling: enable software signaling of fence.
* @signaled: [optional] peek whether the fence is signaled, can be null.
* @wait: custom wait implementation, or fence_default_wait.
+ * @cleanup: [optional] called when the timeline is destroyed
* @release: [optional] called on destruction of fence, can be null
* @fill_driver_data: [optional] callback to fill in free-form debug info
* Returns amount of bytes filled, or -errno.
@@ -205,6 +207,7 @@ struct fence_ops {
bool (*enable_signaling)(struct fence *fence);
bool (*signaled)(struct fence *fence);
signed long (*wait)(struct fence *fence, bool intr, signed long timeout);
+ void (*cleanup)(struct fence *fence, void *user_data);
void (*release)(struct fence *fence);

int (*fill_driver_data)(struct fence *fence, void *data, int size);
@@ -217,6 +220,7 @@ struct fence *fence_create_on_timeline(struct fence_timeline *obj,
unsigned int value);
void fence_init(struct fence *fence, const struct fence_ops *ops,
spinlock_t *lock, unsigned context, unsigned seqno);
+void fence_add_user_data(struct fence *fence, void *user_data);

void fence_release(struct kref *kref);
void fence_free(struct fence *fence);
--
2.5.0