Skip to content

Commit 349ab91

Browse files
committed
drm/i915/guc: Make wq_lock irq-safe
Following the use of dma_fence_signal() from within our interrupt handler, we need to make guc->wq_lock also irq-safe. This was done previously as part of the guc scheduler patch (which also started mixing our fences with the interrupt handler), but is now required to fix the current guc submission backend. v4: Document that __i915_guc_submit is always under an irq disabled section v5: Move wq_rsvd adjustment to its own function Fixes: 67b807a ("drm/i915: Delay disabling the user interrupt for breadcrumbs") Signed-off-by: Chris Wilson <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Cc: Mika Kuoppala <[email protected]> Reviewed-by: Michal Wajdeczko <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Tvrtko Ursulin <[email protected]>
1 parent 1e08a26 commit 349ab91

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

drivers/gpu/drm/i915/i915_guc_submission.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request)
348348
u32 freespace;
349349
int ret;
350350

351-
spin_lock(&client->wq_lock);
351+
spin_lock_irq(&client->wq_lock);
352352
freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size);
353353
freespace -= client->wq_rsvd;
354354
if (likely(freespace >= wqi_size)) {
@@ -358,21 +358,27 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request)
358358
client->no_wq_space++;
359359
ret = -EAGAIN;
360360
}
361-
spin_unlock(&client->wq_lock);
361+
spin_unlock_irq(&client->wq_lock);
362362

363363
return ret;
364364
}
365365

366+
static void guc_client_update_wq_rsvd(struct i915_guc_client *client, int size)
367+
{
368+
unsigned long flags;
369+
370+
spin_lock_irqsave(&client->wq_lock, flags);
371+
client->wq_rsvd += size;
372+
spin_unlock_irqrestore(&client->wq_lock, flags);
373+
}
374+
366375
void i915_guc_wq_unreserve(struct drm_i915_gem_request *request)
367376
{
368-
const size_t wqi_size = sizeof(struct guc_wq_item);
377+
const int wqi_size = sizeof(struct guc_wq_item);
369378
struct i915_guc_client *client = request->i915->guc.execbuf_client;
370379

371380
GEM_BUG_ON(READ_ONCE(client->wq_rsvd) < wqi_size);
372-
373-
spin_lock(&client->wq_lock);
374-
client->wq_rsvd -= wqi_size;
375-
spin_unlock(&client->wq_lock);
381+
guc_client_update_wq_rsvd(client, -wqi_size);
376382
}
377383

378384
/* Construct a Work Item and append it to the GuC's Work Queue */
@@ -511,6 +517,9 @@ static void __i915_guc_submit(struct drm_i915_gem_request *rq)
511517
struct i915_guc_client *client = guc->execbuf_client;
512518
int b_ret;
513519

520+
/* We are always called with irqs disabled */
521+
GEM_BUG_ON(!irqs_disabled());
522+
514523
spin_lock(&client->wq_lock);
515524
guc_wq_item_append(client, rq);
516525

@@ -945,16 +954,19 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
945954

946955
/* Take over from manual control of ELSP (execlists) */
947956
for_each_engine(engine, dev_priv, id) {
957+
const int wqi_size = sizeof(struct guc_wq_item);
948958
struct drm_i915_gem_request *rq;
949959

950960
engine->submit_request = i915_guc_submit;
951961
engine->schedule = NULL;
952962

953963
/* Replay the current set of previously submitted requests */
964+
spin_lock_irq(&engine->timeline->lock);
954965
list_for_each_entry(rq, &engine->timeline->requests, link) {
955-
client->wq_rsvd += sizeof(struct guc_wq_item);
966+
guc_client_update_wq_rsvd(client, wqi_size);
956967
__i915_guc_submit(rq);
957968
}
969+
spin_unlock_irq(&engine->timeline->lock);
958970
}
959971

960972
return 0;

0 commit comments

Comments
 (0)