[Intel-gfx] [PATCH] drm/i915: Reserve space improvements
Daniel Vetter
daniel at ffwll.ch
Wed Jul 1 05:29:31 PDT 2015
On Wed, Jul 01, 2015 at 11:44:07AM +0100, Tomas Elf wrote:
> On 30/06/2015 17:15, Tomas Elf wrote:
> >On 30/06/2015 16:53, John Harrison wrote:
> >>On 30/06/2015 15:43, Tomas Elf wrote:
> >>>On 30/06/2015 12:40, John.C.Harrison at Intel.com wrote:
> >>>>From: John Harrison <John.C.Harrison at Intel.com>
> >>>>
> >>>>An earlier patch was added to reserve space in the ring buffer for the
> >>>>commands issued during 'add_request()'. The initial version was
> >>>>pessimistic in the way it handled buffer wrapping and would cause
> >>>>premature wraps and thus waste ring space.
> >>>>
> >>>>This patch updates the code to better handle the wrap case. It no
> >>>>longer enforces that the space being asked for and the reserved space
> >>>>are a single contiguous block. Instead, it allows the reserve to be on
> >>>>the far end of a wrap operation. It still guarantees that the space is
> >>>>available so when the wrap occurs, no wait will happen. Thus the wrap
> >>>>cannot fail which is the whole point of the exercise.
> >>>>
> >>>>Also fixed a merge failure with some comments from the original patch.
> >>>>
> >>>>v2: Incorporated suggestion by David Gordon to move the wrap code
> >>>>inside the prepare function and thus allow a single combined
> >>>>wait_for_space() call rather than doing one before the wrap and
> >>>>another after. This also makes the prepare code much simpler and
> >>>>easier to follow.
> >>>>
> >>>>v3: Fix for 'effective_size' vs 'size' during ring buffer remainder
> >>>>calculations (spotted by Tomas Elf).
> >>>>
> >>>>For: VIZ-5115
> >>>>CC: Daniel Vetter <daniel at ffwll.ch>
> >>>>Signed-off-by: John Harrison <John.C.Harrison at Intel.com>
> >>>>---
> >>>> drivers/gpu/drm/i915/intel_lrc.c | 73
> >>>>+++++++++++++-------------
> >>>> drivers/gpu/drm/i915/intel_ringbuffer.c | 90
> >>>>+++++++++++++++++++--------------
> >>>> drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +-
> >>>> 3 files changed, 90 insertions(+), 77 deletions(-)
> >>>>
> >>>>diff --git a/drivers/gpu/drm/i915/intel_lrc.c
> >>>>b/drivers/gpu/drm/i915/intel_lrc.c
> >>>>index b36e064..7d9515d 100644
> >>>>--- a/drivers/gpu/drm/i915/intel_lrc.c
> >>>>+++ b/drivers/gpu/drm/i915/intel_lrc.c
> >>>>@@ -663,12 +663,12 @@ static int logical_ring_wait_for_space(struct
> >>>>drm_i915_gem_request *req,
> >>>> unsigned space;
> >>>> int ret;
> >>>>
> >>>>- /* The whole point of reserving space is to not wait! */
> >>>>- WARN_ON(ringbuf->reserved_in_use);
> >>>>-
> >>>> if (intel_ring_space(ringbuf) >= bytes)
> >>>> return 0;
> >>>>
> >>>>+ /* The whole point of reserving space is to not wait! */
> >>>>+ WARN_ON(ringbuf->reserved_in_use);
> >>>>+
> >>>> list_for_each_entry(target, &ring->request_list, list) {
> >>>> /*
> >>>> * The request queue is per-engine, so can contain requests
> >>>>@@ -718,22 +718,11 @@ intel_logical_ring_advance_and_submit(struct
> >>>>drm_i915_gem_request *request)
> >>>> execlists_context_queue(request);
> >>>> }
> >>>>
> >>>>-static int logical_ring_wrap_buffer(struct drm_i915_gem_request *req)
> >>>>+static void __wrap_ring_buffer(struct intel_ringbuffer *ringbuf)
> >>>> {
> >>>>- struct intel_ringbuffer *ringbuf = req->ringbuf;
> >>>> uint32_t __iomem *virt;
> >>>> int rem = ringbuf->size - ringbuf->tail;
> >>>>
> >>>>- /* Can't wrap if space has already been reserved! */
> >>>>- WARN_ON(ringbuf->reserved_in_use);
> >>>>-
> >>>>- if (ringbuf->space < rem) {
> >>>>- int ret = logical_ring_wait_for_space(req, rem);
> >>>>-
> >>>>- if (ret)
> >>>>- return ret;
> >>>>- }
> >>>>-
> >>>> virt = ringbuf->virtual_start + ringbuf->tail;
> >>>> rem /= 4;
> >>>> while (rem--)
> >>>>@@ -741,40 +730,50 @@ static int logical_ring_wrap_buffer(struct
> >>>>drm_i915_gem_request *req)
> >>>>
> >>>> ringbuf->tail = 0;
> >>>> intel_ring_update_space(ringbuf);
> >>>>-
> >>>>- return 0;
> >>>> }
> >>>>
> >>>> static int logical_ring_prepare(struct drm_i915_gem_request *req,
> >>>>int bytes)
> >>>> {
> >>>> struct intel_ringbuffer *ringbuf = req->ringbuf;
> >>>>- int ret;
> >>>>-
> >>>>- /*
> >>>>- * Add on the reserved size to the request to make sure that after
> >>>>- * the intended commands have been emitted, there is guaranteed to
> >>>>- * still be enough free space to send them to the hardware.
> >>>>- */
> >>>>- if (!ringbuf->reserved_in_use)
> >>>>- bytes += ringbuf->reserved_size;
> >>>>-
> >>>>- if (unlikely(ringbuf->tail + bytes > ringbuf->effective_size)) {
> >>>>- ret = logical_ring_wrap_buffer(req);
> >>>>- if (unlikely(ret))
> >>>>- return ret;
> >>>>+ int remain_usable = ringbuf->effective_size - ringbuf->tail;
> >>>>+ int remain_actual = ringbuf->size - ringbuf->tail;
> >>>
> >>>You could add a comment here (and in the legacy implementation)
> >>>explaining why we make the distinction between remain_usable and
> >>>remain_actual. Or you could add the comment when we actually use
> >>>remain_actual further down in the function. It's up to you.
> >>>
> >>>We first need to be pessimistic about how much space is left in the
> >>>ring buffer when determining the need for wrapping - therefore we use
> >>>remain_usable, which disregards the end-of-buffer padding - and then
> >>>we need to be pessimistic about how much ring space we need to wait
> >>>for - therefore we use remain_actual, which takes the end-of-buffer
> >>>padding into consideration to make sure that we're actually not
> >>>waiting for too little space.
> >>
> >>It's not about being pessimistic or optimistic. That implies there is
> >>some choice, that one version is a little bit better in one situation
> >>but either would do. Whereas this is about functional correctness. The
> >>difference between the actual ring size and the usable ring size is not
> >>some reserved space thing to make something go faster. This is about the
> >>hardware locking up if the entire buffer is used. I think 'usable' and
> >>'actual' are fairly obvious names. If you want to know the details about
> >>why there is an 'effective_size' in the first place then look up
> >>'effective_size' in the code and read the comment about i830 hangs.
> >
> >You're probably right. Let's just forget about it.
> >
> >>
> >>>If you add those comments maybe you could also rename the variables to
> >>>something like "remaining_space_usable" etc. since "remain_usable" is
> >>>more of a verb than a noun. But that's seriously nitpicking.
> >>Or maybe
> >>'remaining_space_that_is_usable_without_causing_an_i830_to_hang_because_it_skips_the_last_two_cachelines'?
> >>
> >>There is such a thing as being too verbose and making the code hard to
> >>read.
> >
> >That is indeed a very long variable name. It's 104 characters long so
> >that wouldn't clear checkpatch.pl :). My nitpicky suggestion was 9
> >characters longer. And, yeah, it's possible to get too verbose. This
> >driver is not even remotely close to that point as it stands today :).
> >
> >Thanks,
> >Tomas
>
> Anyway, I think we're done here.
>
> Reviewed-by: Tomas Elf <tomas.elf at intel.com>
Queued for -next.t
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
More information about the Intel-gfx
mailing list