[Intel-gfx] [PATCH 4/4] drm/i915: Protect timeline->hwsp dereferencing
Chris Wilson
chris at chris-wilson.co.uk
Thu Sep 19 11:18:28 UTC 2019
Quoting Tvrtko Ursulin (2019-09-19 11:48:25)
>
> On 18/09/2019 15:54, Chris Wilson wrote:
> > As not only is the signal->timeline volatile, so will be acquiring the
> > timeline's HWSP. We must first carefully acquire the timeline from the
> > signaling request and then lock the timeline. With the removal of the
> > struct_mutex serialisation of request construction, we can have multiple
> > timelines active at once, and so we must avoid using the nested mutex
> > lock as it is quite possible for both timelines to be establishing
> > semaphores on the other and so deadlock.
> >
> > Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> > Cc: Tvrtko Ursulin <tvrtko.ursulin at linux.intel.com>
> > ---
> > drivers/gpu/drm/i915/gt/intel_timeline.c | 32 ++++++++++++++++++------
> > 1 file changed, 25 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
> > index 2ce81bdf7f86..7b1d4098dd2e 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_timeline.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
> > @@ -500,17 +500,32 @@ int intel_timeline_read_hwsp(struct i915_request *from,
> > struct i915_request *to,
> > u32 *hwsp)
> > {
> > - struct intel_timeline_cacheline *cl = from->hwsp_cacheline;
> > - struct intel_timeline *tl = from->timeline;
>
> I think this should have been annotated in 2/4.
I left it un-annotated so that it would be left with a warning, as I felt
this change was substantial enough to merit its own patch.
> > + struct intel_timeline *tl;
> > int err;
> >
> > + rcu_read_lock();
> > + tl = rcu_dereference(from->timeline);
> > + if (i915_request_completed(from) || !kref_get_unless_zero(&tl->kref))
> > + tl = NULL;
> > + rcu_read_unlock();
> > + if (!tl) /* already completed */
> > + return 1;
> > +
> > GEM_BUG_ON(rcu_access_pointer(to->timeline) == tl);
> >
> > - mutex_lock_nested(&tl->mutex, SINGLE_DEPTH_NESTING);
> > - err = i915_request_completed(from);
> > - if (!err)
> > + err = -EBUSY;
> > + if (mutex_trylock(&tl->mutex)) {
> > + struct intel_timeline_cacheline *cl = from->hwsp_cacheline;
> > +
> > + if (i915_request_completed(from)) {
> > + err = 1;
> > + goto unlock;
> > + }
> > +
> > err = cacheline_ref(cl, to);
> > - if (!err) {
> > + if (err)
> > + goto unlock;
> > +
> > if (likely(cl == tl->hwsp_cacheline)) {
> > *hwsp = tl->hwsp_offset;
> > } else { /* across a seqno wrap, recover the original offset */
> > @@ -518,8 +533,11 @@ int intel_timeline_read_hwsp(struct i915_request *from,
> > ptr_unmask_bits(cl->vaddr, CACHELINE_BITS) *
> > CACHELINE_BYTES;
> > }
> > +
> > +unlock:
> > + mutex_unlock(&tl->mutex);
> > }
> > - mutex_unlock(&tl->mutex);
> > + intel_timeline_put(tl);
> >
> > return err;
> > }
> >
>
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Thanks,
-Chris
More information about the Intel-gfx
mailing list