diff options
author | Mika Kuoppala <mika.kuoppala@linux.intel.com> | 2012-12-10 08:41:48 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-12-11 07:32:26 -0500 |
commit | f72b3435c1a75406d82d6e252bb78f009efd4bd9 (patch) | |
tree | 5b9e854dc74ca4d52374cd6e7e816312c6daca31 /drivers/gpu/drm/i915/intel_ringbuffer.c | |
parent | 3ac18232946aacf0a9807c3143f8449ed4aa68f4 (diff) |
drm/i915: Don't emit semaphore wait if wrap happened
If wrap just happened we need to prevent emitting waits for
pre wrap values. Detect this and emit no-ops instead.
v2: Use olr > seqno to detect wrap instead of *seqno == 0
as suggested by Chris Wilson.
v3: Use last used seqno to detect the wraparound. From
Chris Wilson
v4: Fixed unnecessary last_seqno assigment
References: https://bugs.freedesktop.org/show_bug.cgi?id=57967
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0d03dc649c5e..69bbe7bb9f6d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -596,6 +596,13 @@ gen6_add_request(struct intel_ring_buffer *ring) | |||
596 | return 0; | 596 | return 0; |
597 | } | 597 | } |
598 | 598 | ||
599 | static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev, | ||
600 | u32 seqno) | ||
601 | { | ||
602 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
603 | return dev_priv->last_seqno < seqno; | ||
604 | } | ||
605 | |||
599 | /** | 606 | /** |
600 | * intel_ring_sync - sync the waiter to the signaller on seqno | 607 | * intel_ring_sync - sync the waiter to the signaller on seqno |
601 | * | 608 | * |
@@ -626,11 +633,20 @@ gen6_ring_sync(struct intel_ring_buffer *waiter, | |||
626 | if (ret) | 633 | if (ret) |
627 | return ret; | 634 | return ret; |
628 | 635 | ||
629 | intel_ring_emit(waiter, | 636 | /* If seqno wrap happened, omit the wait with no-ops */ |
630 | dw1 | signaller->semaphore_register[waiter->id]); | 637 | if (likely(!i915_gem_has_seqno_wrapped(waiter->dev, seqno))) { |
631 | intel_ring_emit(waiter, seqno); | 638 | intel_ring_emit(waiter, |
632 | intel_ring_emit(waiter, 0); | 639 | dw1 | |
633 | intel_ring_emit(waiter, MI_NOOP); | 640 | signaller->semaphore_register[waiter->id]); |
641 | intel_ring_emit(waiter, seqno); | ||
642 | intel_ring_emit(waiter, 0); | ||
643 | intel_ring_emit(waiter, MI_NOOP); | ||
644 | } else { | ||
645 | intel_ring_emit(waiter, MI_NOOP); | ||
646 | intel_ring_emit(waiter, MI_NOOP); | ||
647 | intel_ring_emit(waiter, MI_NOOP); | ||
648 | intel_ring_emit(waiter, MI_NOOP); | ||
649 | } | ||
634 | intel_ring_advance(waiter); | 650 | intel_ring_advance(waiter); |
635 | 651 | ||
636 | return 0; | 652 | return 0; |