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>
This commit is contained in:
parent
3ac1823294
commit
f72b3435c1
|
@ -671,7 +671,7 @@ typedef struct drm_i915_private {
|
||||||
|
|
||||||
struct pci_dev *bridge_dev;
|
struct pci_dev *bridge_dev;
|
||||||
struct intel_ring_buffer ring[I915_NUM_RINGS];
|
struct intel_ring_buffer ring[I915_NUM_RINGS];
|
||||||
uint32_t next_seqno;
|
uint32_t last_seqno, next_seqno;
|
||||||
|
|
||||||
drm_dma_handle_t *status_page_dmah;
|
drm_dma_handle_t *status_page_dmah;
|
||||||
struct resource mch_res;
|
struct resource mch_res;
|
||||||
|
|
|
@ -1969,7 +1969,7 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
|
||||||
dev_priv->next_seqno = 1;
|
dev_priv->next_seqno = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*seqno = dev_priv->next_seqno++;
|
*seqno = dev_priv->last_seqno = dev_priv->next_seqno++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -596,6 +596,13 @@ gen6_add_request(struct intel_ring_buffer *ring)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev,
|
||||||
|
u32 seqno)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
return dev_priv->last_seqno < seqno;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_ring_sync - sync the waiter to the signaller on seqno
|
* intel_ring_sync - sync the waiter to the signaller on seqno
|
||||||
*
|
*
|
||||||
|
@ -626,11 +633,20 @@ gen6_ring_sync(struct intel_ring_buffer *waiter,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* If seqno wrap happened, omit the wait with no-ops */
|
||||||
|
if (likely(!i915_gem_has_seqno_wrapped(waiter->dev, seqno))) {
|
||||||
intel_ring_emit(waiter,
|
intel_ring_emit(waiter,
|
||||||
dw1 | signaller->semaphore_register[waiter->id]);
|
dw1 |
|
||||||
|
signaller->semaphore_register[waiter->id]);
|
||||||
intel_ring_emit(waiter, seqno);
|
intel_ring_emit(waiter, seqno);
|
||||||
intel_ring_emit(waiter, 0);
|
intel_ring_emit(waiter, 0);
|
||||||
intel_ring_emit(waiter, MI_NOOP);
|
intel_ring_emit(waiter, MI_NOOP);
|
||||||
|
} else {
|
||||||
|
intel_ring_emit(waiter, MI_NOOP);
|
||||||
|
intel_ring_emit(waiter, MI_NOOP);
|
||||||
|
intel_ring_emit(waiter, MI_NOOP);
|
||||||
|
intel_ring_emit(waiter, MI_NOOP);
|
||||||
|
}
|
||||||
intel_ring_advance(waiter);
|
intel_ring_advance(waiter);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue