mirror of
https://github.com/torvalds/linux.git
synced 2024-12-17 08:31:39 +00:00
drm/i915/ringbuffer: Handle wrapping of the autoreported HEAD
If the tail advances beyond the autoreport HEAD value, then we need to fallback to an uncached read of the HEAD register in order to ascertain the correct amount of remaining space in the ringbuffer. Reported-by: Fang, Xun <xunx.fang@intel.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32259 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
8316f33766
commit
8c0a6bfef1
@ -696,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev,
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
u32 head;
|
||||
|
||||
head = intel_read_status_page(ring, 4);
|
||||
if (head) {
|
||||
ring->head = head & HEAD_ADDR;
|
||||
ring->space = ring->head - (ring->tail + 8);
|
||||
if (ring->space < 0)
|
||||
ring->space += ring->size;
|
||||
if (ring->space >= n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
trace_i915_ring_wait_begin (dev);
|
||||
end = jiffies + 3 * HZ;
|
||||
do {
|
||||
ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
|
||||
/* If the reported head position has wrapped or hasn't advanced,
|
||||
* fallback to the slow and accurate path.
|
||||
*/
|
||||
head = intel_read_status_page(ring, 4);
|
||||
if (head < ring->actual_head)
|
||||
head = I915_READ_HEAD(ring);
|
||||
ring->actual_head = head;
|
||||
ring->head = head & HEAD_ADDR;
|
||||
ring->space = ring->head - (ring->tail + 8);
|
||||
if (ring->space < 0)
|
||||
ring->space += ring->size;
|
||||
|
@ -30,8 +30,9 @@ struct intel_ring_buffer {
|
||||
struct drm_device *dev;
|
||||
struct drm_gem_object *gem_object;
|
||||
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
u32 actual_head;
|
||||
u32 head;
|
||||
u32 tail;
|
||||
int space;
|
||||
struct intel_hw_status_page status_page;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user