All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel, Thomas" <thomas.daniel@intel.com>
To: "intel-gfx@lists.freedesktop.org" <intel-gfx@lists.freedesktop.org>
Cc: "Belgaumkar, Vinay" <vinay.belgaumkar@intel.com>,
	"Goel, Akash" <akash.goel@intel.com>
Subject: Re: [PATCH v4] drm/i915: Add soft-pinning API for execbuffer
Date: Tue, 30 Jun 2015 14:20:36 +0000	[thread overview]
Message-ID: <BFEE8FEC12424048AF1805991D65FA912EDA08DA@irsmsx105.ger.corp.intel.com> (raw)
In-Reply-To: <1435673593-28127-1-git-send-email-thomas.daniel@intel.com>

Many apologies to Michal for incorrectly spelling his name in the CC list.

Thomas.

> -----Original Message-----
> From: Daniel, Thomas
> Sent: Tuesday, June 30, 2015 3:13 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Chris Wilson; Goel, Akash; Belgaumkar, Vinay; Michal Winiarsky; Zou,
> Nanhai; Daniel, Thomas
> Subject: [PATCH v4] drm/i915: Add soft-pinning API for execbuffer
> 
> From: Chris Wilson <chris@chris-wilson.co.uk>
> 
> Userspace can pass in an offset that it presumes the object is located
> at. The kernel will then do its utmost to fit the object into that
> location. The assumption is that userspace is handling its own object
> locations (for example along with full-ppgtt) and that the kernel will
> rarely have to make space for the user's requests.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> 
> v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris
> Wilson.  Fixed incorrect error paths causing crash found by Michal Winiarski.
> (Not published externally)
> 
> v3: Rebased because of trivial conflict in object_bind_to_vm.  Fixed eviction
> to allow eviction of soft-pinned objects when another soft-pinned object used
> by a subsequent execbuffer overlaps reported by Michal Winiarski.
> (Not published externally)
> 
> v4: Moved soft-pinned objects to the front of ordered_vmas so that they are
> pinned first after an address conflict happens to avoid repeated conflicts in
> rare cases (Suggested by Chris Wilson).  Expanded comment on
> drm_i915_gem_exec_object2.offset to cover this new API.
> 
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Akash Goel <akash.goel@intel.com>
> Cc: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
> Cc: Michal Winiarsky <michal.winiarsky@intel.com>
> Cc: Zou Nanhai <nanhai.zou@intel.com>
> Signed-off-by: Thomas Daniel <thomas.daniel@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h            |    4 +++
>  drivers/gpu/drm/i915/i915_gem.c            |   51 ++++++++++++++++++++--------
>  drivers/gpu/drm/i915/i915_gem_evict.c      |   38 +++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c |   16 +++++++--
>  include/uapi/drm/i915_drm.h                |    9 +++--
>  5 files changed, 99 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index d90a782..e96c101 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2747,7 +2747,9 @@ void i915_gem_vma_destroy(struct i915_vma *vma);
>  #define PIN_USER	(1<<4)
>  #define PIN_UPDATE	(1<<5)
>  #define PIN_FULL_RANGE	(1<<6)
> +#define PIN_OFFSET_FIXED	(1<<7)
>  #define PIN_OFFSET_MASK (~4095)
> +
>  int __must_check
>  i915_gem_object_pin(struct drm_i915_gem_object *obj,
>  		    struct i915_address_space *vm,
> @@ -3085,6 +3087,8 @@ int __must_check i915_gem_evict_something(struct
> drm_device *dev,
>  					  unsigned long start,
>  					  unsigned long end,
>  					  unsigned flags);
> +int __must_check
> +i915_gem_evict_for_vma(struct i915_vma *target);
>  int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
>  int i915_gem_evict_everything(struct drm_device *dev);
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c
> b/drivers/gpu/drm/i915/i915_gem.c
> index f170da6..a7e5ff2 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -3806,22 +3806,41 @@ i915_gem_object_bind_to_vm(struct
> drm_i915_gem_object *obj,
>  	if (IS_ERR(vma))
>  		goto err_unpin;
> 
> +	if (flags & PIN_OFFSET_FIXED) {
> +		uint64_t offset = flags & PIN_OFFSET_MASK;
> +		if (offset & (alignment - 1)) {
> +			ret = -EINVAL;
> +			goto err_free_vma;
> +		}
> +		vma->node.start = offset;
> +		vma->node.size = size;
> +		vma->node.color = obj->cache_level;
> +		ret = drm_mm_reserve_node(&vm->mm, &vma->node);
> +		if (ret) {
> +			ret = i915_gem_evict_for_vma(vma);
> +			if (ret == 0)
> +				ret = drm_mm_reserve_node(&vm->mm,
> &vma->node);
> +		}
> +		if (ret)
> +			goto err_free_vma;
> +	} else {
>  search_free:
> -	ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node,
> -						  size, alignment,
> -						  obj->cache_level,
> -						  start, end,
> -						  search_flag,
> -						  alloc_flag);
> -	if (ret) {
> -		ret = i915_gem_evict_something(dev, vm, size, alignment,
> -					       obj->cache_level,
> -					       start, end,
> -					       flags);
> -		if (ret == 0)
> -			goto search_free;
> +		ret = drm_mm_insert_node_in_range_generic(&vm->mm,
> &vma->node,
> +						  	  size, alignment,
> +						  	  obj->cache_level,
> +						  	  start, end,
> +						  	  search_flag,
> +						  	  alloc_flag);
> +		if (ret) {
> +			ret = i915_gem_evict_something(dev, vm, size,
> alignment,
> +					       	       obj->cache_level,
> +					       	       start, end,
> +					       	       flags);
> +			if (ret == 0)
> +				goto search_free;
> 
> -		goto err_free_vma;
> +			goto err_free_vma;
> +		}
>  	}
>  	if (WARN_ON(!i915_gem_valid_gtt_space(vma, obj->cache_level))) {
>  		ret = -EINVAL;
> @@ -4357,6 +4376,10 @@ i915_vma_misplaced(struct i915_vma *vma,
> uint32_t alignment, uint64_t flags)
>  	    vma->node.start < (flags & PIN_OFFSET_MASK))
>  		return true;
> 
> +	if (flags & PIN_OFFSET_FIXED &&
> +	    vma->node.start != (flags & PIN_OFFSET_MASK))
> +		return true;
> +
>  	return false;
>  }
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c
> b/drivers/gpu/drm/i915/i915_gem_evict.c
> index d09e35e..6098e2f 100644
> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
> @@ -199,6 +199,44 @@ found:
>  	return ret;
>  }
> 
> +int
> +i915_gem_evict_for_vma(struct i915_vma *target)
> +{
> +	struct drm_mm_node *node, *next;
> +
> +	list_for_each_entry_safe(node, next,
> +			&target->vm->mm.head_node.node_list,
> +			node_list) {
> +		struct i915_vma *vma;
> +		int ret;
> +
> +		if (node->start + node->size <= target->node.start)
> +			continue;
> +		if (node->start >= target->node.start + target->node.size)
> +			break;
> +
> +		vma = container_of(node, typeof(*vma), node);
> +
> +		if (vma->pin_count) {
> +			/* We may need to evict a buffer in the same batch */
> +			if (!vma->exec_entry)
> +				return -EBUSY;
> +
> +			if (vma->exec_entry->flags & EXEC_OBJECT_PINNED)
> +				/* Overlapping fixed objects in the same batch
> */
> +				return -EINVAL;
> +
> +			return -ENOSPC;
> +		}
> +
> +		ret = i915_vma_unbind(vma);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * i915_gem_evict_vm - Evict all idle vmas from a vm
>   * @vm: Address space to cleanse
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index 3d94744..4e6955e 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -596,6 +596,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma
> *vma,
>  			flags |= PIN_GLOBAL | PIN_MAPPABLE;
>  		if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS)
>  			flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
> +		if (entry->flags & EXEC_OBJECT_PINNED)
> +			flags |= entry->offset | PIN_OFFSET_FIXED;
>  	}
> 
>  	ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, flags);
> @@ -665,6 +667,10 @@ eb_vma_misplaced(struct i915_vma *vma)
>  	    vma->node.start & (entry->alignment - 1))
>  		return true;
> 
> +	if (entry->flags & EXEC_OBJECT_PINNED &&
> +	    vma->node.start != entry->offset)
> +		return true;
> +
>  	if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS &&
>  	    vma->node.start < BATCH_OFFSET_BIAS)
>  		return true;
> @@ -690,6 +696,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs
> *ring,
>  	struct i915_vma *vma;
>  	struct i915_address_space *vm;
>  	struct list_head ordered_vmas;
> +	struct list_head pinned_vmas;
>  	bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
>  	int retry;
> 
> @@ -698,6 +705,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs
> *ring,
>  	vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;
> 
>  	INIT_LIST_HEAD(&ordered_vmas);
> +	INIT_LIST_HEAD(&pinned_vmas);
>  	while (!list_empty(vmas)) {
>  		struct drm_i915_gem_exec_object2 *entry;
>  		bool need_fence, need_mappable;
> @@ -716,7 +724,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs
> *ring,
>  			obj->tiling_mode != I915_TILING_NONE;
>  		need_mappable = need_fence || need_reloc_mappable(vma);
> 
> -		if (need_mappable) {
> +		if (entry->flags & EXEC_OBJECT_PINNED)
> +			list_move_tail(&vma->exec_list, &pinned_vmas);
> +		else if (need_mappable) {
>  			entry->flags |= __EXEC_OBJECT_NEEDS_MAP;
>  			list_move(&vma->exec_list, &ordered_vmas);
>  		} else
> @@ -726,6 +736,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs
> *ring,
>  		obj->base.pending_write_domain = 0;
>  	}
>  	list_splice(&ordered_vmas, vmas);
> +	list_splice(&pinned_vmas, vmas);
> 
>  	/* Attempt to pin all of the buffers into the GTT.
>  	 * This is done in 3 phases:
> @@ -1404,7 +1415,8 @@ eb_get_batch(struct eb_vmas *eb)
>  	 * Note that actual hangs have only been observed on gen7, but for
>  	 * paranoia do it everywhere.
>  	 */
> -	vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;
> +	if ((vma->exec_entry->flags & EXEC_OBJECT_PINNED) == 0)
> +		vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;
> 
>  	return vma->obj;
>  }
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 55ba527..18f8f99 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -677,8 +677,10 @@ struct drm_i915_gem_exec_object2 {
>  	__u64 alignment;
> 
>  	/**
> -	 * Returned value of the updated offset of the object, for future
> -	 * presumed_offset writes.
> +	 * When the EXEC_OBJECT_PINNED flag is specified this is populated by
> +	 * the user with the GTT offset at which this object will be pinned.
> +	 * Otherwise the kernel populates it with the value of the updated
> +	 * offset of the object, for future presumed_offset writes.
>  	 */
>  	__u64 offset;
> 
> @@ -686,7 +688,8 @@ struct drm_i915_gem_exec_object2 {
>  #define EXEC_OBJECT_NEEDS_GTT	(1<<1)
>  #define EXEC_OBJECT_WRITE	(1<<2)
>  #define EXEC_OBJECT_SUPPORTS_48BBADDRESS (1<<3)
> -#define __EXEC_OBJECT_UNKNOWN_FLAGS -
> (EXEC_OBJECT_SUPPORTS_48BBADDRESS<<1)
> +#define EXEC_OBJECT_PINNED	(1<<4)
> +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)
>  	__u64 flags;
> 
>  	__u64 rsvd1;
> --
> 1.7.9.5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2015-06-30 14:20 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-06  9:44 [PATCH] drm/i915: Add soft-pinning API for execbuffer Chris Wilson
2015-03-11  6:41 ` [Intel-gfx] " Zhenyu Wang
2015-04-29 13:28 ` Daniel, Thomas
2015-04-29 14:01   ` Chris Wilson
2015-06-30 14:13 ` [PATCH v4] " Thomas Daniel
2015-06-30 14:20   ` Daniel, Thomas [this message]
2015-07-15 14:55     ` Goel, Akash
2015-07-15 15:06       ` Chris Wilson
2015-07-15 15:41         ` Daniel, Thomas
2015-07-15 15:46           ` Chris Wilson
2015-07-15 15:58             ` Daniel, Thomas
2015-07-15 16:04               ` Chris Wilson
2015-07-04  5:29   ` Kristian Høgsberg
2015-07-04 12:23     ` Chris Wilson
2015-07-08 15:04       ` Daniel, Thomas
2015-07-08 15:35         ` Chris Wilson
2015-07-04  7:53   ` Chris Wilson
2015-07-20 16:41   ` [PATCH v5] " Thomas Daniel
2015-07-20 16:50     ` Chris Wilson
2015-10-16 10:59     ` [PATCH v6] " Thomas Daniel
2015-10-16 14:09       ` Goel, Akash
2015-10-16 14:15         ` Chris Wilson
2015-12-02 11:28       ` Tvrtko Ursulin
2015-12-02 11:35         ` Chris Wilson
2015-12-08 11:55       ` [PATCH v7] " Thomas Daniel
2015-12-08 18:49         ` Michel Thierry
2015-12-09 10:30           ` Tvrtko Ursulin
2015-12-09 10:51             ` Chris Wilson
2015-12-09 12:34               ` Tvrtko Ursulin
2015-12-09 13:33                 ` Michel Thierry
2015-12-09 13:35                   ` Tvrtko Ursulin
2015-12-09 19:09                     ` Belgaumkar, Vinay

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=BFEE8FEC12424048AF1805991D65FA912EDA08DA@irsmsx105.ger.corp.intel.com \
    --to=thomas.daniel@intel.com \
    --cc=akash.goel@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=vinay.belgaumkar@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.