From 4243517b21cf64bcdd378ea0be6dde7ecbcbc448 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Tue, 28 Apr 2015 11:02:42 +0300 Subject: [PATCH 3/3] drm/i915/gtt: Allocate va range only if vma is not bound When we have bound vma into an address space, the layout of page table structures is immutable. So we can be absolutely certain that if vma is already bound, there is no need to (re)allocate a virtual address range for it. v2: - add sanity checks and remove superfluous GLOBAL_BIND set - we might do update for an unbound vma (Chris) v3: s/u32/unsigned (Chris) Testcase: igt/gem_exec_big #bdw Reported-by: Chris Wilson Cc: Chris Wilson Cc: Michel Thierry Cc: Daniel Vetter Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_gtt.c | 39 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6fae6bd..85f27d6 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1928,8 +1928,6 @@ static int ggtt_bind_vma(struct i915_vma *vma, vma->vm->insert_entries(vma->vm, pages, vma->node.start, cache_level, pte_flags); - - vma->bound |= GLOBAL_BIND; } if (dev_priv->mm.aliasing_ppgtt && flags & LOCAL_BIND) { @@ -2804,21 +2802,13 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma) int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags) { - int ret = 0; - u32 bind_flags = 0; - - if (vma->vm->allocate_va_range) { - trace_i915_va_alloc(vma->vm, vma->node.start, - vma->node.size, - VM_TO_TRACE_NAME(vma->vm)); + int ret; + unsigned bind_flags; - ret = vma->vm->allocate_va_range(vma->vm, - vma->node.start, - vma->node.size); - if (ret) - return ret; - } + if (WARN_ON(flags == 0)) + return -EINVAL; + bind_flags = 0; if (flags & PIN_GLOBAL) bind_flags |= GLOBAL_BIND; if (flags & PIN_USER) @@ -2829,8 +2819,23 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, else bind_flags &= ~vma->bound; - if (bind_flags) - ret = vma->vm->bind_vma(vma, cache_level, bind_flags); + if (bind_flags == 0) + return 0; + + if (vma->bound == 0 && vma->vm->allocate_va_range) { + trace_i915_va_alloc(vma->vm, + vma->node.start, + vma->node.size, + VM_TO_TRACE_NAME(vma->vm)); + + ret = vma->vm->allocate_va_range(vma->vm, + vma->node.start, + vma->node.size); + if (ret) + return ret; + } + + ret = vma->vm->bind_vma(vma, cache_level, bind_flags); if (ret) return ret; -- 1.9.1