diff mbox

[1/3] drm/i915: Avoid the branch in computing intel_ring_space()

Message ID 20170426083735.10832-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson April 26, 2017, 8:37 a.m. UTC
Exploit the power-of-two ring size to compute the space across the
wraparound using a mask rather than a if. Convert to unsigned integers
so the operation is well defined.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c | 20 ++++++++++----------
 drivers/gpu/drm/i915/intel_ringbuffer.h | 30 ++++++++++++++++--------------
 2 files changed, 26 insertions(+), 24 deletions(-)

Comments

Chris Wilson April 26, 2017, 9:03 a.m. UTC | #1
On Wed, Apr 26, 2017 at 08:59:14AM -0000, Patchwork wrote:
> == Series Details ==
> 
> Series: series starting with [1/3] drm/i915: Avoid the branch in computing intel_ring_space()
> URL   : https://patchwork.freedesktop.org/series/23555/
> State : failure
> 
> == Summary ==
> 
> Series 23555v1 Series without cover letter
> https://patchwork.freedesktop.org/api/1.0/series/23555/revisions/1/mbox/
> 
> Test gem_close_race:
>         Subgroup basic-threads:
>                 pass       -> INCOMPLETE (fi-ivb-3520m)
>                 pass       -> INCOMPLETE (fi-ivb-3770)
>                 pass       -> INCOMPLETE (fi-kbl-7500u)
>                 pass       -> INCOMPLETE (fi-bdw-gvtdvm)
>                 pass       -> INCOMPLETE (fi-skl-6260u)
>                 pass       -> INCOMPLETE (fi-snb-2520m)
>                 pass       -> INCOMPLETE (fi-byt-j1900)
>                 pass       -> INCOMPLETE (fi-ilk-650)
>                 pass       -> INCOMPLETE (fi-hsw-4770r)
>                 pass       -> INCOMPLETE (fi-snb-2600)
>                 pass       -> INCOMPLETE (fi-skl-6700k)
>                 pass       -> INCOMPLETE (fi-byt-n2820)
>                 pass       -> INCOMPLETE (fi-skl-6770hq)
>                 pass       -> INCOMPLETE (fi-bdw-5557u)
>                 pass       -> INCOMPLETE (fi-hsw-4770)
>                 pass       -> INCOMPLETE (fi-kbl-7560u)
>                 pass       -> INCOMPLETE (fi-skl-gvtdvm)
>                 pass       -> INCOMPLETE (fi-skl-6700hq)

Oops. Serves me right for tweaking before sending.
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 6836efb7e3d2..16739352f057 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -39,12 +39,15 @@ 
  */
 #define LEGACY_REQUEST_SIZE 200
 
-static int __intel_ring_space(int head, int tail, int size)
+static unsigned int __intel_ring_space(unsigned int head,
+				       unsigned int tail,
+				       unsigned int size)
 {
-	int space = head - tail;
-	if (space <= 0)
-		space += size;
-	return space - I915_RING_FREE_SPACE;
+	/* "If the Ring Buffer Head Pointer and the Tail Pointer are on the
+	 * same cacheline, the Head Pointer must not be greater than the Tail
+	 * Pointer."
+	 */
+	return (head - tail - CACHELINE_BYTES) & (size - 1);
 }
 
 void intel_ring_update_space(struct intel_ring *ring)
@@ -1619,12 +1622,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, &ring->request_list, ring_link) {
-		unsigned space;
-
 		/* Would completion of this request free enough space? */
-		space = __intel_ring_space(target->postfix, ring->emit,
-					   ring->size);
-		if (space >= bytes)
+		if (bytes <= __intel_ring_space(target->postfix,
+						ring->emit, ring->size))
 			break;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 96710b616efb..1b1099b94912 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -17,17 +17,6 @@ 
 #define CACHELINE_BYTES 64
 #define CACHELINE_DWORDS (CACHELINE_BYTES / sizeof(uint32_t))
 
-/*
- * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use"
- * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use"
- * Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use"
- *
- * "If the Ring Buffer Head Pointer and the Tail Pointer are on the same
- * cacheline, the Head Pointer must not be greater than the Tail
- * Pointer."
- */
-#define I915_RING_FREE_SPACE 64
-
 struct intel_hw_status_page {
 	struct i915_vma *vma;
 	u32 *page_addr;
@@ -145,9 +134,9 @@  struct intel_ring {
 	u32 tail;
 	u32 emit;
 
-	int space;
-	int size;
-	int effective_size;
+	u32 space;
+	u32 size;
+	u32 effective_size;
 };
 
 struct i915_gem_context;
@@ -547,6 +536,19 @@  assert_ring_tail_valid(const struct intel_ring *ring, unsigned int tail)
 	 */
 	GEM_BUG_ON(!IS_ALIGNED(tail, 8));
 	GEM_BUG_ON(tail >= ring->size);
+
+	/* "Ring Buffer Use"
+	 *	Gen2 BSpec "1. Programming Environment" / 1.4.4.6
+	 *	Gen3 BSpec "1c Memory Interface Functions" / 2.3.4.5
+	 *	Gen4+ BSpec "1c Memory Interface and Command Stream" / 5.3.4.5
+	 * "If the Ring Buffer Head Pointer and the Tail Pointer are on the
+	 * same cacheline, the Head Pointer must not be greater than the Tail
+	 * Pointer."
+	 */
+#define cacheline(a) round_down(a, CACHELINE_BYTES)
+	GEM_BUG_ON(cacheline(tail) == cacheline(ring->head) &&
+		   tail < ring->head);
+#undef cacheline
 }
 
 static inline unsigned int