[PATCH 1/2] dma-buf/sw_sync: put fence signaling into work item
Christian König
ckoenig.leichtzumerken at gmail.com
Tue Aug 12 14:34:01 UTC 2025
From: Christian König <ckoenig at able.fritz.box>
Offload signaling fence in the sw_sync component into a work item to
improve testing the real world signaling conditions.
Needs more testing before pushing it upstream!
Signed-off-by: Christian König <ckoenig at able.fritz.box>
---
drivers/dma-buf/sw_sync.c | 25 ++++++++++++++-----------
drivers/dma-buf/sync_debug.h | 2 ++
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 3c20f1d31cf5..43b8ac32482d 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -80,6 +80,7 @@ struct sw_sync_get_deadline {
#define SW_SYNC_HAS_DEADLINE_BIT DMA_FENCE_FLAG_USER_BITS
+static void sync_timeline_signal(struct work_struct *work);
static const struct dma_fence_ops timeline_fence_ops;
static inline struct sync_pt *dma_fence_to_sync_pt(struct dma_fence *fence)
@@ -110,6 +111,7 @@ static struct sync_timeline *sync_timeline_create(const char *name)
obj->pt_tree = RB_ROOT;
INIT_LIST_HEAD(&obj->pt_list);
+ INIT_WORK(&obj->signal_work, sync_timeline_signal);
spin_lock_init(&obj->lock);
sync_timeline_debug_add(obj);
@@ -123,6 +125,7 @@ static void sync_timeline_free(struct kref *kref)
container_of(kref, struct sync_timeline, kref);
sync_timeline_debug_remove(obj);
+ flush_work(&obj->signal_work);
kfree(obj);
}
@@ -199,23 +202,20 @@ static const struct dma_fence_ops timeline_fence_ops = {
/**
* sync_timeline_signal() - signal a status change on a sync_timeline
- * @obj: sync_timeline to signal
- * @inc: num to increment on timeline->value
+ * @work: the work item
*
- * A sync implementation should call this any time one of it's fences
- * has signaled or has an error condition.
+ * Signal all fences where the sequence number indicate to do so.
*/
-static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
+static void sync_timeline_signal(struct work_struct *work)
{
+ struct sync_timeline *obj = container_of(work, typeof(*obj),
+ signal_work);
LIST_HEAD(signalled);
struct sync_pt *pt, *next;
trace_sync_timeline(obj);
spin_lock_irq(&obj->lock);
-
- obj->value += inc;
-
list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
if (!timeline_fence_signaled(&pt->base))
break;
@@ -227,7 +227,6 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
dma_fence_signal_locked(&pt->base);
}
-
spin_unlock_irq(&obj->lock);
list_for_each_entry_safe(pt, next, &signalled, link) {
@@ -394,11 +393,15 @@ static long sw_sync_ioctl_inc(struct sync_timeline *obj, unsigned long arg)
return -EFAULT;
while (value > INT_MAX) {
- sync_timeline_signal(obj, INT_MAX);
+ obj->value += INT_MAX;
+
+ schedule_work(&obj->signal_work);
+ flush_work(&obj->signal_work);
value -= INT_MAX;
}
- sync_timeline_signal(obj, value);
+ obj->value += value;
+ schedule_work(&obj->signal_work);
return 0;
}
diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
index 02af347293d0..a1b03c48d82a 100644
--- a/drivers/dma-buf/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -17,6 +17,7 @@
#include <linux/rbtree.h>
#include <linux/spinlock.h>
#include <linux/dma-fence.h>
+#include <linux/workqueue.h>
#include <linux/sync_file.h>
#include <uapi/linux/sync_file.h>
@@ -40,6 +41,7 @@ struct sync_timeline {
struct rb_root pt_tree;
struct list_head pt_list;
+ struct work_struct signal_work;
spinlock_t lock;
struct list_head sync_timeline_list;
--
2.43.0
More information about the dri-devel
mailing list