Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 77f0d0e9 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/execlists: Pack the count into the low bits of the port.request



add/remove: 1/1 grow/shrink: 5/4 up/down: 391/-578 (-187)
function                                     old     new   delta
execlists_submit_ports                       262     471    +209
port_assign.isra                               -     136    +136
capture                                     6344    6359     +15
reset_common_ring                            438     452     +14
execlists_submit_request                     228     238     +10
gen8_init_common_ring                        334     341      +7
intel_engine_is_idle                         106     105      -1
i915_engine_info                            2314    2290     -24
__i915_gem_set_wedged_BKL                    485     411     -74
intel_lrc_irq_handler                       1789    1604    -185
execlists_update_context                     294       -    -294

The most important change there is the improve to the
intel_lrc_irq_handler and excclist_submit_ports (net improvement since
execlists_update_context is now inlined).

v2: Use the port_api() for guc as well (even though currently we do not
pack any counters in there, yet) and hide all port->request_count inside
the helpers.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170517121007.27224-5-chris@chris-wilson.co.uk
parent 0ce81788
Loading
Loading
Loading
Loading
+15 −17
Original line number Original line Diff line number Diff line
@@ -3353,6 +3353,7 @@ static int i915_engine_info(struct seq_file *m, void *unused)
		if (i915.enable_execlists) {
		if (i915.enable_execlists) {
			u32 ptr, read, write;
			u32 ptr, read, write;
			struct rb_node *rb;
			struct rb_node *rb;
			unsigned int idx;


			seq_printf(m, "\tExeclist status: 0x%08x %08x\n",
			seq_printf(m, "\tExeclist status: 0x%08x %08x\n",
				   I915_READ(RING_EXECLIST_STATUS_LO(engine)),
				   I915_READ(RING_EXECLIST_STATUS_LO(engine)),
@@ -3370,8 +3371,7 @@ static int i915_engine_info(struct seq_file *m, void *unused)
			if (read > write)
			if (read > write)
				write += GEN8_CSB_ENTRIES;
				write += GEN8_CSB_ENTRIES;
			while (read < write) {
			while (read < write) {
				unsigned int idx = ++read % GEN8_CSB_ENTRIES;
				idx = ++read % GEN8_CSB_ENTRIES;

				seq_printf(m, "\tExeclist CSB[%d]: 0x%08x, context: %d\n",
				seq_printf(m, "\tExeclist CSB[%d]: 0x%08x, context: %d\n",
					   idx,
					   idx,
					   I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)),
					   I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)),
@@ -3379,21 +3379,19 @@ static int i915_engine_info(struct seq_file *m, void *unused)
			}
			}


			rcu_read_lock();
			rcu_read_lock();
			rq = READ_ONCE(engine->execlist_port[0].request);
			for (idx = 0; idx < ARRAY_SIZE(engine->execlist_port); idx++) {
				unsigned int count;

				rq = port_unpack(&engine->execlist_port[idx],
						 &count);
				if (rq) {
				if (rq) {
				seq_printf(m, "\t\tELSP[0] count=%d, ",
					seq_printf(m, "\t\tELSP[%d] count=%d, ",
					   engine->execlist_port[0].count);
						   idx, count);
					print_request(m, rq, "rq: ");
					print_request(m, rq, "rq: ");
				} else {
				} else {
				seq_printf(m, "\t\tELSP[0] idle\n");
					seq_printf(m, "\t\tELSP[%d] idle\n",
						   idx);
				}
				}
			rq = READ_ONCE(engine->execlist_port[1].request);
			if (rq) {
				seq_printf(m, "\t\tELSP[1] count=%d, ",
					   engine->execlist_port[1].count);
				print_request(m, rq, "rq: ");
			} else {
				seq_printf(m, "\t\tELSP[1] idle\n");
			}
			}
			rcu_read_unlock();
			rcu_read_unlock();


+4 −2
Original line number Original line Diff line number Diff line
@@ -3019,12 +3019,14 @@ static void engine_set_wedged(struct intel_engine_cs *engine)
	 */
	 */


	if (i915.enable_execlists) {
	if (i915.enable_execlists) {
		struct execlist_port *port = engine->execlist_port;
		unsigned long flags;
		unsigned long flags;
		unsigned int n;


		spin_lock_irqsave(&engine->timeline->lock, flags);
		spin_lock_irqsave(&engine->timeline->lock, flags);


		i915_gem_request_put(engine->execlist_port[0].request);
		for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++)
		i915_gem_request_put(engine->execlist_port[1].request);
			i915_gem_request_put(port_request(&port[n]));
		memset(engine->execlist_port, 0, sizeof(engine->execlist_port));
		memset(engine->execlist_port, 0, sizeof(engine->execlist_port));
		engine->execlist_queue = RB_ROOT;
		engine->execlist_queue = RB_ROOT;
		engine->execlist_first = NULL;
		engine->execlist_first = NULL;
+9 −4
Original line number Original line Diff line number Diff line
@@ -1324,12 +1324,17 @@ static void engine_record_requests(struct intel_engine_cs *engine,
static void error_record_engine_execlists(struct intel_engine_cs *engine,
static void error_record_engine_execlists(struct intel_engine_cs *engine,
					  struct drm_i915_error_engine *ee)
					  struct drm_i915_error_engine *ee)
{
{
	const struct execlist_port *port = engine->execlist_port;
	unsigned int n;
	unsigned int n;


	for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++)
	for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) {
		if (engine->execlist_port[n].request)
		struct drm_i915_gem_request *rq = port_request(&port[n]);
			record_request(engine->execlist_port[n].request,

				       &ee->execlist[n]);
		if (!rq)
			break;

		record_request(rq, &ee->execlist[n]);
	}
}
}


static void record_context(struct drm_i915_error_context *e,
static void record_context(struct drm_i915_error_context *e,
+23 −11
Original line number Original line Diff line number Diff line
@@ -653,10 +653,22 @@ static void nested_enable_signaling(struct drm_i915_gem_request *rq)
	spin_unlock(&rq->lock);
	spin_unlock(&rq->lock);
}
}


static void port_assign(struct execlist_port *port,
			struct drm_i915_gem_request *rq)
{
	GEM_BUG_ON(rq == port_request(port));

	if (port_isset(port))
		i915_gem_request_put(port_request(port));

	port_set(port, i915_gem_request_get(rq));
	nested_enable_signaling(rq);
}

static bool i915_guc_dequeue(struct intel_engine_cs *engine)
static bool i915_guc_dequeue(struct intel_engine_cs *engine)
{
{
	struct execlist_port *port = engine->execlist_port;
	struct execlist_port *port = engine->execlist_port;
	struct drm_i915_gem_request *last = port[0].request;
	struct drm_i915_gem_request *last = port_request(port);
	struct rb_node *rb;
	struct rb_node *rb;
	bool submit = false;
	bool submit = false;


@@ -670,8 +682,7 @@ static bool i915_guc_dequeue(struct intel_engine_cs *engine)
			if (port != engine->execlist_port)
			if (port != engine->execlist_port)
				break;
				break;


			i915_gem_request_assign(&port->request, last);
			port_assign(port, last);
			nested_enable_signaling(last);
			port++;
			port++;
		}
		}


@@ -681,13 +692,12 @@ static bool i915_guc_dequeue(struct intel_engine_cs *engine)
		rq->priotree.priority = INT_MAX;
		rq->priotree.priority = INT_MAX;


		i915_guc_submit(rq);
		i915_guc_submit(rq);
		trace_i915_gem_request_in(rq, port - engine->execlist_port);
		trace_i915_gem_request_in(rq, port_index(port, engine));
		last = rq;
		last = rq;
		submit = true;
		submit = true;
	}
	}
	if (submit) {
	if (submit) {
		i915_gem_request_assign(&port->request, last);
		port_assign(port, last);
		nested_enable_signaling(last);
		engine->execlist_first = rb;
		engine->execlist_first = rb;
	}
	}
	spin_unlock_irq(&engine->timeline->lock);
	spin_unlock_irq(&engine->timeline->lock);
@@ -703,17 +713,19 @@ static void i915_guc_irq_handler(unsigned long data)
	bool submit;
	bool submit;


	do {
	do {
		rq = port[0].request;
		rq = port_request(&port[0]);
		while (rq && i915_gem_request_completed(rq)) {
		while (rq && i915_gem_request_completed(rq)) {
			trace_i915_gem_request_out(rq);
			trace_i915_gem_request_out(rq);
			i915_gem_request_put(rq);
			i915_gem_request_put(rq);
			port[0].request = port[1].request;

			port[1].request = NULL;
			port[0] = port[1];
			rq = port[0].request;
			memset(&port[1], 0, sizeof(port[1]));

			rq = port_request(&port[0]);
		}
		}


		submit = false;
		submit = false;
		if (!port[1].request)
		if (!port_count(&port[1]))
			submit = i915_guc_dequeue(engine);
			submit = i915_guc_dequeue(engine);
	} while (submit);
	} while (submit);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -1233,7 +1233,7 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
		return false;
		return false;


	/* Both ports drained, no more ELSP submission? */
	/* Both ports drained, no more ELSP submission? */
	if (engine->execlist_port[0].request)
	if (port_request(&engine->execlist_port[0]))
		return false;
		return false;


	/* Ring stopped? */
	/* Ring stopped? */
Loading