diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-05-04 09:08:44 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-05-04 10:40:38 -0400 |
commit | 605d5b3297687cce9d3c4298c699188e61486a4c (patch) | |
tree | 843b54037b92d5477ae26f5c3d68b44c68a0aea1 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | 266a240bf0abf1e00e72e571f3724ec753a35f19 (diff) |
drm/i915: Avoid the branch in computing intel_ring_space()
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.
References: https://bugs.freedesktop.org/show_bug.cgi?id=99671
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170504130846.4807-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3ce1c87dec46..46f2696bf886 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -39,12 +39,17 @@ | |||
39 | */ | 39 | */ |
40 | #define LEGACY_REQUEST_SIZE 200 | 40 | #define LEGACY_REQUEST_SIZE 200 |
41 | 41 | ||
42 | static int __intel_ring_space(int head, int tail, int size) | 42 | static unsigned int __intel_ring_space(unsigned int head, |
43 | unsigned int tail, | ||
44 | unsigned int size) | ||
43 | { | 45 | { |
44 | int space = head - tail; | 46 | /* |
45 | if (space <= 0) | 47 | * "If the Ring Buffer Head Pointer and the Tail Pointer are on the |
46 | space += size; | 48 | * same cacheline, the Head Pointer must not be greater than the Tail |
47 | return space - I915_RING_FREE_SPACE; | 49 | * Pointer." |
50 | */ | ||
51 | GEM_BUG_ON(!is_power_of_2(size)); | ||
52 | return (head - tail - CACHELINE_BYTES) & (size - 1); | ||
48 | } | 53 | } |
49 | 54 | ||
50 | void intel_ring_update_space(struct intel_ring *ring) | 55 | void intel_ring_update_space(struct intel_ring *ring) |
@@ -1670,12 +1675,9 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes) | |||
1670 | GEM_BUG_ON(!req->reserved_space); | 1675 | GEM_BUG_ON(!req->reserved_space); |
1671 | 1676 | ||
1672 | list_for_each_entry(target, &ring->request_list, ring_link) { | 1677 | list_for_each_entry(target, &ring->request_list, ring_link) { |
1673 | unsigned space; | ||
1674 | |||
1675 | /* Would completion of this request free enough space? */ | 1678 | /* Would completion of this request free enough space? */ |
1676 | space = __intel_ring_space(target->postfix, ring->emit, | 1679 | if (bytes <= __intel_ring_space(target->postfix, |
1677 | ring->size); | 1680 | ring->emit, ring->size)) |
1678 | if (space >= bytes) | ||
1679 | break; | 1681 | break; |
1680 | } | 1682 | } |
1681 | 1683 | ||
@@ -1744,11 +1746,11 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req, int num_dwords) | |||
1744 | } | 1746 | } |
1745 | 1747 | ||
1746 | GEM_BUG_ON(ring->emit > ring->size - bytes); | 1748 | GEM_BUG_ON(ring->emit > ring->size - bytes); |
1749 | GEM_BUG_ON(ring->space < bytes); | ||
1747 | cs = ring->vaddr + ring->emit; | 1750 | cs = ring->vaddr + ring->emit; |
1748 | GEM_DEBUG_EXEC(memset(cs, POISON_INUSE, bytes)); | 1751 | GEM_DEBUG_EXEC(memset(cs, POISON_INUSE, bytes)); |
1749 | ring->emit += bytes; | 1752 | ring->emit += bytes; |
1750 | ring->space -= bytes; | 1753 | ring->space -= bytes; |
1751 | GEM_BUG_ON(ring->space < 0); | ||
1752 | 1754 | ||
1753 | return cs; | 1755 | return cs; |
1754 | } | 1756 | } |