[PATCH 4/4] drm/ttm: individualize BO reservation obj when they are freed

Alex Deucher alexdeucher at gmail.com
Wed Jul 26 16:58:36 UTC 2017


On Wed, Jul 26, 2017 at 9:12 AM, Christian König
<deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at amd.com>
>
> Use the BOs reservation object when it is put on the ddelete list. This way we
> avoid delaying freeing up the BO because of new fences on the reservation object.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>

You might want to mention more explicitly these uses cases that this
patch set fixes in the patch description.

Patch 2-4 are:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/ttm/ttm_bo.c | 54 ++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 47 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index 46dd2d6..8f04c74 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -394,14 +394,33 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
>         ww_mutex_unlock (&bo->resv->lock);
>  }
>
> +static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
> +{
> +       int r;
> +
> +       if (bo->resv == &bo->ttm_resv)
> +               return 0;
> +
> +       reservation_object_init(&bo->ttm_resv);
> +       BUG_ON(reservation_object_lock(&bo->ttm_resv, NULL));
> +
> +       r = reservation_object_copy_fences(&bo->ttm_resv, bo->resv);
> +       if (r) {
> +               reservation_object_unlock(&bo->ttm_resv);
> +               reservation_object_fini(&bo->ttm_resv);
> +       }
> +
> +       return r;
> +}
> +
>  static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
>  {
>         struct reservation_object_list *fobj;
>         struct dma_fence *fence;
>         int i;
>
> -       fobj = reservation_object_get_list(bo->resv);
> -       fence = reservation_object_get_excl(bo->resv);
> +       fobj = reservation_object_get_list(&bo->ttm_resv);
> +       fence = reservation_object_get_excl(&bo->ttm_resv);
>         if (fence && !fence->ops->signaled)
>                 dma_fence_enable_sw_signaling(fence);
>
> @@ -430,8 +449,19 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
>                         ttm_bo_cleanup_memtype_use(bo);
>
>                         return;
> -               } else
> -                       ttm_bo_flush_all_fences(bo);
> +               }
> +
> +               ret = ttm_bo_individualize_resv(bo);
> +               if (ret) {
> +                       /* Last resort, if we fail to allocate memory for the
> +                        * fences block for the BO to become idle and free it.
> +                        */
> +                       spin_unlock(&glob->lru_lock);
> +                       ttm_bo_wait(bo, true, true);
> +                       ttm_bo_cleanup_memtype_use(bo);
> +                       return;
> +               }
> +               ttm_bo_flush_all_fences(bo);
>
>                 /*
>                  * Make NO_EVICT bos immediately available to
> @@ -443,6 +473,8 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
>                         ttm_bo_add_to_lru(bo);
>                 }
>
> +               if (bo->resv != &bo->ttm_resv)
> +                       reservation_object_unlock(&bo->ttm_resv);
>                 __ttm_bo_unreserve(bo);
>         }
>
> @@ -471,17 +503,25 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
>                                           bool no_wait_gpu)
>  {
>         struct ttm_bo_global *glob = bo->glob;
> +       struct reservation_object *resv;
>         int ret;
>
> -       ret = ttm_bo_wait(bo, false, true);
> +       if (unlikely(list_empty(&bo->ddestroy)))
> +               resv = bo->resv;
> +       else
> +               resv = &bo->ttm_resv;
> +
> +       if (reservation_object_test_signaled_rcu(resv, true))
> +               ret = 0;
> +       else
> +               ret = -EBUSY;
>
>         if (ret && !no_wait_gpu) {
>                 long lret;
>                 ww_mutex_unlock(&bo->resv->lock);
>                 spin_unlock(&glob->lru_lock);
>
> -               lret = reservation_object_wait_timeout_rcu(bo->resv,
> -                                                          true,
> +               lret = reservation_object_wait_timeout_rcu(resv, true,
>                                                            interruptible,
>                                                            30 * HZ);
>
> --
> 2.7.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list