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 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel