[Intel-gfx] [PATCH] drm/i915: Pin relocations for the duration of constructing the execbuffer
Ben Widawsky
benjamin.widawsky at intel.com
Wed Nov 27 08:23:50 CET 2013
On Tue, Nov 26, 2013 at 11:23:15AM +0000, Chris Wilson wrote:
> As the execbuffer dispatch grows ever more complex and involves multiple
> stages of moving objects into the aperture, we need to take greater care
> that we do not evict our execbuffer objects prior to dispatch. This is
> relatively simple as we can just keep the objects pinned for not just
> the relocation but until we are finished.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Ben Widawsky <benjamin.widawsky at intel.com>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: stable at vger.kernel.org
To be honest, I don't quite see the actual issue, but the problem
description, and solution make sense to me. I've also been running with
the patch quite a bit on HSW.
Acked-by: Ben Widawsky <ben at bwidawsk.net>
Tested-by: Ben Widawsky <ben at bwidawsk.net>
> ---
> drivers/gpu/drm/i915/i915_gem_execbuffer.c | 60 ++++++++++++++++--------------
> 1 file changed, 32 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index 885d595e0e02..b7e787fb4649 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -33,6 +33,9 @@
> #include "intel_drv.h"
> #include <linux/dma_remapping.h>
>
> +#define __EXEC_OBJECT_HAS_PIN (1<<31)
> +#define __EXEC_OBJECT_HAS_FENCE (1<<30)
> +
> struct eb_vmas {
> struct list_head vmas;
> int and;
> @@ -187,7 +190,28 @@ static struct i915_vma *eb_get_vma(struct eb_vmas *eb, unsigned long handle)
> }
> }
>
> -static void eb_destroy(struct eb_vmas *eb) {
> +static void
> +i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
> +{
> + struct drm_i915_gem_exec_object2 *entry;
> + struct drm_i915_gem_object *obj = vma->obj;
> +
> + if (!drm_mm_node_allocated(&vma->node))
> + return;
> +
> + entry = vma->exec_entry;
> +
> + if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
> + i915_gem_object_unpin_fence(obj);
> +
> + if (entry->flags & __EXEC_OBJECT_HAS_PIN)
> + i915_gem_object_unpin(obj);
> +
> + entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
> +}
> +
> +static void eb_destroy(struct eb_vmas *eb)
> +{
> while (!list_empty(&eb->vmas)) {
> struct i915_vma *vma;
>
> @@ -195,6 +219,7 @@ static void eb_destroy(struct eb_vmas *eb) {
> struct i915_vma,
> exec_list);
> list_del_init(&vma->exec_list);
> + i915_gem_execbuffer_unreserve_vma(vma);
> drm_gem_object_unreference(&vma->obj->base);
> }
> kfree(eb);
> @@ -478,9 +503,6 @@ i915_gem_execbuffer_relocate(struct eb_vmas *eb,
> return ret;
> }
>
> -#define __EXEC_OBJECT_HAS_PIN (1<<31)
> -#define __EXEC_OBJECT_HAS_FENCE (1<<30)
> -
> static int
> need_reloc_mappable(struct i915_vma *vma)
> {
> @@ -552,26 +574,6 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma,
> return 0;
> }
>
> -static void
> -i915_gem_execbuffer_unreserve_vma(struct i915_vma *vma)
> -{
> - struct drm_i915_gem_exec_object2 *entry;
> - struct drm_i915_gem_object *obj = vma->obj;
> -
> - if (!drm_mm_node_allocated(&vma->node))
> - return;
> -
> - entry = vma->exec_entry;
> -
> - if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
> - i915_gem_object_unpin_fence(obj);
> -
> - if (entry->flags & __EXEC_OBJECT_HAS_PIN)
> - i915_gem_object_unpin(obj);
> -
> - entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
> -}
> -
> static int
> i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
> struct list_head *vmas,
> @@ -670,13 +672,14 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
> goto err;
> }
>
> -err: /* Decrement pin count for bound objects */
> - list_for_each_entry(vma, vmas, exec_list)
> - i915_gem_execbuffer_unreserve_vma(vma);
> -
> +err:
> if (ret != -ENOSPC || retry++)
> return ret;
>
> + /* Decrement pin count for bound objects */
> + list_for_each_entry(vma, vmas, exec_list)
> + i915_gem_execbuffer_unreserve_vma(vma);
> +
> ret = i915_gem_evict_vm(vm, true);
> if (ret)
> return ret;
> @@ -708,6 +711,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
> while (!list_empty(&eb->vmas)) {
> vma = list_first_entry(&eb->vmas, struct i915_vma, exec_list);
> list_del_init(&vma->exec_list);
> + i915_gem_execbuffer_unreserve_vma(vma);
> drm_gem_object_unreference(&vma->obj->base);
> }
>
> --
> 1.8.4.4
>
--
Ben Widawsky, Intel Open Source Technology Center
More information about the Intel-gfx
mailing list