Commit d1cee2d3 authored by Matthew Brost's avatar Matthew Brost Committed by John Harrison
Browse files

drm/i915: Move active request tracking to a vfunc



Move active request tracking to a backend vfunc rather than assuming all
backends want to do this in the manner. In the of case execlists /
ring submission the tracking is on the physical engine while with GuC
submission it is on the context.

Signed-off-by: default avatarMatthew Brost <matthew.brost@intel.com>
Reviewed-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Signed-off-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210727002348.97202-8-matthew.brost@intel.com
parent 27466222
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -393,6 +393,9 @@ intel_context_init(struct intel_context *ce, struct intel_engine_cs *engine)
	spin_lock_init(&ce->guc_state.lock);
	INIT_LIST_HEAD(&ce->guc_state.fences);

	spin_lock_init(&ce->guc_active.lock);
	INIT_LIST_HEAD(&ce->guc_active.requests);

	ce->guc_id = GUC_INVALID_LRC_ID;
	INIT_LIST_HEAD(&ce->guc_id_link);

+7 −0
Original line number Diff line number Diff line
@@ -162,6 +162,13 @@ struct intel_context {
		struct list_head fences;
	} guc_state;

	struct {
		/** lock: protects everything in guc_active */
		spinlock_t lock;
		/** requests: active requests on this context */
		struct list_head requests;
	} guc_active;

	/* GuC scheduling state flags that do not require a lock. */
	atomic_t guc_sched_state_no_lock;

+6 −0
Original line number Diff line number Diff line
@@ -414,6 +414,12 @@ struct intel_engine_cs {

	void		(*release)(struct intel_engine_cs *engine);

	/*
	 * Add / remove request from engine active tracking
	 */
	void		(*add_active_request)(struct i915_request *rq);
	void		(*remove_active_request)(struct i915_request *rq);

	struct intel_engine_execlists execlists;

	/*
+40 −0
Original line number Diff line number Diff line
@@ -3157,6 +3157,42 @@ static void execlists_park(struct intel_engine_cs *engine)
	cancel_timer(&engine->execlists.preempt);
}

static void add_to_engine(struct i915_request *rq)
{
	lockdep_assert_held(&rq->engine->sched_engine->lock);
	list_move_tail(&rq->sched.link, &rq->engine->sched_engine->requests);
}

static void remove_from_engine(struct i915_request *rq)
{
	struct intel_engine_cs *engine, *locked;

	/*
	 * Virtual engines complicate acquiring the engine timeline lock,
	 * as their rq->engine pointer is not stable until under that
	 * engine lock. The simple ploy we use is to take the lock then
	 * check that the rq still belongs to the newly locked engine.
	 */
	locked = READ_ONCE(rq->engine);
	spin_lock_irq(&locked->sched_engine->lock);
	while (unlikely(locked != (engine = READ_ONCE(rq->engine)))) {
		spin_unlock(&locked->sched_engine->lock);
		spin_lock(&engine->sched_engine->lock);
		locked = engine;
	}
	list_del_init(&rq->sched.link);

	clear_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags);
	clear_bit(I915_FENCE_FLAG_HOLD, &rq->fence.flags);

	/* Prevent further __await_execution() registering a cb, then flush */
	set_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags);

	spin_unlock_irq(&locked->sched_engine->lock);

	i915_request_notify_execute_cb_imm(rq);
}

static bool can_preempt(struct intel_engine_cs *engine)
{
	if (GRAPHICS_VER(engine->i915) > 8)
@@ -3251,6 +3287,8 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)

	engine->cops = &execlists_context_ops;
	engine->request_alloc = execlists_request_alloc;
	engine->add_active_request = add_to_engine;
	engine->remove_active_request = remove_from_engine;

	engine->reset.prepare = execlists_reset_prepare;
	engine->reset.rewind = execlists_reset_rewind;
@@ -3847,6 +3885,8 @@ execlists_create_virtual(struct intel_engine_cs **siblings, unsigned int count)
			 "v%dx%d", ve->base.class, count);
		ve->base.context_size = sibling->context_size;

		ve->base.add_active_request = sibling->add_active_request;
		ve->base.remove_active_request = sibling->remove_active_request;
		ve->base.emit_bb_start = sibling->emit_bb_start;
		ve->base.emit_flush = sibling->emit_flush;
		ve->base.emit_init_breadcrumb = sibling->emit_init_breadcrumb;
+22 −0
Original line number Diff line number Diff line
@@ -1047,6 +1047,25 @@ static void setup_irq(struct intel_engine_cs *engine)
	}
}

static void add_to_engine(struct i915_request *rq)
{
	lockdep_assert_held(&rq->engine->sched_engine->lock);
	list_move_tail(&rq->sched.link, &rq->engine->sched_engine->requests);
}

static void remove_from_engine(struct i915_request *rq)
{
	spin_lock_irq(&rq->engine->sched_engine->lock);
	list_del_init(&rq->sched.link);

	/* Prevent further __await_execution() registering a cb, then flush */
	set_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags);

	spin_unlock_irq(&rq->engine->sched_engine->lock);

	i915_request_notify_execute_cb_imm(rq);
}

static void setup_common(struct intel_engine_cs *engine)
{
	struct drm_i915_private *i915 = engine->i915;
@@ -1064,6 +1083,9 @@ static void setup_common(struct intel_engine_cs *engine)
	engine->reset.cancel = reset_cancel;
	engine->reset.finish = reset_finish;

	engine->add_active_request = add_to_engine;
	engine->remove_active_request = remove_from_engine;

	engine->cops = &ring_context_ops;
	engine->request_alloc = ring_request_alloc;

Loading