Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c0a6bfe authored by Chris Wilson's avatar Chris Wilson
Browse files

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: default avatarFang, Xun <xunx.fang@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32259


Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 8316f337
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -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;
+3 −2
Original line number Diff line number Diff line
@@ -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;