Commit 9eee0dd7 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Protect timeline->hwsp dereferencing

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190919111912.21631-3-chris@chris-wilson.co.uk
parent 6a79d848
...@@ -500,17 +500,32 @@ int intel_timeline_read_hwsp(struct i915_request *from, ...@@ -500,17 +500,32 @@ int intel_timeline_read_hwsp(struct i915_request *from,
struct i915_request *to, struct i915_request *to,
u32 *hwsp) u32 *hwsp)
{ {
struct intel_timeline_cacheline *cl = from->hwsp_cacheline; struct intel_timeline *tl;
struct intel_timeline *tl = from->timeline;
int err; 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); GEM_BUG_ON(rcu_access_pointer(to->timeline) == tl);
mutex_lock_nested(&tl->mutex, SINGLE_DEPTH_NESTING); err = -EBUSY;
err = i915_request_completed(from); if (mutex_trylock(&tl->mutex)) {
if (!err) struct intel_timeline_cacheline *cl = from->hwsp_cacheline;
if (i915_request_completed(from)) {
err = 1;
goto unlock;
}
err = cacheline_ref(cl, to); err = cacheline_ref(cl, to);
if (!err) { if (err)
goto unlock;
if (likely(cl == tl->hwsp_cacheline)) { if (likely(cl == tl->hwsp_cacheline)) {
*hwsp = tl->hwsp_offset; *hwsp = tl->hwsp_offset;
} else { /* across a seqno wrap, recover the original offset */ } else { /* across a seqno wrap, recover the original offset */
...@@ -518,8 +533,11 @@ int intel_timeline_read_hwsp(struct i915_request *from, ...@@ -518,8 +533,11 @@ int intel_timeline_read_hwsp(struct i915_request *from,
ptr_unmask_bits(cl->vaddr, CACHELINE_BITS) * ptr_unmask_bits(cl->vaddr, CACHELINE_BITS) *
CACHELINE_BYTES; CACHELINE_BYTES;
} }
unlock:
mutex_unlock(&tl->mutex);
} }
mutex_unlock(&tl->mutex); intel_timeline_put(tl);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment