Commit c10c78ad authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/execlists: Refactor out can_merge_rq()



In the next patch, we add another user that wants to check whether
requests can be merge into a single HW execution, and in the future we
want to add more conditions under which requests from the same context
cannot be merge. In preparation, extract out can_merge_rq().

v2: Reorder tests to decide if we can continue filling ELSP and bonus
comments.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190208235108.23127-1-chris@chris-wilson.co.uk
parent 21182b3c
Loading
Loading
Loading
Loading
+24 −11
Original line number Original line Diff line number Diff line
@@ -254,12 +254,11 @@ static inline bool need_preempt(const struct intel_engine_cs *engine,
}
}


__maybe_unused static inline bool
__maybe_unused static inline bool
assert_priority_queue(const struct intel_engine_execlists *execlists,
assert_priority_queue(const struct i915_request *prev,
		      const struct i915_request *prev,
		      const struct i915_request *next)
		      const struct i915_request *next)
{
{
	if (!prev)
	const struct intel_engine_execlists *execlists =
		return true;
		&prev->engine->execlists;


	/*
	/*
	 * Without preemption, the prev may refer to the still active element
	 * Without preemption, the prev may refer to the still active element
@@ -564,6 +563,17 @@ static bool can_merge_ctx(const struct intel_context *prev,
	return true;
	return true;
}
}


static bool can_merge_rq(const struct i915_request *prev,
			 const struct i915_request *next)
{
	GEM_BUG_ON(!assert_priority_queue(prev, next));

	if (!can_merge_ctx(prev->hw_context, next->hw_context))
		return false;

	return true;
}

static void port_assign(struct execlist_port *port, struct i915_request *rq)
static void port_assign(struct execlist_port *port, struct i915_request *rq)
{
{
	GEM_BUG_ON(rq == port_request(port));
	GEM_BUG_ON(rq == port_request(port));
@@ -716,8 +726,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
		int i;
		int i;


		priolist_for_each_request_consume(rq, rn, p, i) {
		priolist_for_each_request_consume(rq, rn, p, i) {
			GEM_BUG_ON(!assert_priority_queue(execlists, last, rq));

			/*
			/*
			 * Can we combine this request with the current port?
			 * Can we combine this request with the current port?
			 * It has to be the same context/ringbuffer and not
			 * It has to be the same context/ringbuffer and not
@@ -729,8 +737,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
			 * second request, and so we never need to tell the
			 * second request, and so we never need to tell the
			 * hardware about the first.
			 * hardware about the first.
			 */
			 */
			if (last &&
			if (last && !can_merge_rq(last, rq)) {
			    !can_merge_ctx(rq->hw_context, last->hw_context)) {
				/*
				/*
				 * If we are on the second port and cannot
				 * If we are on the second port and cannot
				 * combine this request with the last, then we
				 * combine this request with the last, then we
@@ -739,6 +746,14 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
				if (port == last_port)
				if (port == last_port)
					goto done;
					goto done;


				/*
				 * We must not populate both ELSP[] with the
				 * same LRCA, i.e. we must submit 2 different
				 * contexts if we submit 2 ELSP.
				 */
				if (last->hw_context == rq->hw_context)
					goto done;

				/*
				/*
				 * If GVT overrides us we only ever submit
				 * If GVT overrides us we only ever submit
				 * port[0], leaving port[1] empty. Note that we
				 * port[0], leaving port[1] empty. Note that we
@@ -750,7 +765,6 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
				    ctx_single_port_submission(rq->hw_context))
				    ctx_single_port_submission(rq->hw_context))
					goto done;
					goto done;


				GEM_BUG_ON(last->hw_context == rq->hw_context);


				if (submit)
				if (submit)
					port_assign(port, last);
					port_assign(port, last);
@@ -790,8 +804,7 @@ done:
	 * request triggering preemption on the next dequeue (or subsequent
	 * request triggering preemption on the next dequeue (or subsequent
	 * interrupt for secondary ports).
	 * interrupt for secondary ports).
	 */
	 */
	execlists->queue_priority_hint =
	execlists->queue_priority_hint = queue_prio(execlists);
		port != execlists->port ? rq_prio(last) : INT_MIN;


	if (submit) {
	if (submit) {
		port_assign(port, last);
		port_assign(port, last);