On Tue, Feb 28, 2017 at 09:09:04AM +0000, Chris Wilson wrote: > 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. > > v2: __i915_guc_submit needs the full irqsave spinlock. > > Fixes: 67b807a89230 ("drm/i915: Delay disabling the user interrupt for breadcrumbs") > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> > Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_guc_submission.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c > index beec88a30347..cbe0f509699c 100644 > --- a/drivers/gpu/drm/i915/i915_guc_submission.c > +++ b/drivers/gpu/drm/i915/i915_guc_submission.c > @@ -348,7 +348,7 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request) > u32 freespace; > int ret; > > - spin_lock(&client->wq_lock); > + spin_lock_irq(&client->wq_lock); > freespace = CIRC_SPACE(client->wq_tail, desc->head, client->wq_size); > freespace -= client->wq_rsvd; > if (likely(freespace >= wqi_size)) { > @@ -358,7 +358,7 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request) > client->no_wq_space++; > ret = -EAGAIN; > } > - spin_unlock(&client->wq_lock); > + spin_unlock_irq(&client->wq_lock); > > return ret; > } > @@ -367,12 +367,13 @@ void i915_guc_wq_unreserve(struct drm_i915_gem_request *request) > { > const size_t wqi_size = sizeof(struct guc_wq_item); > struct i915_guc_client *client = request->i915->guc.execbuf_client; > + unsigned long flags; > > GEM_BUG_ON(READ_ONCE(client->wq_rsvd) < wqi_size); > > - spin_lock(&client->wq_lock); > + spin_lock_irqsave(&client->wq_lock, flags); > client->wq_rsvd -= wqi_size; > - spin_unlock(&client->wq_lock); > + spin_unlock_irqrestore(&client->wq_lock, flags); Should we just use cmpxchg here? unsigned int new, old; do { old = client->wq_rsvd; new = old - wqi_size; } while (cmpxchg(&clint->wq_rsvd, old, new) != old); > } > > /* Construct a Work Item and append it to the GuC's Work Queue */ > @@ -951,10 +952,15 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) > engine->schedule = NULL; > > /* Replay the current set of previously submitted requests */ > + spin_lock_irq(&engine->timeline->lock); > list_for_each_entry(rq, &engine->timeline->requests, link) { > + spin_lock(&client->wq_lock); > client->wq_rsvd += sizeof(struct guc_wq_item); > + spin_unlock(&client->wq_lock); And here. So perhaps: static void guc_wq_add_reserved(client, int delta); -Chris -- Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx