All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 8/8] drm/i915: Wait on external rendering for GEM objects
Date: Tue, 19 Jul 2016 17:12:22 +0300	[thread overview]
Message-ID: <1468937542.13019.5.camel@linux.intel.com> (raw)
In-Reply-To: <1468925519-32534-8-git-send-email-chris@chris-wilson.co.uk>

On ti, 2016-07-19 at 11:51 +0100, Chris Wilson wrote:
> When transitioning to the GTT or CPU domain we wait on all rendering
> from i915 to complete (with the optimisation of allowing concurrent read
> access by both the GPU and client). We don't yet ensure all rendering
> from third parties (tracked by implicit fences on the dma-buf) is
> complete. Since implicitly tracked rendering by third parties will
> ignore our cache-domain tracking, we have to always wait upon rendering
> from third-parties when transitioning to direct access to the backing
> store. We still rely on clients notifying us of cache domain changes
> (i.e. they need to move to the GTT read or write domain after doing a CPU
> access before letting the third party render again).
> 
> v2:
> This introduces a potential WARN_ON into i915_gem_object_free() as the
> current i915_vma_unbind() calls i915_gem_object_wait_rendering(). To
> hit this path we first need to render with the GPU, have a dma-buf
> attached with an unsignaled fence and then interrupt the wait. It does
> get fixed later in the series (when i915_vma_unbind() only waits on the
> active VMA and not all, including third-party, rendering.
> 
> To offset that risk, use the __i915_vma_unbind_no_wait hack.
> 
> Testcase: igt/prime_vgem/basic-fence-read
> Testcase: igt/prime_vgem/basic-fence-mmap
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/i915_gem.c | 44 ++++++++++++++++++++++++++---------------
>  1 file changed, 28 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 079e09cee16a..37868cc594cb 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -29,10 +29,12 @@
>  #include 
>  #include 
>  #include "i915_drv.h"
> +#include "i915_gem_dmabuf.h"
>  #include "i915_vgpu.h"
>  #include "i915_trace.h"
>  #include "intel_drv.h"
>  #include "intel_mocs.h"
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -511,6 +513,10 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
>  	if (WARN_ON(!i915_gem_object_has_struct_page(obj)))
>  		return -EINVAL;
>  
> +	ret = i915_gem_object_wait_rendering(obj, true);
> +	if (ret)
> +		return ret;
> +
>  	if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) {
>  		/* If we're not in the cpu read domain, set ourself into the gtt
>  		 * read domain and manually flush cachelines (if required). This
> @@ -518,9 +524,6 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
>  		 * anyway again before the next pread happens. */
>  		*needs_clflush = !cpu_cache_is_coherent(obj->base.dev,
>  							obj->cache_level);
> -		ret = i915_gem_object_wait_rendering(obj, true);
> -		if (ret)
> -			return ret;
>  	}
>  
>  	ret = i915_gem_object_get_pages(obj);
> @@ -1132,15 +1135,16 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
>  
>  	obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
>  
> +	ret = i915_gem_object_wait_rendering(obj, false);
> +	if (ret)
> +		return ret;
> +
>  	if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
>  		/* If we're not in the cpu write domain, set ourself into the gtt
>  		 * write domain and manually flush cachelines (if required). This
>  		 * optimizes for the case when the gpu will use the data
>  		 * right away and we therefore have to clflush anyway. */
>  		needs_clflush_after = cpu_write_needs_clflush(obj);
> -		ret = i915_gem_object_wait_rendering(obj, false);
> -		if (ret)
> -			return ret;
>  	}
>  	/* Same trick applies to invalidate partially written cachelines read
>  	 * before writing. */
> @@ -1335,11 +1339,9 @@ int
>  i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
>  			       bool readonly)
>  {
> +	struct reservation_object *resv;
>  	int ret, i;
>  
> -	if (!obj->active)
> -		return 0;
> -
>  	if (readonly) {
>  		if (obj->last_write_req != NULL) {
>  			ret = i915_wait_request(obj->last_write_req);
> @@ -1366,6 +1368,16 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
>  		GEM_BUG_ON(obj->active);
>  	}
>  
> +	resv = i915_gem_object_get_dmabuf_resv(obj);
> +	if (resv) {
> +		long err;

We already have ret in the function scope.

> +
> +		err = reservation_object_wait_timeout_rcu(resv, !readonly, true,
> +							  MAX_SCHEDULE_TIMEOUT);
> +		if (err < 0)
> +			return err;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -3402,13 +3414,13 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
>  	struct i915_vma *vma;
>  	int ret;
>  
> -	if (obj->base.write_domain == I915_GEM_DOMAIN_GTT)
> -		return 0;
> -
>  	ret = i915_gem_object_wait_rendering(obj, !write);
>  	if (ret)
>  		return ret;
>  
> +	if (obj->base.write_domain == I915_GEM_DOMAIN_GTT)
> +		return 0;
> +

Not sure I follow this change, wait rendering would only be issued if
DOMAIN_CPU was in place, this function was about moving to gtt_domain
so should really be NOP if in GTT domain already, no? Maybe calling
site should do an explicit wait_rendering if needed.

>  	/* Flush and acquire obj->pages so that we are coherent through
>  	 * direct access in memory with previous cached writes through
>  	 * shmemfs and that our cache domain tracking remains valid.
> @@ -3752,13 +3764,13 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
>  	uint32_t old_write_domain, old_read_domains;
>  	int ret;
>  
> -	if (obj->base.write_domain == I915_GEM_DOMAIN_CPU)
> -		return 0;
> -
>  	ret = i915_gem_object_wait_rendering(obj, !write);
>  	if (ret)
>  		return ret;
>  
> +	if (obj->base.write_domain == I915_GEM_DOMAIN_CPU)
> +		return 0;
> +

Ditto.

>  	i915_gem_object_flush_gtt_write_domain(obj);
>  
>  	old_write_domain = obj->base.write_domain;
> @@ -4238,7 +4250,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
>  		int ret;
>  
>  		vma->pin_count = 0;
> -		ret = i915_vma_unbind(vma);

Maybe add a comment/TODO/FIXME: about the potential WARN.

Regards, Joonas

> +		ret = __i915_vma_unbind_no_wait(vma);
>  		if (WARN_ON(ret == -ERESTARTSYS)) {
>  			bool was_interruptible;
>  
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2016-07-19 14:13 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-19 10:51 [PATCH 1/8] drm/i915: Move GEM request routines to i915_gem_request.c Chris Wilson
2016-07-19 10:51 ` [PATCH 2/8] drm/i915: Retire oldest completed request before allocating next Chris Wilson
2016-07-19 10:51 ` [PATCH 3/8] drm/i915: Mark all current requests as complete before resetting them Chris Wilson
2016-07-19 10:51 ` [PATCH 4/8] drm/i915: Derive GEM requests from dma-fence Chris Wilson
2016-07-19 10:51 ` [PATCH 5/8] drm/i915: Disable waitboosting for fence_wait() Chris Wilson
2016-07-19 10:51 ` [PATCH 6/8] drm/i915: Disable waitboosting for mmioflips/semaphores Chris Wilson
2016-07-19 10:51 ` [PATCH 7/8] drm/i915: Mark imported dma-buf objects as being coherent Chris Wilson
2016-07-19 13:27   ` Joonas Lahtinen
2016-07-19 10:51 ` [PATCH 8/8] drm/i915: Wait on external rendering for GEM objects Chris Wilson
2016-07-19 14:12   ` Joonas Lahtinen [this message]
2016-07-19 14:27     ` Chris Wilson
2016-07-20  7:32       ` Joonas Lahtinen
2016-07-19 11:29 ` ✗ Ro.CI.BAT: failure for series starting with [1/8] drm/i915: Move GEM request routines to i915_gem_request.c Patchwork

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=1468937542.13019.5.camel@linux.intel.com \
    --to=joonas.lahtinen@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 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.