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

Commit 675d9ad7 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Track requests inside each intel_ring



By tracking each request occupying space inside an individual
intel_ring, we can greatly simplify the logic of tracking available
space and not worry about other timelines. (Each ring is an ordered
timeline of committed requests.)

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470293567-10811-17-git-send-email-chris@chris-wilson.co.uk
parent fa545cbf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
	 * Note this requires that we are always called in request
	 * completion order.
	 */
	list_del(&request->ring_link);
	request->ring->last_retired_head = request->postfix;

	/* Walk through the active list, calling retire on each. This allows
@@ -487,6 +488,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
	request->previous_seqno = engine->last_submitted_seqno;
	smp_store_mb(engine->last_submitted_seqno, request->fence.seqno);
	list_add_tail(&request->link, &engine->request_list);
	list_add_tail(&request->ring_link, &ring->request_list);

	/* Record the position of the start of the request so that
	 * should we detect the updated seqno part-way through the
+3 −0
Original line number Diff line number Diff line
@@ -109,6 +109,9 @@ struct drm_i915_gem_request {
	/** engine->request_list entry for this request */
	struct list_head link;

	/** ring->request_list entry for this request */
	struct list_head ring_link;

	struct drm_i915_file_private *file_priv;
	/** file_priv list entry for this request */
	struct list_head client_list;
+4 −11
Original line number Diff line number Diff line
@@ -2046,6 +2046,8 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size)
	ring->engine = engine;
	list_add(&ring->link, &engine->buffers);

	INIT_LIST_HEAD(&ring->request_list);

	ring->size = size;
	/* Workaround an erratum on the i830 which causes a hang if
	 * the TAIL pointer points to within the last 2 cachelines
@@ -2266,7 +2268,6 @@ int intel_ring_alloc_request_extras(struct drm_i915_gem_request *request)
static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
{
	struct intel_ring *ring = req->ring;
	struct intel_engine_cs *engine = req->engine;
	struct drm_i915_gem_request *target;

	intel_ring_update_space(ring);
@@ -2284,17 +2285,9 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
	 */
	GEM_BUG_ON(!req->reserved_space);

	list_for_each_entry(target, &engine->request_list, link) {
	list_for_each_entry(target, &ring->request_list, ring_link) {
		unsigned space;

		/*
		 * The request queue is per-engine, so can contain requests
		 * from multiple ringbuffers. Here, we must ignore any that
		 * aren't from the ringbuffer we're considering.
		 */
		if (target->ring != ring)
			continue;

		/* Would completion of this request free enough space? */
		space = __intel_ring_space(target->postfix, ring->tail,
					   ring->size);
@@ -2302,7 +2295,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
			break;
	}

	if (WARN_ON(&target->link == &engine->request_list))
	if (WARN_ON(&target->ring_link == &ring->request_list))
		return -ENOSPC;

	return i915_wait_request(target);
+2 −0
Original line number Diff line number Diff line
@@ -90,6 +90,8 @@ struct intel_ring {
	struct intel_engine_cs *engine;
	struct list_head link;

	struct list_head request_list;

	u32 head;
	u32 tail;
	int space;