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

Commit f72b3435 authored by Mika Kuoppala's avatar Mika Kuoppala Committed by Daniel Vetter
Browse files

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: default avatarMika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 3ac18232
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
}
}


+21 −5
Original line number Original line Diff line number Diff line
@@ -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;