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

Commit 395b70be authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Flush read-only buffers from the active list upon idle as well



It is possible for the active list to only contain a read-only buffer so
that the ring->gpu_write_list remains entry. This leads to an
inconsistency between i915_gpu_is_active() and i915_gpu_idle() causing
an infinite spin during the shrinker and an assertion failure that
i915_gpu_idle() does indeed flush all buffers from the active lists.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 8f28f54a
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
@@ -2172,7 +2172,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
static int i915_ring_idle(struct drm_device *dev,
			  struct intel_ring_buffer *ring)
{
	if (list_empty(&ring->gpu_write_list))
	if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list))
		return 0;

	i915_gem_flush_ring(dev, NULL, ring,
@@ -2190,9 +2190,7 @@ i915_gpu_idle(struct drm_device *dev)
	int ret;

	lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
		       list_empty(&dev_priv->render_ring.active_list) &&
		       list_empty(&dev_priv->bsd_ring.active_list) &&
		       list_empty(&dev_priv->blt_ring.active_list));
		       list_empty(&dev_priv->mm.active_list));
	if (lists_empty)
		return 0;

@@ -4900,9 +4898,7 @@ i915_gpu_is_active(struct drm_device *dev)
	int lists_empty;

	lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
		      list_empty(&dev_priv->render_ring.active_list) &&
		      list_empty(&dev_priv->bsd_ring.active_list) &&
		      list_empty(&dev_priv->blt_ring.active_list);
		      list_empty(&dev_priv->mm.active_list);

	return !lists_empty;
}
+2 −6
Original line number Diff line number Diff line
@@ -165,9 +165,7 @@ i915_gem_evict_everything(struct drm_device *dev)

	lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
		       list_empty(&dev_priv->mm.flushing_list) &&
		       list_empty(&dev_priv->render_ring.active_list) &&
		       list_empty(&dev_priv->bsd_ring.active_list) &&
		       list_empty(&dev_priv->blt_ring.active_list));
		       list_empty(&dev_priv->mm.active_list));
	if (lists_empty)
		return -ENOSPC;

@@ -184,9 +182,7 @@ i915_gem_evict_everything(struct drm_device *dev)

	lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
		       list_empty(&dev_priv->mm.flushing_list) &&
		       list_empty(&dev_priv->render_ring.active_list) &&
		       list_empty(&dev_priv->bsd_ring.active_list) &&
		       list_empty(&dev_priv->blt_ring.active_list));
		       list_empty(&dev_priv->mm.active_list));
	BUG_ON(!lists_empty);

	return 0;