hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/dma-buf/sw_sync.c
....@@ -193,6 +193,7 @@
193193 */
194194 static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
195195 {
196
+ LIST_HEAD(signalled);
196197 struct sync_pt *pt, *next;
197198
198199 trace_sync_timeline(obj);
....@@ -205,21 +206,20 @@
205206 if (!timeline_fence_signaled(&pt->base))
206207 break;
207208
208
- list_del_init(&pt->link);
209
+ dma_fence_get(&pt->base);
210
+
211
+ list_move_tail(&pt->link, &signalled);
209212 rb_erase(&pt->node, &obj->pt_tree);
210213
211
- /*
212
- * A signal callback may release the last reference to this
213
- * fence, causing it to be freed. That operation has to be
214
- * last to avoid a use after free inside this loop, and must
215
- * be after we remove the fence from the timeline in order to
216
- * prevent deadlocking on timeline->lock inside
217
- * timeline_fence_release().
218
- */
219214 dma_fence_signal_locked(&pt->base);
220215 }
221216
222217 spin_unlock_irq(&obj->lock);
218
+
219
+ list_for_each_entry_safe(pt, next, &signalled, link) {
220
+ list_del_init(&pt->link);
221
+ dma_fence_put(&pt->base);
222
+ }
223223 }
224224
225225 /**