[PATCH] drm/amdgpu: Attach exclusive fence to prime exported bo's. (v5)

Mike Lothian mike at fireburn.co.uk
Sun Nov 13 15:30:31 UTC 2016


Hi

I've tested this version now - works great

Thanks

Mike

On Wed, 9 Nov 2016 at 01:26 Mario Kleiner <mario.kleiner.de at gmail.com>
wrote:

> External clients which import our bo's wait only
> for exclusive dmabuf-fences, not on shared ones,
> ditto for bo's which we import from external
> providers and write to.
>
> Therefore attach exclusive fences on prime shared buffers
> if our exported buffer gets imported by an external
> client, or if we import a buffer from an external
> exporter.
>
> See discussion in thread:
> https://lists.freedesktop.org/archives/dri-devel/2016-October/122370.html
>
> Prime export tested on Intel iGPU + AMD Tonga dGPU as
> DRI3/Present Prime render offload, and with the Tonga
> standalone as primary gpu.
>
> v2: Add a wait for all shared fences before prime export,
>     as suggested by Christian Koenig.
>
> v3: - Mark buffer prime_exported in amdgpu_gem_prime_pin,
>     so we only use the exclusive fence when exporting a
>     bo to external clients like a separate iGPU, but not
>     when exporting/importing from/to ourselves as part of
>     regular DRI3 fd passing.
>
>     - Propagate failure of reservation_object_wait_rcu back
>     to caller.
>
> v4: - Switch to a prime_shared_count counter instead of a
>       flag, which gets in/decremented on prime_pin/unpin, so
>       we can switch back to shared fences if all clients
>       detach from our exported bo.
>
>     - Also switch to exclusive fence for prime imported bo's.
>
> v5: - Drop lret, instead use int ret -> long ret, as proposed
>       by Christian.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95472
> Tested-by: Mike Lothian <mike at fireburn.co.uk> (v1)
> Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com>
> Reviewed-by: Christian König <christian.koenig at amd.com>.
> Cc: Christian König <christian.koenig at amd.com>
> Cc: Michel Dänzer <michel.daenzer at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h         |  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c |  2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c   | 20 +++++++++++++++++++-
>  3 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 039b57e..496f72b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -459,6 +459,7 @@ struct amdgpu_bo {
>         u64                             metadata_flags;
>         void                            *metadata;
>         u32                             metadata_size;
> +       unsigned                        prime_shared_count;
>         /* list of all virtual address to which this bo
>          * is associated to
>          */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> index 651115d..c02db01f6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> @@ -132,7 +132,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device
> *adev,
>                 entry->priority = min(info[i].bo_priority,
>                                       AMDGPU_BO_LIST_MAX_PRIORITY);
>                 entry->tv.bo = &entry->robj->tbo;
> -               entry->tv.shared = true;
> +               entry->tv.shared = !entry->robj->prime_shared_count;
>
>                 if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)
>                         gds_obj = entry->robj;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
> index 7700dc2..3826d5a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
> @@ -74,20 +74,36 @@ amdgpu_gem_prime_import_sg_table(struct drm_device
> *dev,
>         if (ret)
>                 return ERR_PTR(ret);
>
> +       bo->prime_shared_count = 1;
>         return &bo->gem_base;
>  }
>
>  int amdgpu_gem_prime_pin(struct drm_gem_object *obj)
>  {
>         struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
> -       int ret = 0;
> +       long ret = 0;
>
>         ret = amdgpu_bo_reserve(bo, false);
>         if (unlikely(ret != 0))
>                 return ret;
>
> +       /*
> +        * Wait for all shared fences to complete before we switch to
> future
> +        * use of exclusive fence on this prime shared bo.
> +        */
> +       ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, true,
> false,
> +                                                 MAX_SCHEDULE_TIMEOUT);
> +       if (unlikely(ret < 0)) {
> +               DRM_DEBUG_PRIME("Fence wait failed: %li\n", ret);
> +               amdgpu_bo_unreserve(bo);
> +               return ret;
> +       }
> +
>         /* pin buffer into GTT */
>         ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL);
> +       if (likely(ret == 0))
> +               bo->prime_shared_count++;
> +
>         amdgpu_bo_unreserve(bo);
>         return ret;
>  }
> @@ -102,6 +118,8 @@ void amdgpu_gem_prime_unpin(struct drm_gem_object *obj)
>                 return;
>
>         amdgpu_bo_unpin(bo);
> +       if (bo->prime_shared_count)
> +               bo->prime_shared_count--;
>         amdgpu_bo_unreserve(bo);
>  }
>
> --
> 2.7.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20161113/103f3171/attachment-0001.html>


More information about the dri-devel mailing list