[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