public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 47/64] drm/i915: Be more careful when unbinding vma
Date: Tue, 12 Jul 2016 16:04:57 +0100	[thread overview]
Message-ID: <57850719.3040104@linux.intel.com> (raw)
In-Reply-To: <1467880930-23082-47-git-send-email-chris@chris-wilson.co.uk>


On 07/07/16 09:41, Chris Wilson wrote:
> When we call i915_vma_unbind(), we will wait upon outstanding rendering.
> This will also trigger a retirement phase, which may update the object
> lists. If, we extend request tracking to the VMA itself (rather than
> keep it at the encompassing object), then there is a potential that the
> obj->vma_list be modified for other elements upon i915_vma_unbind(). As
> a result, if we walk over the object list and call i915_vma_unbind(), we
> need to be prepared for that list to change.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_drv.h          |  2 ++
>   drivers/gpu/drm/i915/i915_gem.c          | 57 +++++++++++++++++++++++---------
>   drivers/gpu/drm/i915/i915_gem_shrinker.c |  7 +---
>   drivers/gpu/drm/i915/i915_gem_userptr.c  |  4 +--
>   4 files changed, 46 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 633585054669..27e1182544a2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3032,6 +3032,8 @@ int __must_check i915_vma_unbind(struct i915_vma *vma);
>    * _guarantee_ VMA in question is _not in use_ anywhere.
>    */
>   int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
> +
> +int i915_gem_object_unbind(struct drm_i915_gem_object *obj);
>   int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
>   void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
>   void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index c6816f9969d5..28a3079a7892 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -283,18 +283,38 @@ static const struct drm_i915_gem_object_ops i915_gem_phys_ops = {
>   	.release = i915_gem_object_release_phys,
>   };
>
> +int
> +i915_gem_object_unbind(struct drm_i915_gem_object *obj)
> +{
> +	struct i915_vma *vma;
> +	LIST_HEAD(still_in_list);
> +	int ret;
> +
> +	/* The vma will only be freed if it is marked as closed, and if we wait
> +	 * upon rendering to the vma, we may unbind anything in the list.
> +	 */
> +	while ((vma = list_first_entry_or_null(&obj->vma_list,
> +					       struct i915_vma,
> +					       obj_link))) {
> +		list_move_tail(&vma->obj_link, &still_in_list);
> +		ret = i915_vma_unbind(vma);
> +		if (ret)
> +			break;
> +	}
> +	list_splice(&still_in_list, &obj->vma_list);
> +
> +	return ret;
> +}
> +
>   static int
>   drop_pages(struct drm_i915_gem_object *obj)
>   {
> -	struct i915_vma *vma, *next;
>   	int ret;
>
>   	i915_gem_object_get(obj);
> -	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link)
> -		if (i915_vma_unbind(vma))
> -			break;
> -
> -	ret = i915_gem_object_put_pages(obj);
> +	ret = i915_gem_object_unbind(obj);
> +	if (ret == 0)
> +		ret = i915_gem_object_put_pages(obj);
>   	i915_gem_object_put(obj);
>
>   	return ret;
> @@ -3442,8 +3462,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
>   int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
>   				    enum i915_cache_level cache_level)
>   {
> -	struct drm_device *dev = obj->base.dev;
> -	struct i915_vma *vma, *next;
> +	struct i915_vma *vma;
>   	int ret = 0;
>
>   	if (obj->cache_level == cache_level)
> @@ -3454,7 +3473,8 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
>   	 * catch the issue of the CS prefetch crossing page boundaries and
>   	 * reading an invalid PTE on older architectures.
>   	 */
> -	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
> +restart:
> +	list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   		if (!drm_mm_node_allocated(&vma->node))
>   			continue;
>
> @@ -3463,11 +3483,18 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
>   			return -EBUSY;
>   		}
>
> -		if (!i915_gem_valid_gtt_space(vma, cache_level)) {
> -			ret = i915_vma_unbind(vma);
> -			if (ret)
> -				return ret;
> -		}
> +		if (i915_gem_valid_gtt_space(vma, cache_level))
> +			continue;
> +
> +		ret = i915_vma_unbind(vma);
> +		if (ret)
> +			return ret;
> +
> +		/* As unbinding may affect other elements in the
> +		 * obj->vma_list (due to side-effects from retiring
> +		 * an active vma), play safe and restart the iterator.
> +		 */
> +		goto restart;
>   	}

Does not look efficient for long lists but I don't see a solution right 
now. Any chance of this O(N^2) iteration hurting us in the real world?

>
>   	/* We can reuse the existing drm_mm nodes but need to change the
> @@ -3486,7 +3513,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
>   		if (ret)
>   			return ret;
>
> -		if (!HAS_LLC(dev) && cache_level != I915_CACHE_NONE) {
> +		if (!HAS_LLC(obj->base.dev) && cache_level != I915_CACHE_NONE) {
>   			/* Access to snoopable pages through the GTT is
>   			 * incoherent and on some machines causes a hard
>   			 * lockup. Relinquish the CPU mmaping to force
> diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> index 725a8c894517..8ad95695f80c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
> +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> @@ -155,7 +155,6 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
>   		INIT_LIST_HEAD(&still_in_list);
>   		while (count < target && !list_empty(phase->list)) {
>   			struct drm_i915_gem_object *obj;
> -			struct i915_vma *vma, *v;
>
>   			obj = list_first_entry(phase->list,
>   					       typeof(*obj), global_list);
> @@ -178,11 +177,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
>   			i915_gem_object_get(obj);
>
>   			/* For the unbound phase, this should be a no-op! */
> -			list_for_each_entry_safe(vma, v,
> -						 &obj->vma_list, obj_link)
> -				if (i915_vma_unbind(vma))
> -					break;
> -
> +			i915_gem_object_unbind(obj);
>   			if (i915_gem_object_put_pages(obj) == 0)
>   				count += obj->base.size >> PAGE_SHIFT;
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
> index ca8b82ab93d6..e935b327f3f9 100644
> --- a/drivers/gpu/drm/i915/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
> @@ -104,7 +104,6 @@ static void cancel_userptr(struct work_struct *work)
>
>   	if (obj->pages != NULL) {
>   		struct drm_i915_private *dev_priv = to_i915(dev);
> -		struct i915_vma *vma, *tmp;
>   		bool was_interruptible;
>
>   		wait_rendering(obj);
> @@ -112,8 +111,7 @@ static void cancel_userptr(struct work_struct *work)
>   		was_interruptible = dev_priv->mm.interruptible;
>   		dev_priv->mm.interruptible = false;
>
> -		list_for_each_entry_safe(vma, tmp, &obj->vma_list, obj_link)
> -			WARN_ON(i915_vma_unbind(vma));
> +		WARN_ON(i915_gem_object_unbind(obj));
>   		WARN_ON(i915_gem_object_put_pages(obj));
>
>   		dev_priv->mm.interruptible = was_interruptible;
>

Regards,

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

  reply	other threads:[~2016-07-12 15:05 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-07  8:41 [PATCH 01/64] drm/i915/breadcrumbs: Queue hangcheck before sleeping Chris Wilson
2016-07-07  8:41 ` [PATCH 02/64] drm/i915: Preserve current RPS frequency across init Chris Wilson
2016-07-07  8:41 ` [PATCH 03/64] drm/i915: Remove superfluous powersave work flushing Chris Wilson
2016-07-07  8:41 ` [PATCH 04/64] drm/i915: Defer enabling rc6 til after we submit the first batch/context Chris Wilson
2016-07-07  8:41 ` [PATCH 05/64] drm/i915: Remove temporary RPM wakeref assert disables Chris Wilson
2016-07-07  8:41 ` [PATCH 06/64] drm: Restore double clflush on the last partial cacheline Chris Wilson
2016-07-12 13:57   ` Daniel Vetter
2016-07-13  8:07     ` Mika Kuoppala
2016-07-07  8:41 ` [PATCH 07/64] drm/i915: Move GEM request routines to i915_gem_request.c Chris Wilson
2016-07-07  8:41 ` [PATCH 08/64] drm/i915: Retire oldest completed request before allocating next Chris Wilson
2016-07-07  9:41   ` Tvrtko Ursulin
2016-07-07  9:45     ` Chris Wilson
2016-07-07 10:03       ` Tvrtko Ursulin
2016-07-07 10:10         ` Chris Wilson
2016-07-08  9:21   ` Mika Kuoppala
2016-07-08  9:28     ` Chris Wilson
2016-07-07  8:41 ` [PATCH 09/64] drm/i915: Mark all current requests as complete before resetting them Chris Wilson
2016-07-07 16:09   ` Mika Kuoppala
2016-07-07  8:41 ` [PATCH 10/64] drm/i915: Derive GEM requests from dma-fence Chris Wilson
2016-07-07  8:41 ` [PATCH 11/64] drm/i915: Disable waitboosting for fence_wait() Chris Wilson
2016-07-07  8:41 ` [PATCH 12/64] drm/i915: Disable waitboosting for mmioflips/semaphores Chris Wilson
2016-07-07  8:41 ` [PATCH 13/64] drm/i915: Export our request as a dma-buf fence on the reservation object Chris Wilson
2016-07-07  8:41 ` [PATCH 14/64] drm/i915: Wait on external rendering for GEM objects Chris Wilson
2016-07-07  8:41 ` [PATCH 15/64] drm/i915: Mark imported dma-buf objects as being coherent Chris Wilson
2016-07-07  8:41 ` [PATCH 16/64] drm/i915: Rename request reference/unreference to get/put Chris Wilson
2016-07-07  8:41 ` [PATCH 17/64] drm/i915: Rename i915_gem_context_reference/unreference() Chris Wilson
2016-07-07  8:41 ` [PATCH 18/64] drm/i915: Wrap drm_gem_object_lookup in i915_gem_object_lookup Chris Wilson
2016-07-07  8:41 ` [PATCH 19/64] drm/i915: Wrap drm_gem_object_reference in i915_gem_object_get Chris Wilson
2016-07-07  8:41 ` [PATCH 20/64] drm/i915: Rename drm_gem_object_unreference in preparation for lockless free Chris Wilson
2016-07-07  8:41 ` [PATCH 21/64] drm/i915: Rename drm_gem_object_unreference_unlocked " Chris Wilson
2016-07-07  8:41 ` [PATCH 22/64] drm/i915: Treat ringbuffer writes as write to normal memory Chris Wilson
2016-07-07  8:41 ` [PATCH 23/64] drm/i915: Rename ring->virtual_start as ring->vaddr Chris Wilson
2016-07-07  8:41 ` [PATCH 24/64] drm/i915: Convert i915_semaphores_is_enabled over to early sanitize Chris Wilson
2016-07-07  8:41 ` [PATCH 25/64] drm/i915: Unify intel_logical_ring_emit and intel_ring_emit Chris Wilson
2016-07-07  8:41 ` [PATCH 26/64] drm/i915: Rename request->ringbuf to request->ring Chris Wilson
2016-07-07  8:41 ` [PATCH 27/64] drm/i915: Rename backpointer from intel_ringbuffer to intel_engine_cs Chris Wilson
2016-07-07  8:41 ` [PATCH 28/64] drm/i915: Rename intel_context[engine].ringbuf Chris Wilson
2016-07-07  8:41 ` [PATCH 29/64] drm/i915: Rename struct intel_ringbuffer to struct intel_ring Chris Wilson
2016-07-07  8:41 ` [PATCH 30/64] drm/i915: Rename residual ringbuf parameters Chris Wilson
2016-07-07  8:41 ` [PATCH 31/64] drm/i915: Rename intel_pin_and_map_ring() Chris Wilson
2016-07-07  8:41 ` [PATCH 32/64] drm/i915: Remove obsolete engine->gpu_caches_dirty Chris Wilson
2016-07-07  8:41 ` [PATCH 33/64] drm/i915: Simplify request_alloc by returning the allocated request Chris Wilson
2016-07-07  8:41 ` [PATCH 34/64] drm/i915: Unify legacy/execlists emission of MI_BATCHBUFFER_START Chris Wilson
2016-07-07  8:41 ` [PATCH 35/64] drm/i915: Convert engine->write_tail to operate on a request Chris Wilson
2016-07-07  8:41 ` [PATCH 36/64] drm/i915: Unify request submission Chris Wilson
2016-07-07  8:41 ` [PATCH 37/64] drm/i915: Stop passing caller's num_dwords to engine->semaphore.signal() Chris Wilson
2016-07-07  8:41 ` [PATCH 38/64] drm/i915: Reuse legacy breadcrumbs + tail emission Chris Wilson
2016-07-07  8:41 ` [PATCH 39/64] drm/i915/ringbuffer: Specialise SNB+ request emission for semaphores Chris Wilson
2016-07-07  8:41 ` [PATCH 40/64] drm/i915: Remove duplicate golden render state init from execlists Chris Wilson
2016-07-07  8:41 ` [PATCH 41/64] drm/i915: Unify legacy/execlists submit_execbuf callbacks Chris Wilson
2016-07-07  8:41 ` [PATCH 42/64] drm/i915: Simplify calling engine->sync_to Chris Wilson
2016-07-07  8:41 ` [PATCH 43/64] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers Chris Wilson
2016-07-07  8:41 ` [PATCH 44/64] drm/i915: Split early global GTT initialisation Chris Wilson
2016-07-07  8:41 ` [PATCH 45/64] drm/i915: Store owning file on the i915_address_space Chris Wilson
2016-07-07  8:41 ` [PATCH 46/64] drm/i915: Count how many VMA are bound for an object Chris Wilson
2016-07-12 14:30   ` Tvrtko Ursulin
2016-07-12 14:38     ` Chris Wilson
2016-07-12 15:12       ` Tvrtko Ursulin
2016-07-12 16:08         ` Chris Wilson
2016-07-07  8:41 ` [PATCH 47/64] drm/i915: Be more careful when unbinding vma Chris Wilson
2016-07-12 15:04   ` Tvrtko Ursulin [this message]
2016-07-12 16:42     ` Chris Wilson
2016-07-13  8:53       ` Tvrtko Ursulin
2016-07-07  8:41 ` [PATCH 48/64] drm/i915: Kill drop_pages() Chris Wilson
2016-07-12 15:14   ` Tvrtko Ursulin
2016-07-07  8:41 ` [PATCH 49/64] drm/i915: Introduce i915_gem_active for request tracking Chris Wilson
2016-07-12 16:05   ` Tvrtko Ursulin
2016-07-12 16:30     ` Chris Wilson
2016-07-13  8:54       ` Tvrtko Ursulin
2016-07-07  8:41 ` [PATCH 50/64] drm/i915: Prepare i915_gem_active for annotations Chris Wilson
2016-07-13 15:40   ` Tvrtko Ursulin
2016-07-13 15:58     ` Chris Wilson
2016-07-14  9:32       ` Tvrtko Ursulin
2016-07-14 10:04         ` Chris Wilson
2016-07-07  8:41 ` [PATCH 51/64] drm/i915: Mark up i915_gem_active for locking annotation Chris Wilson
2016-07-07  8:41 ` [PATCH 52/64] drm/i915: Refactor blocking waits Chris Wilson
2016-07-07  8:41 ` [PATCH 53/64] drm/i915: Rename request->list to link for consistency Chris Wilson
2016-07-07  8:42 ` [PATCH 54/64] drm/i915: Remove obsolete i915_gem_object_flush_active() Chris Wilson
2016-07-07  8:42 ` [PATCH 55/64] drm/i915: Refactor activity tracking for requests Chris Wilson
2016-07-07  8:42 ` [PATCH 56/64] drm/i915: Convert intel_overlay to request tracking Chris Wilson
2016-07-07  8:42 ` [PATCH 57/64] drm/i915: Move the special case wait-request handling to its one caller Chris Wilson
2016-07-07  8:42 ` [PATCH 58/64] drm/i915: Double check activity before relocations Chris Wilson
2016-07-07  8:42 ` [PATCH 59/64] drm/i915: Move request list retirement to i915_gem_request.c Chris Wilson
2016-07-07  8:42 ` [PATCH 60/64] drm/i915: i915_vma_move_to_active prep patch Chris Wilson
2016-07-07  8:42 ` [PATCH 61/64] drm/i915: Track active vma requests Chris Wilson
2016-07-07  8:42 ` [PATCH 62/64] drm/i915: Release vma when the handle is closed Chris Wilson
2016-07-07  8:42 ` [PATCH 63/64] drm/i915: Mark the context and address space as closed Chris Wilson
2016-07-07  8:42 ` [PATCH 64/64] Revert "drm/i915: Clean up associated VMAs on context destruction" Chris Wilson
2016-07-07  9:12 ` ✗ Ro.CI.BAT: warning for series starting with [01/64] drm/i915/breadcrumbs: Queue hangcheck before sleeping Patchwork
2016-07-07  9:28   ` Chris Wilson
2016-07-08  8:44     ` Chris Wilson

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=57850719.3040104@linux.intel.com \
    --to=tvrtko.ursulin@linux.intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox