@@ -89,17 +89,20 @@ void intel_context_exit_engine(struct intel_context *ce);
static inline void intel_context_enter(struct intel_context *ce)
{
+ lockdep_assert_held(&ce->timeline->mutex);
if (!ce->active_count++)
ce->ops->enter(ce);
}
static inline void intel_context_mark_active(struct intel_context *ce)
{
+ lockdep_assert_held(&ce->timeline->mutex);
++ce->active_count;
}
static inline void intel_context_exit(struct intel_context *ce)
{
+ lockdep_assert_held(&ce->timeline->mutex);
GEM_BUG_ON(!ce->active_count);
if (!--ce->active_count)
ce->ops->exit(ce);
@@ -61,7 +61,7 @@ struct intel_context {
u32 *lrc_reg_state;
u64 lrc_desc;
- unsigned int active_count; /* notionally protected by timeline->mutex */
+ unsigned int active_count; /* protected by timeline->mutex */
atomic_t pin_count;
struct mutex pin_mutex; /* guards pinning and associated on-gpuing */
@@ -37,6 +37,16 @@ static int __engine_unpark(struct intel_wakeref *wf)
return 0;
}
+static inline void __timeline_mark_lock(struct intel_context *ce)
+{
+ mutex_acquire(&ce->timeline->mutex.dep_map, 2, 0, _THIS_IP_);
+}
+
+static inline void __timeline_mark_unlock(struct intel_context *ce)
+{
+ mutex_release(&ce->timeline->mutex.dep_map, 0, _THIS_IP_);
+}
+
static bool switch_to_kernel_context(struct intel_engine_cs *engine)
{
struct i915_request *rq;
@@ -61,6 +71,8 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
* retiring the last request, thus all rings should be empty and
* all timelines idle.
*/
+ __timeline_mark_lock(engine->kernel_context);
+
rq = __i915_request_create(engine->kernel_context, GFP_NOWAIT);
if (IS_ERR(rq))
/* Context switch failed, hope for the best! Maybe reset? */
@@ -80,6 +92,8 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
__intel_wakeref_defer_park(&engine->wakeref);
__i915_request_queue(rq, NULL);
+ __timeline_mark_unlock(engine->kernel_context);
+
return false;
}
@@ -338,6 +338,8 @@ void intel_timeline_enter(struct intel_timeline *tl)
{
struct intel_gt_timelines *timelines = &tl->gt->timelines;
+ lockdep_assert_held(&tl->mutex);
+
GEM_BUG_ON(!atomic_read(&tl->pin_count));
if (tl->active_count++)
return;
@@ -352,6 +354,8 @@ void intel_timeline_exit(struct intel_timeline *tl)
{
struct intel_gt_timelines *timelines = &tl->gt->timelines;
+ lockdep_assert_held(&tl->mutex);
+
GEM_BUG_ON(!tl->active_count);
if (--tl->active_count)
return;
@@ -1087,7 +1087,8 @@ __i915_request_add_to_timeline(struct i915_request *rq)
* precludes optimising to use semaphores serialisation of a single
* timeline across engines.
*/
- prev = rcu_dereference_protected(timeline->last_request.request, 1);
+ prev = rcu_dereference_protected(timeline->last_request.request,
+ lockdep_is_held(&timeline->mutex));
if (prev && !i915_request_completed(prev)) {
if (is_power_of_2(prev->engine->mask | rq->engine->mask))
i915_sw_fence_await_sw_fence(&rq->submit,