From: Dave Gordon <david.s.gordon@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 1/2] drm/i915: Don't wait twice in {__intel, logical}_ring_prepare()
Date: Fri, 12 Jun 2015 21:25:37 +0100 [thread overview]
Message-ID: <1434140738-19521-2-git-send-email-david.s.gordon@intel.com> (raw)
In-Reply-To: <1434140738-19521-1-git-send-email-david.s.gordon@intel.com>
In the case that the ringbuffer was near-full AND 'tail' was
near the end of the buffer, we could have ended up waiting twice:
once to gain ownership of the space between TAIL and the end
(which we just want to fill with padding, so as not to split a
single command sequence across the end of the ringbuffer), and
then again to get enough space for the new data that the caller
wants to add.
Now we just precalculate the total amount of space we'll need
*including* any for padding at the end of the ringbuffer and wait
for that much in one go.
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
---
drivers/gpu/drm/i915/intel_lrc.c | 52 +++++++++++++++----------------
drivers/gpu/drm/i915/intel_ringbuffer.c | 51 +++++++++++++++---------------
2 files changed, 50 insertions(+), 53 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 454e836..a4bb5d3 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -740,39 +740,22 @@ intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf,
execlists_context_queue(ring, ctx, ringbuf->tail, request);
}
-static int logical_ring_wrap_buffer(struct intel_ringbuffer *ringbuf,
- struct intel_context *ctx)
-{
- uint32_t __iomem *virt;
- int rem = ringbuf->size - ringbuf->tail;
-
- if (ringbuf->space < rem) {
- int ret = logical_ring_wait_for_space(ringbuf, ctx, rem);
-
- if (ret)
- return ret;
- }
-
- virt = ringbuf->virtual_start + ringbuf->tail;
- rem /= 4;
- while (rem--)
- iowrite32(MI_NOOP, virt++);
-
- ringbuf->tail = 0;
- intel_ring_update_space(ringbuf);
-
- return 0;
-}
-
static int logical_ring_prepare(struct intel_ringbuffer *ringbuf,
struct intel_context *ctx, int bytes)
{
+ int fill = 0;
int ret;
+ /*
+ * If the request will not fit between 'tail' and the effective
+ * size of the ringbuffer, then we need to pad the end of the
+ * ringbuffer with NOOPs, then start the request at the top of
+ * the ring. This increases the total size that we need to check
+ * for by however much is left at the end of the ring ...
+ */
if (unlikely(ringbuf->tail + bytes > ringbuf->effective_size)) {
- ret = logical_ring_wrap_buffer(ringbuf, ctx);
- if (unlikely(ret))
- return ret;
+ fill = ringbuf->size - ringbuf->tail;
+ bytes += fill;
}
if (unlikely(ringbuf->space < bytes)) {
@@ -781,6 +764,21 @@ static int logical_ring_prepare(struct intel_ringbuffer *ringbuf,
return ret;
}
+ if (unlikely(fill)) {
+ uint32_t __iomem *virt = ringbuf->virtual_start + ringbuf->tail;
+
+ /* tail should not have moved */
+ if (WARN_ON(fill != ringbuf->size - ringbuf->tail))
+ fill = ringbuf->size - ringbuf->tail;
+
+ do
+ iowrite32(MI_NOOP, virt++);
+ while ((fill -= 4) > 0);
+
+ ringbuf->tail = 0;
+ intel_ring_update_space(ringbuf);
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index a3406b2..5a1cd20 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2137,29 +2137,6 @@ static int ring_wait_for_space(struct intel_engine_cs *ring, int n)
return 0;
}
-static int intel_wrap_ring_buffer(struct intel_engine_cs *ring)
-{
- uint32_t __iomem *virt;
- struct intel_ringbuffer *ringbuf = ring->buffer;
- int rem = ringbuf->size - ringbuf->tail;
-
- if (ringbuf->space < rem) {
- int ret = ring_wait_for_space(ring, rem);
- if (ret)
- return ret;
- }
-
- virt = ringbuf->virtual_start + ringbuf->tail;
- rem /= 4;
- while (rem--)
- iowrite32(MI_NOOP, virt++);
-
- ringbuf->tail = 0;
- intel_ring_update_space(ringbuf);
-
- return 0;
-}
-
int intel_ring_idle(struct intel_engine_cs *ring)
{
struct drm_i915_gem_request *req;
@@ -2197,12 +2174,19 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring,
int bytes)
{
struct intel_ringbuffer *ringbuf = ring->buffer;
+ int fill = 0;
int ret;
+ /*
+ * If the request will not fit between 'tail' and the effective
+ * size of the ringbuffer, then we need to pad the end of the
+ * ringbuffer with NOOPs, then start the request at the top of
+ * the ring. This increases the total size that we need to check
+ * for by however much is left at the end of the ring ...
+ */
if (unlikely(ringbuf->tail + bytes > ringbuf->effective_size)) {
- ret = intel_wrap_ring_buffer(ring);
- if (unlikely(ret))
- return ret;
+ fill = ringbuf->size - ringbuf->tail;
+ bytes += fill;
}
if (unlikely(ringbuf->space < bytes)) {
@@ -2211,6 +2195,21 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring,
return ret;
}
+ if (unlikely(fill)) {
+ uint32_t __iomem *virt = ringbuf->virtual_start + ringbuf->tail;
+
+ /* tail should not have moved */
+ if (WARN_ON(fill != ringbuf->size - ringbuf->tail))
+ fill = ringbuf->size - ringbuf->tail;
+
+ do
+ iowrite32(MI_NOOP, virt++);
+ while ((fill -= 4) > 0);
+
+ ringbuf->tail = 0;
+ intel_ring_update_space(ringbuf);
+ }
+
return 0;
}
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2015-06-12 20:25 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1433789441-8295-1-git-send-email-david.s.gordon@intel.com>
2015-06-12 17:09 ` [PATCH v2] Resolve issues with ringbuffer space management Dave Gordon
2015-06-12 17:09 ` [PATCH 1/2] drm/i915: use effective_size for ringbuffer calculations Dave Gordon
2015-06-12 18:12 ` Chris Wilson
2015-06-12 19:55 ` Dave Gordon
2015-06-12 20:41 ` Chris Wilson
2015-06-12 17:09 ` [PATCH 2/2] drm/i915: Rework order of operations in {__intel, logical}_ring_prepare() Dave Gordon
2015-06-12 18:05 ` Chris Wilson
2015-06-12 18:54 ` Dave Gordon
2015-06-12 19:10 ` Chris Wilson
2015-06-12 20:25 ` (no subject) Dave Gordon
2015-06-12 20:25 ` Dave Gordon [this message]
2015-06-12 20:25 ` [PATCH 2/2] drm/i915: Allocate OLR more safely (workaround until OLR goes away) Dave Gordon
2015-06-17 11:04 ` (no subject) Daniel Vetter
2015-06-17 12:41 ` Jani Nikula
2015-06-18 10:30 ` Dave Gordon
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=1434140738-19521-2-git-send-email-david.s.gordon@intel.com \
--to=david.s.gordon@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).