@@ -173,26 +173,34 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl)
173173 intel_engine_add_retire (b -> irq_engine , tl );
174174}
175175
176- static bool __signal_request (struct i915_request * rq , struct list_head * signals )
176+ static bool __signal_request (struct i915_request * rq )
177177{
178- clear_bit (I915_FENCE_FLAG_SIGNAL , & rq -> fence .flags );
179-
180178 if (!__dma_fence_signal (& rq -> fence )) {
181179 i915_request_put (rq );
182180 return false;
183181 }
184182
185- list_add_tail (& rq -> signal_link , signals );
186183 return true;
187184}
188185
186+ static struct llist_node *
187+ slist_add (struct llist_node * node , struct llist_node * head )
188+ {
189+ node -> next = head ;
190+ return node ;
191+ }
192+
189193static void signal_irq_work (struct irq_work * work )
190194{
191195 struct intel_breadcrumbs * b = container_of (work , typeof (* b ), irq_work );
192196 const ktime_t timestamp = ktime_get ();
197+ struct llist_node * signal , * sn ;
193198 struct intel_context * ce , * cn ;
194199 struct list_head * pos , * next ;
195- LIST_HEAD (signal );
200+
201+ signal = NULL ;
202+ if (unlikely (!llist_empty (& b -> signaled_requests )))
203+ signal = llist_del_all (& b -> signaled_requests );
196204
197205 spin_lock (& b -> irq_lock );
198206
@@ -224,8 +232,6 @@ static void signal_irq_work(struct irq_work *work)
224232 if (b -> irq_armed && list_empty (& b -> signalers ))
225233 __intel_breadcrumbs_disarm_irq (b );
226234
227- list_splice_init (& b -> signaled_requests , & signal );
228-
229235 list_for_each_entry_safe (ce , cn , & b -> signalers , signal_link ) {
230236 GEM_BUG_ON (list_empty (& ce -> signals ));
231237
@@ -242,7 +248,10 @@ static void signal_irq_work(struct irq_work *work)
242248 * spinlock as the callback chain may end up adding
243249 * more signalers to the same context or engine.
244250 */
245- __signal_request (rq , & signal );
251+ clear_bit (I915_FENCE_FLAG_SIGNAL , & rq -> fence .flags );
252+ if (__signal_request (rq ))
253+ /* We own signal_node now, xfer to local list */
254+ signal = slist_add (& rq -> signal_node , signal );
246255 }
247256
248257 /*
@@ -262,9 +271,9 @@ static void signal_irq_work(struct irq_work *work)
262271
263272 spin_unlock (& b -> irq_lock );
264273
265- list_for_each_safe ( pos , next , & signal ) {
274+ llist_for_each_safe ( signal , sn , signal ) {
266275 struct i915_request * rq =
267- list_entry ( pos , typeof (* rq ), signal_link );
276+ llist_entry ( signal , typeof (* rq ), signal_node );
268277 struct list_head cb_list ;
269278
270279 spin_lock (& rq -> lock );
@@ -291,7 +300,7 @@ intel_breadcrumbs_create(struct intel_engine_cs *irq_engine)
291300
292301 spin_lock_init (& b -> irq_lock );
293302 INIT_LIST_HEAD (& b -> signalers );
294- INIT_LIST_HEAD (& b -> signaled_requests );
303+ init_llist_head (& b -> signaled_requests );
295304
296305 init_irq_work (& b -> irq_work , signal_irq_work );
297306
@@ -355,7 +364,8 @@ static void insert_breadcrumb(struct i915_request *rq,
355364 * its signal completion.
356365 */
357366 if (__request_completed (rq )) {
358- if (__signal_request (rq , & b -> signaled_requests ))
367+ if (__signal_request (rq ) &&
368+ llist_add (& rq -> signal_node , & b -> signaled_requests ))
359369 irq_work_queue (& b -> irq_work );
360370 return ;
361371 }
0 commit comments