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

Commit 0a878716 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

drm/i915: restore ggtt double-bind avoidance



This was accidentally lost in

commit 75d04a37
Author: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Date:   Tue Apr 28 17:56:17 2015 +0300

    drm/i915/gtt: Allocate va range only if vma is not bound

While at it implement an improved version suggested by Chris which
avoids the double-bind irrespective of what type of bind is done
first.

Note that this exact bug was already addressed in

commit d0e30adc
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Wed Jul 29 20:02:48 2015 +0100

    drm/i915: Mark PIN_USER binding as GLOBAL_BIND without the aliasing ppgtt

but the problem is still that originally in

commit 0875546c
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Mon Apr 20 09:04:05 2015 -0700

    drm/i915: Fix up the vma aliasing ppgtt binding

if forgotten to take into account there case where we have a
GLOBAL_BIND before a LOCAL_BIND. This patch here fixes that.

v2: Pimp commit message and revert the partial fix.

v3: Split into two functions to specialize on aliasing_ppgtt y/n.

v4: WARN_ON for paranoia in the init sequence, since the ggtt probe
and aliasing ppgtt setup are far apart.

v5: Style nits.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: http://mid.gmane.org/1444911781-32607-1-git-send-email-daniel.vetter@ffwll.ch


Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent e12c8ce8
Loading
Loading
Loading
Loading
+34 −12
Original line number Diff line number Diff line
@@ -2501,6 +2501,36 @@ static void i915_ggtt_clear_range(struct i915_address_space *vm,
static int ggtt_bind_vma(struct i915_vma *vma,
			 enum i915_cache_level cache_level,
			 u32 flags)
{
	struct drm_i915_gem_object *obj = vma->obj;
	u32 pte_flags = 0;
	int ret;

	ret = i915_get_ggtt_vma_pages(vma);
	if (ret)
		return ret;

	/* Currently applicable only to VLV */
	if (obj->gt_ro)
		pte_flags |= PTE_READ_ONLY;

	vma->vm->insert_entries(vma->vm, vma->ggtt_view.pages,
				vma->node.start,
				cache_level, pte_flags);

	/*
	 * Without aliasing PPGTT there's no difference between
	 * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally
	 * upgrade to both bound if we bind either to avoid double-binding.
	 */
	vma->bound |= GLOBAL_BIND | LOCAL_BIND;

	return 0;
}

static int aliasing_gtt_bind_vma(struct i915_vma *vma,
				 enum i915_cache_level cache_level,
				 u32 flags)
{
	struct drm_device *dev = vma->vm->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2519,23 +2549,13 @@ static int ggtt_bind_vma(struct i915_vma *vma,
		pte_flags |= PTE_READ_ONLY;


	if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) {
	if (flags & GLOBAL_BIND) {
		vma->vm->insert_entries(vma->vm, pages,
					vma->node.start,
					cache_level, pte_flags);

		/* Note the inconsistency here is due to absence of the
		 * aliasing ppgtt on gen4 and earlier. Though we always
		 * request PIN_USER for execbuffer (translated to LOCAL_BIND),
		 * without the appgtt, we cannot honour that request and so
		 * must substitute it with a global binding. Since we do this
		 * behind the upper layers back, we need to explicitly set
		 * the bound flag ourselves.
		 */
		vma->bound |= GLOBAL_BIND;
	}

	if (dev_priv->mm.aliasing_ppgtt && flags & LOCAL_BIND) {
	if (flags & LOCAL_BIND) {
		struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
		appgtt->base.insert_entries(&appgtt->base, pages,
					    vma->node.start,
@@ -2699,6 +2719,8 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
					true);

		dev_priv->mm.aliasing_ppgtt = ppgtt;
		WARN_ON(dev_priv->gtt.base.bind_vma != ggtt_bind_vma);
		dev_priv->gtt.base.bind_vma = aliasing_gtt_bind_vma;
	}

	return 0;