Skip to content

Commit eb0104e

Browse files
icklerodrigovivi
authored andcommitted
drm/i915/gt: Track signaled breadcrumbs outside of the breadcrumb spinlock
Make b->signaled_requests a lockless-list so that we can manipulate it outside of the b->irq_lock. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201123113717.20500-2-chris@chris-wilson.co.uk (cherry picked from commit 6cfe66e) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 08b49e1 commit eb0104e

3 files changed

Lines changed: 28 additions & 14 deletions

File tree

drivers/gpu/drm/i915/gt/intel_breadcrumbs.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
189193
static 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
}

drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct intel_breadcrumbs {
3535
struct intel_engine_cs *irq_engine;
3636

3737
struct list_head signalers;
38-
struct list_head signaled_requests;
38+
struct llist_head signaled_requests;
3939

4040
struct irq_work irq_work; /* for use from inside irq_lock */
4141

drivers/gpu/drm/i915/i915_request.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,11 @@ struct i915_request {
176176
struct intel_context *context;
177177
struct intel_ring *ring;
178178
struct intel_timeline __rcu *timeline;
179-
struct list_head signal_link;
179+
180+
union {
181+
struct list_head signal_link;
182+
struct llist_node signal_node;
183+
};
180184

181185
/*
182186
* The rcu epoch of when this request was allocated. Used to judiciously

0 commit comments

Comments
 (0)