From 616d9cee4fdc4a377c03be8fd6efa5df4fcd0d81 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 16 Jun 2017 15:05:21 +0100 Subject: [PATCH] drm/i915: First try the previous execbuffer location When choosing a slot for an execbuffer, we ideally want to use the same address as last time (so that we don't have to rebind it) and the same address as expected by the user (so that we don't have to fixup any relocations pointing to it). If we first try to bind the incoming execbuffer->offset from the user, or the currently bound offset that should hopefully achieve the goal of avoiding the rebind cost and the relocation penalty. However, if the object is not currently bound there we don't want to arbitrarily unbind an object in our chosen position and so choose to rebind/relocate the incoming object instead. After we report the new position back to the user, on the next pass the relocations should have settled down. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 12 ++++++++---- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++++++ drivers/gpu/drm/i915/i915_gem_gtt.h | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d91386f0e840..3eaf07dfbe62 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -336,10 +336,15 @@ eb_pin_vma(struct i915_execbuffer *eb, { u64 flags; - flags = vma->node.start; - flags |= PIN_USER | PIN_NONBLOCK | PIN_OFFSET_FIXED; + if (vma->node.size) + flags = vma->node.start; + else + flags = entry->offset & PIN_OFFSET_MASK; + + flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED; if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_GTT)) flags |= PIN_GLOBAL; + if (unlikely(i915_vma_pin(vma, 0, 0, flags))) return; @@ -469,8 +474,7 @@ eb_add_vma(struct i915_execbuffer *eb, __exec_to_vma(entry) = (uintptr_t)vma; err = 0; - if (vma->node.size) - eb_pin_vma(eb, entry, vma); + eb_pin_vma(eb, entry, vma); if (eb_vma_misplaced(entry, vma)) { eb_unreserve_vma(vma, entry); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 4ff854e6413c..205dd91d3601 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3402,6 +3402,9 @@ int i915_gem_gtt_reserve(struct i915_address_space *vm, if (err != -ENOSPC) return err; + if (flags & PIN_NOEVICT) + return -ENOSPC; + err = i915_gem_evict_for_node(vm, node, flags); if (err == 0) err = drm_mm_reserve_node(&vm->mm, node); @@ -3516,6 +3519,9 @@ int i915_gem_gtt_insert(struct i915_address_space *vm, if (err != -ENOSPC) return err; + if (flags & PIN_NOEVICT) + return -ENOSPC; + /* No free space, pick a slot at random. * * There is a pathological case here using a GTT shared between diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index da9aa9f706e7..1b2a56c3e5d3 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -589,6 +589,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm, #define PIN_MAPPABLE BIT(1) #define PIN_ZONE_4G BIT(2) #define PIN_NONFAULT BIT(3) +#define PIN_NOEVICT BIT(4) #define PIN_MBZ BIT(5) /* I915_VMA_PIN_OVERFLOW */ #define PIN_GLOBAL BIT(6) /* I915_VMA_GLOBAL_BIND */ -- GitLab