All of lore.kernel.org
 help / color / mirror / Atom feed
From: John.C.Harrison@Intel.com
To: Intel-GFX@Lists.FreeDesktop.Org
Subject: [PATCH 06/59] drm/i915: i915_add_request must not fail
Date: Thu, 19 Mar 2015 12:30:11 +0000	[thread overview]
Message-ID: <1426768264-16996-7-git-send-email-John.C.Harrison@Intel.com> (raw)
In-Reply-To: <1426768264-16996-1-git-send-email-John.C.Harrison@Intel.com>

From: John Harrison <John.C.Harrison@Intel.com>

The i915_add_request() function is called to keep track of work that has been
written to the ring buffer. It adds epilogue commands to track progress (seqno
updates and such), moves the request structure onto the right list and other
such house keeping tasks. However, the work itself has already been written to
the ring and will get executed whether or not the add request call succeeds. So
no matter what goes wrong, there isn't a whole lot of point in failing the call.

At the moment, this is fine(ish). If the add request does bail early on and not
do the housekeeping, the request will still float around in the
ring->outstanding_lazy_request field and be picked up next time. It means
multiple pieces of work will be tagged as the same request and driver can't
actually wait for the first piece of work until something else has been
submitted. But it all sort of hangs together.

This patch series is all about removing the OLR and guaranteeing that each piece
of work gets its own personal request. That means that there is no more
'hoovering up of forgotten requests'. If the request does not get tracked then
it will be leaked. Thus the add request call _must_ not fail. The previous patch
should have already ensured that it _will_ not fail by removing the potential
for running out of ring space. This patch enforces the rule by actually removing
the early exit paths and the return code.

Note that if something does manage to fail and the epilogue commands don't get
written to the ring, the driver will still hang together. The request will be
added to the tracking lists. And as in the old case, any subsequent work will
generate a new seqno which will suffice for marking the old one as complete.

For: VIZ-5115
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h              |    6 ++--
 drivers/gpu/drm/i915/i915_gem.c              |   44 +++++++++++---------------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   |    2 +-
 drivers/gpu/drm/i915/i915_gem_render_state.c |    2 +-
 drivers/gpu/drm/i915/intel_lrc.c             |    2 +-
 drivers/gpu/drm/i915/intel_overlay.c         |   10 +++---
 drivers/gpu/drm/i915/intel_ringbuffer.c      |    8 ++---
 7 files changed, 32 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fe6446d..7b36d4a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2748,9 +2748,9 @@ void i915_gem_init_swizzling(struct drm_device *dev);
 void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int __must_check i915_gpu_idle(struct drm_device *dev);
 int __must_check i915_gem_suspend(struct drm_device *dev);
-int __i915_add_request(struct intel_engine_cs *ring,
-		       struct drm_file *file,
-		       struct drm_i915_gem_object *batch_obj);
+void __i915_add_request(struct intel_engine_cs *ring,
+			struct drm_file *file,
+			struct drm_i915_gem_object *batch_obj);
 #define i915_add_request(ring) \
 	__i915_add_request(ring, NULL, NULL)
 int __i915_wait_request(struct drm_i915_gem_request *req,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fc383fc..cdf1c9d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1159,15 +1159,12 @@ i915_gem_check_wedge(struct i915_gpu_error *error,
 int
 i915_gem_check_olr(struct drm_i915_gem_request *req)
 {
-	int ret;
-
 	WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
 
-	ret = 0;
 	if (req == req->ring->outstanding_lazy_request)
-		ret = i915_add_request(req->ring);
+		i915_add_request(req->ring);
 
-	return ret;
+	return 0;
 }
 
 static void fake_irq(unsigned long data)
@@ -2325,9 +2322,14 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
 	return 0;
 }
 
-int __i915_add_request(struct intel_engine_cs *ring,
-		       struct drm_file *file,
-		       struct drm_i915_gem_object *obj)
+/*
+ * NB: This function is not allowed to fail. Doing so would mean the the
+ * request is not being tracked for completion but the work itself is
+ * going to happen on the hardware. This would be a Bad Thing(tm).
+ */
+void __i915_add_request(struct intel_engine_cs *ring,
+			struct drm_file *file,
+			struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_private *dev_priv = ring->dev->dev_private;
 	struct drm_i915_gem_request *request;
@@ -2337,7 +2339,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
 
 	request = ring->outstanding_lazy_request;
 	if (WARN_ON(request == NULL))
-		return -ENOMEM;
+		return;
 
 	if (i915.enable_execlists) {
 		ringbuf = request->ctx->engine[ring->id].ringbuf;
@@ -2359,15 +2361,12 @@ int __i915_add_request(struct intel_engine_cs *ring,
 	 * is that the flush _must_ happen before the next request, no matter
 	 * what.
 	 */
-	if (i915.enable_execlists) {
+	if (i915.enable_execlists)
 		ret = logical_ring_flush_all_caches(ringbuf, request->ctx);
-		if (ret)
-			return ret;
-	} else {
+	else
 		ret = intel_ring_flush_all_caches(ring);
-		if (ret)
-			return ret;
-	}
+	/* Not allowed to fail! */
+	WARN_ON(ret);
 
 	/* Record the position of the start of the request so that
 	 * should we detect the updated seqno part-way through the
@@ -2376,15 +2375,12 @@ int __i915_add_request(struct intel_engine_cs *ring,
 	 */
 	request->postfix = intel_ring_get_tail(ringbuf);
 
-	if (i915.enable_execlists) {
+	if (i915.enable_execlists)
 		ret = ring->emit_request(ringbuf, request);
-		if (ret)
-			return ret;
-	} else {
+	else
 		ret = ring->add_request(ring);
-		if (ret)
-			return ret;
-	}
+	/* Not allowed to fail! */
+	WARN_ON(ret);
 
 	request->head = request_start;
 	request->tail = intel_ring_get_tail(ringbuf);
@@ -2435,8 +2431,6 @@ int __i915_add_request(struct intel_engine_cs *ring,
 
 	/* Sanity check that the reserved size was large enough. */
 	intel_ring_reserved_space_end(ringbuf);
-
-	return 0;
 }
 
 static inline void
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 38e2178..1bb237c 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1063,7 +1063,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev,
 	ring->gpu_caches_dirty = true;
 
 	/* Add a breadcrumb for the completion of the batch buffer */
-	(void)__i915_add_request(ring, file, obj);
+	__i915_add_request(ring, file, obj);
 }
 
 static int
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 521548a..ce4788f 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -173,7 +173,7 @@ int i915_gem_render_state_init(struct intel_engine_cs *ring)
 
 	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
 
-	ret = __i915_add_request(ring, NULL, so.obj);
+	__i915_add_request(ring, NULL, so.obj);
 	/* __i915_add_request moves object to inactive if it fails */
 out:
 	i915_gem_render_state_fini(&so);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index bdbdcae..8d48761 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1352,7 +1352,7 @@ static int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
 
 	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
 
-	ret = __i915_add_request(ring, file, so.obj);
+	__i915_add_request(ring, file, so.obj);
 	/* intel_logical_ring_add_request moves object to inactive if it
 	 * fails */
 out:
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 823d1d9..6af2581 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -219,17 +219,15 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 	BUG_ON(overlay->last_flip_req);
 	i915_gem_request_assign(&overlay->last_flip_req,
 					     ring->outstanding_lazy_request);
-	ret = i915_add_request(ring);
-	if (ret)
-		return ret;
+	i915_add_request(ring);
 
 	overlay->flip_tail = tail;
 	ret = i915_wait_request(overlay->last_flip_req);
 	if (ret)
 		return ret;
 	i915_gem_retire_requests(dev);
-
 	i915_gem_request_assign(&overlay->last_flip_req, NULL);
+
 	return 0;
 }
 
@@ -291,7 +289,9 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
 	WARN_ON(overlay->last_flip_req);
 	i915_gem_request_assign(&overlay->last_flip_req,
 					     ring->outstanding_lazy_request);
-	return i915_add_request(ring);
+	i915_add_request(ring);
+
+	return 0;
 }
 
 static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 9075008..1a7ed8b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2172,14 +2172,10 @@ static int intel_wrap_ring_buffer(struct intel_engine_cs *ring)
 int intel_ring_idle(struct intel_engine_cs *ring)
 {
 	struct drm_i915_gem_request *req;
-	int ret;
 
 	/* We need to add any requests required to flush the objects and ring */
-	if (ring->outstanding_lazy_request) {
-		ret = i915_add_request(ring);
-		if (ret)
-			return ret;
-	}
+	if (ring->outstanding_lazy_request)
+		i915_add_request(ring);
 
 	/* Wait upon the last request to be completed */
 	if (list_empty(&ring->request_list))
-- 
1.7.9.5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2015-03-19 12:31 UTC|newest]

Thread overview: 122+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-19 12:30 [PATCH 00/59] Remove the outstanding_lazy_request John.C.Harrison
2015-03-19 12:30 ` [PATCH 01/59] drm/i915: Rename 'do_execbuf' to 'execbuf_submit' John.C.Harrison
2015-03-31 15:45   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 02/59] drm/i915: Make intel_logical_ring_begin() static John.C.Harrison
2015-03-31 15:47   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 03/59] drm/i915: Move common request allocation code into a common function John.C.Harrison
2015-03-31 15:48   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 04/59] drm/i915: Fix for ringbuf space wait in LRC mode John.C.Harrison
2015-03-19 14:56   ` Daniel, Thomas
2015-03-31 15:50   ` Tomas Elf
2015-04-01  5:56     ` Daniel Vetter
2015-04-01 12:00       ` John Harrison
2015-04-01  8:53     ` Chris Wilson
2015-03-19 12:30 ` [PATCH 05/59] drm/i915: Reserve ring buffer space for i915_add_request() commands John.C.Harrison
2015-03-20 15:13   ` Daniel Vetter
2015-03-20 15:55     ` John Harrison
2015-03-23  8:54       ` Daniel Vetter
2015-03-31 16:03         ` Chris Wilson
2015-03-20 16:19   ` John Harrison
2015-03-20 18:13     ` John Harrison
2015-03-31 15:58   ` Tomas Elf
2015-03-19 12:30 ` John.C.Harrison [this message]
2015-03-19 12:30 ` [PATCH 07/59] drm/i915: Early alloc request in execbuff John.C.Harrison
2015-03-31 16:09   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 08/59] drm/i915: Set context in request from creation even in legacy mode John.C.Harrison
2015-03-31 16:10   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 09/59] drm/i915: Merged the many do_execbuf() parameters into a structure John.C.Harrison
2015-03-31 16:16   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 10/59] drm/i915: Simplify i915_gem_execbuffer_retire_commands() parameters John.C.Harrison
2015-03-19 12:30 ` [PATCH 11/59] drm/i915: Update alloc_request to return the allocated request John.C.Harrison
2015-03-31 16:20   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 12/59] drm/i915: Add request to execbuf params and add explicit cleanup John.C.Harrison
2015-03-19 12:30 ` [PATCH 13/59] drm/i915: Update the dispatch tracepoint to use params->request John.C.Harrison
2015-03-19 12:30 ` [PATCH 14/59] drm/i915: Update move_to_gpu() to take a request structure John.C.Harrison
2015-03-19 12:30 ` [PATCH 15/59] drm/i915: Update execbuffer_move_to_active() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 16/59] drm/i915: Add flag to i915_add_request() to skip the cache flush John.C.Harrison
2015-03-31 16:32   ` Tomas Elf
2015-04-01  5:59     ` Daniel Vetter
2015-04-01  8:52     ` Chris Wilson
2015-03-19 12:30 ` [PATCH 17/59] drm/i915: Update i915_gpu_idle() to manage its own request John.C.Harrison
2015-03-19 12:30 ` [PATCH 18/59] drm/i915: Split i915_ppgtt_init_hw() in half - generic and per ring John.C.Harrison
2015-03-31 16:34   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 19/59] drm/i915: Moved the for_each_ring loop outside of i915_gem_context_enable() John.C.Harrison
2015-03-19 12:30 ` [PATCH 20/59] drm/i915: Don't tag kernel batches as user batches John.C.Harrison
2015-03-31 16:35   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 21/59] drm/i915: Add explicit request management to i915_gem_init_hw() John.C.Harrison
2015-03-31 16:38   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 22/59] drm/i915: Update ppgtt_init_ring() & context_enable() to take requests John.C.Harrison
2015-03-31 16:38   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 23/59] drm/i915: Update i915_switch_context() to take a request structure John.C.Harrison
2015-03-19 12:30 ` [PATCH 24/59] drm/i915: Update do_switch() " John.C.Harrison
2015-03-31 16:40   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 25/59] drm/i915: Update deferred context creation to do explicit request management John.C.Harrison
2015-03-31 16:43   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 26/59] drm/i915: Update init_context() to take a request structure John.C.Harrison
2015-03-19 12:30 ` [PATCH 27/59] drm/i915: Update render_state_init() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 28/59] drm/i915: Update i915_gem_object_sync() " John.C.Harrison
2015-03-31 16:53   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 29/59] drm/i915: Update overlay code to do explicit request management John.C.Harrison
2015-03-31 16:53   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 30/59] drm/i915: Update queue_flip() to take a request structure John.C.Harrison
2015-03-31 16:54   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 31/59] drm/i915: Update add_request() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 32/59] drm/i915: Update [vma|object]_move_to_active() to take request structures John.C.Harrison
2015-03-19 12:30 ` [PATCH 33/59] drm/i915: Update l3_remap to take a request structure John.C.Harrison
2015-03-19 12:30 ` [PATCH 34/59] drm/i915: Update mi_set_context() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 35/59] drm/i915: Update a bunch of execbuffer helpers to take request structures John.C.Harrison
2015-03-19 12:30 ` [PATCH 36/59] drm/i915: Update workarounds_emit() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 37/59] drm/i915: Update flush_all_caches() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 38/59] drm/i915: Update switch_mm() to take a request structure John.C.Harrison
2015-03-31 16:57   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 39/59] drm/i915: Update ring->flush() to take a requests structure John.C.Harrison
2015-03-31 16:59   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 40/59] drm/i915: Update some flush helpers to take request structures John.C.Harrison
2015-03-19 12:30 ` [PATCH 41/59] drm/i915: Update ring->emit_flush() to take a request structure John.C.Harrison
2015-03-19 12:30 ` [PATCH 42/59] drm/i915: Update ring->add_request() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 43/59] drm/i915: Update ring->emit_request() " John.C.Harrison
2015-03-31 17:01   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 44/59] drm/i915: Update ring->dispatch_execbuffer() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 45/59] drm/i915: Update ring->emit_bb_start() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 46/59] drm/i915: Update ring->sync_to() " John.C.Harrison
2015-03-31 17:03   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 47/59] drm/i915: Update ring->signal() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 48/59] drm/i915: Update cacheline_align() " John.C.Harrison
2015-03-19 12:30 ` [PATCH 49/59] drm/i915: Update intel_ring_begin() " John.C.Harrison
2015-03-31 17:04   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 50/59] drm/i915: Update intel_logical_ring_begin() " John.C.Harrison
2015-03-31 17:05   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 51/59] drm/i915: Add *_ring_begin() to request allocation John.C.Harrison
2015-03-20 15:23   ` Daniel Vetter
2015-03-20 15:30     ` Chris Wilson
2015-03-20 16:09       ` John Harrison
2015-03-23  9:10         ` Daniel Vetter
2015-03-31 17:17   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 52/59] drm/i915: Remove the now obsolete intel_ring_get_request() John.C.Harrison
2015-03-19 12:30 ` [PATCH 53/59] drm/i915: Remove the now obsolete 'outstanding_lazy_request' John.C.Harrison
2015-03-31 18:01   ` Tomas Elf
2015-03-19 12:30 ` [PATCH 54/59] drm/i915: Move the request/file and request/pid association to creation time John.C.Harrison
2015-03-31 18:07   ` Tomas Elf
2015-03-19 12:31 ` [PATCH 55/59] drm/i915: Remove fallback poll for ring buffer space John.C.Harrison
2015-03-19 15:00   ` Daniel, Thomas
2015-03-19 15:16     ` Jani Nikula
2015-03-19 16:33       ` John Harrison
2015-03-19 17:29         ` Daniel Vetter
2015-03-31 18:13   ` Tomas Elf
2015-04-01  6:02     ` Daniel Vetter
2015-04-01  8:51     ` Chris Wilson
2015-03-19 12:31 ` [PATCH 56/59] drm/i915: Remove 'faked' request from LRC submission John.C.Harrison
2015-03-19 15:02   ` Daniel, Thomas
2015-03-31 18:14   ` Tomas Elf
2015-03-19 12:31 ` [PATCH 57/59] drm/i915: Update a bunch of LRC functions to take requests John.C.Harrison
2015-03-31 18:18   ` Tomas Elf
2015-03-19 12:31 ` [PATCH 58/59] drm/i915: Remove the now obsolete 'i915_gem_check_olr()' John.C.Harrison
2015-03-31 18:18   ` Tomas Elf
2015-03-19 12:31 ` [PATCH 59/59] drm/i915: Remove the almost obsolete i915_gem_object_flush_active() John.C.Harrison
2015-03-31 18:32   ` Tomas Elf
2015-04-01  6:06     ` Daniel Vetter
2015-05-28 20:02 ` [PATCH 00/59] Remove the outstanding_lazy_request Jesse Barnes
2015-05-28 21:20   ` Chris Wilson
2015-05-29 14:37     ` Jesse Barnes
2015-05-29 18:07       ` Chris Wilson
2015-05-29 11:00   ` John Harrison

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1426768264-16996-7-git-send-email-John.C.Harrison@Intel.com \
    --to=john.c.harrison@intel.com \
    --cc=Intel-GFX@Lists.FreeDesktop.Org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.