Commit 51dc276d authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Leave vma intact as they are discarded

If we find ourselves trying to reuse a misplaced but active vma, we
currently try to discard it to avoid having to wait to unbind it
(upsetting the current user fo the vma). An alternative to marking it as
a dicarded vma and keeping it in both the obj->vma.list and
obj->vma.tree, is to simply remove it from the lookup rbtree.

While it remains in the list of vma, it will be unbound under eviction
pressure and freed along with the object. We will never reuse it again
for new instances. As before, with no pruning, the list may continually
grow, but eventually we will have the most constrained version of the
ggtt view that meets all requirements -- so the list of vma should not
grow without bound.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/2012


Fixes: 9bdcaa5e ("drm/i915: Discard a misplaced GGTT vma")
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Matthew Auld <matthew.auld@intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200611180421.23262-1-chris@chris-wilson.co.uk
parent 94641eb6
Loading
Loading
Loading
Loading
+5 −33
Original line number Diff line number Diff line
@@ -933,44 +933,16 @@ void i915_gem_runtime_suspend(struct drm_i915_private *i915)
	}
}

static bool
discard_ggtt_vma(struct i915_vma *vma, const struct i915_ggtt_view *view)
static void discard_ggtt_vma(struct i915_vma *vma)
{
	const struct i915_ggtt_view discard = {
		.type = I915_GGTT_VIEW_PARTIAL,
	};
	struct drm_i915_gem_object *obj = vma->obj;

	spin_lock(&obj->vma.lock);
	if (i915_vma_compare(vma, vma->vm, &discard)) {
		struct rb_node *rb, **p;

	if (!RB_EMPTY_NODE(&vma->obj_node)) {
		rb_erase(&vma->obj_node, &obj->vma.tree);
		vma->ggtt_view = discard;
		GEM_BUG_ON(i915_vma_compare(vma, vma->vm, &discard));
		GEM_BUG_ON(i915_vma_compare(vma, vma->vm, view) == 0);

		rb = NULL;
		p = &obj->vma.tree.rb_node;
		while (*p) {
			struct i915_vma *pos;
			long cmp;

			rb = *p;
			pos = rb_entry(rb, struct i915_vma, obj_node);

			cmp = i915_vma_compare(pos, vma->vm, &discard);
			if (cmp < 0)
				p = &rb->rb_right;
			else
				p = &rb->rb_left;
		}
		rb_link_node(&vma->obj_node, rb, p);
		rb_insert_color(&vma->obj_node, &obj->vma.tree);
		RB_CLEAR_NODE(&vma->obj_node);
	}
	spin_unlock(&obj->vma.lock);

	return i915_vma_compare(vma, vma->vm, view);
}

struct i915_vma *
@@ -1035,7 +1007,7 @@ new_vma:
		}

		if (i915_vma_is_pinned(vma) || i915_vma_is_active(vma)) {
			if (discard_ggtt_vma(vma, view))
			discard_ggtt_vma(vma);
			goto new_vma;
		}

+2 −1
Original line number Diff line number Diff line
@@ -1087,6 +1087,7 @@ void i915_vma_release(struct kref *ref)

		spin_lock(&obj->vma.lock);
		list_del(&vma->obj_link);
		if (!RB_EMPTY_NODE(&vma->obj_node))
			rb_erase(&vma->obj_node, &obj->vma.tree);
		spin_unlock(&obj->vma.lock);
	}