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

Commit a6508ded authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Use page coloring to provide the guard page at the end of the GTT



As we now mark the reserved hole (drm_mm.head_node) with the special
UNEVICTABLE color, we can use the page coloring to avoid prefetching of
the CS beyond the end of the GTT.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170206084547.27921-3-chris@chris-wilson.co.uk


Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
parent 47db922f
Loading
Loading
Loading
Loading
+8 −2
Original line number Original line Diff line number Diff line
@@ -253,6 +253,9 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
	int ret = 0;
	int ret = 0;


	lockdep_assert_held(&vm->i915->drm.struct_mutex);
	lockdep_assert_held(&vm->i915->drm.struct_mutex);
	GEM_BUG_ON(!IS_ALIGNED(start, I915_GTT_PAGE_SIZE));
	GEM_BUG_ON(!IS_ALIGNED(end, I915_GTT_PAGE_SIZE));

	trace_i915_gem_evict_node(vm, target, flags);
	trace_i915_gem_evict_node(vm, target, flags);


	/* Retire before we search the active list. Although we have
	/* Retire before we search the active list. Although we have
@@ -268,9 +271,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
		/* Expand search to cover neighbouring guard pages (or lack!) */
		/* Expand search to cover neighbouring guard pages (or lack!) */
		if (start > vm->start)
		if (start > vm->start)
			start -= I915_GTT_PAGE_SIZE;
			start -= I915_GTT_PAGE_SIZE;
		if (end < vm->start + vm->total)

		/* Always look at the page afterwards to avoid the end-of-GTT */
		end += I915_GTT_PAGE_SIZE;
		end += I915_GTT_PAGE_SIZE;
	}
	}
	GEM_BUG_ON(start >= end);


	drm_mm_for_each_node_in_range(node, &vm->mm, start, end) {
	drm_mm_for_each_node_in_range(node, &vm->mm, start, end) {
		/* If we find any non-objects (!vma), we cannot evict them */
		/* If we find any non-objects (!vma), we cannot evict them */
@@ -279,6 +284,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
			break;
			break;
		}
		}


		GEM_BUG_ON(!node->allocated);
		vma = container_of(node, typeof(*vma), node);
		vma = container_of(node, typeof(*vma), node);


		/* If we are using coloring to insert guard pages between
		/* If we are using coloring to insert guard pages between
+12 −7
Original line number Original line Diff line number Diff line
@@ -2718,11 +2718,16 @@ static void i915_gtt_color_adjust(const struct drm_mm_node *node,
				  u64 *start,
				  u64 *start,
				  u64 *end)
				  u64 *end)
{
{
	if (node->color != color)
	if (node->allocated && node->color != color)
		*start += I915_GTT_PAGE_SIZE;
		*start += I915_GTT_PAGE_SIZE;


	/* Also leave a space between the unallocated reserved node after the
	 * GTT and any objects within the GTT, i.e. we use the color adjustment
	 * to insert a guard page to prevent prefetches crossing over the
	 * GTT boundary.
	 */
	node = list_next_entry(node, node_list);
	node = list_next_entry(node, node_list);
	if (node->allocated && node->color != color)
	if (node->color != color)
		*end -= I915_GTT_PAGE_SIZE;
		*end -= I915_GTT_PAGE_SIZE;
}
}


@@ -3243,14 +3248,14 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)


	INIT_LIST_HEAD(&dev_priv->vm_list);
	INIT_LIST_HEAD(&dev_priv->vm_list);


	/* Subtract the guard page before address space initialization to
	/* Note that we use page colouring to enforce a guard page at the
	 * shrink the range used by drm_mm.
	 * end of the address space. This is required as the CS may prefetch
	 * beyond the end of the batch buffer, across the page boundary,
	 * and beyond the end of the GTT if we do not provide a guard.
	 */
	 */
	mutex_lock(&dev_priv->drm.struct_mutex);
	mutex_lock(&dev_priv->drm.struct_mutex);
	ggtt->base.total -= I915_GTT_PAGE_SIZE;
	i915_address_space_init(&ggtt->base, dev_priv, "[global]");
	i915_address_space_init(&ggtt->base, dev_priv, "[global]");
	ggtt->base.total += I915_GTT_PAGE_SIZE;
	if (!HAS_LLC(dev_priv) && !USES_PPGTT(dev_priv))
	if (!HAS_LLC(dev_priv))
		ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
		ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
	mutex_unlock(&dev_priv->drm.struct_mutex);
	mutex_unlock(&dev_priv->drm.struct_mutex);