On Mon, Jan 24, 2022 at 01:25:08PM +0100, Christian König wrote:
> Instead of duplicating that at different places add an iterator over all
> the resources in a resource manager.
> 
> Signed-off-by: Christian König <christian.koe...@amd.com>
> ---
>  drivers/gpu/drm/ttm/ttm_bo.c       | 41 +++++++++++----------------
>  drivers/gpu/drm/ttm/ttm_device.c   | 26 ++++++++---------
>  drivers/gpu/drm/ttm/ttm_resource.c | 45 ++++++++++++++++++++++++++++++
>  include/drm/ttm/ttm_resource.h     | 23 +++++++++++++++
>  4 files changed, 95 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index cb0fa932d495..599be3dda8a9 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -579,38 +579,29 @@ int ttm_mem_evict_first(struct ttm_device *bdev,
>                       struct ww_acquire_ctx *ticket)
>  {
>       struct ttm_buffer_object *bo = NULL, *busy_bo = NULL;
> +     struct ttm_resource_cursor cursor;
>       struct ttm_resource *res;
>       bool locked = false;
> -     unsigned i;
>       int ret;
>  
>       spin_lock(&bdev->lru_lock);
> -     for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
> -             list_for_each_entry(res, &man->lru[i], lru) {
> -                     bool busy;
> -
> -                     bo = res->bo;
> -                     if (!ttm_bo_evict_swapout_allowable(bo, ctx, place,
> -                                                         &locked, &busy)) {
> -                             if (busy && !busy_bo && ticket !=
> -                                 dma_resv_locking_ctx(bo->base.resv))
> -                                     busy_bo = bo;
> -                             continue;
> -                     }
> -
> -                     if (!ttm_bo_get_unless_zero(bo)) {
> -                             if (locked)
> -                                     dma_resv_unlock(bo->base.resv);
> -                             continue;
> -                     }
> -                     break;
> +     ttm_resource_manager_for_each_res(man, &cursor, res) {
> +             bool busy;
> +
> +             if (!ttm_bo_evict_swapout_allowable(res->bo, ctx, place,
> +                                                 &locked, &busy)) {
> +                     if (busy && !busy_bo && ticket !=
> +                         dma_resv_locking_ctx(bo->base.resv))
> +                             busy_bo = res->bo;
> +                     continue;
>               }
>  
> -             /* If the inner loop terminated early, we have our candidate */
> -             if (&res->lru != &man->lru[i])
> -                     break;
> -
> -             bo = NULL;
> +             if (!ttm_bo_get_unless_zero(res->bo)) {
> +                     if (locked)
> +                             dma_resv_unlock(res->bo->base.resv);
> +                     continue;
> +             }
> +             bo = res->bo;
>       }
>  
>       if (!bo) {
> diff --git a/drivers/gpu/drm/ttm/ttm_device.c 
> b/drivers/gpu/drm/ttm/ttm_device.c
> index ba35887147ba..a0562ab386f5 100644
> --- a/drivers/gpu/drm/ttm/ttm_device.c
> +++ b/drivers/gpu/drm/ttm/ttm_device.c
> @@ -142,10 +142,10 @@ EXPORT_SYMBOL(ttm_global_swapout);
>  int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx 
> *ctx,
>                      gfp_t gfp_flags)
>  {
> +     struct ttm_resource_cursor cursor;
>       struct ttm_resource_manager *man;
> -     struct ttm_buffer_object *bo;
>       struct ttm_resource *res;
> -     unsigned i, j;
> +     unsigned i;
>       int ret;
>  
>       spin_lock(&bdev->lru_lock);
> @@ -154,20 +154,16 @@ int ttm_device_swapout(struct ttm_device *bdev, struct 
> ttm_operation_ctx *ctx,
>               if (!man || !man->use_tt)
>                       continue;
>  
> -             for (j = 0; j < TTM_MAX_BO_PRIORITY; ++j) {
> -                     list_for_each_entry(res, &man->lru[j], lru) {
> -                             uint32_t num_pages;
> -
> -                             bo = res->bo;
> -                             num_pages = PFN_UP(bo->base.size);
> +             ttm_resource_manager_for_each_res(man, &cursor, res) {
> +                     struct ttm_buffer_object *bo = res->bo;
> +                     uint32_t num_pages = PFN_UP(bo->base.size);
>  
> -                             ret = ttm_bo_swapout(bo, ctx, gfp_flags);
> -                             /* ttm_bo_swapout has dropped the lru_lock */
> -                             if (!ret)
> -                                     return num_pages;
> -                             if (ret != -EBUSY)
> -                                     return ret;
> -                     }
> +                     ret = ttm_bo_swapout(bo, ctx, gfp_flags);
> +                     /* ttm_bo_swapout has dropped the lru_lock */
> +                     if (!ret)
> +                             return num_pages;
> +                     if (ret != -EBUSY)
> +                             return ret;
>               }
>       }
>       spin_unlock(&bdev->lru_lock);
> diff --git a/drivers/gpu/drm/ttm/ttm_resource.c 
> b/drivers/gpu/drm/ttm/ttm_resource.c
> index 450e665c357b..9e68d36a1546 100644
> --- a/drivers/gpu/drm/ttm/ttm_resource.c
> +++ b/drivers/gpu/drm/ttm/ttm_resource.c
> @@ -354,6 +354,51 @@ void ttm_resource_manager_debug(struct 
> ttm_resource_manager *man,
>  }
>  EXPORT_SYMBOL(ttm_resource_manager_debug);
>  
> +/**
> + * ttm_resource_manager_first
> + *
> + * @man: resource manager to iterate over
> + * @cursor: cursor to record the position
> + *
> + * Returns the first resource from the resource manager.
> + */
> +struct ttm_resource *
> +ttm_resource_manager_first(struct ttm_resource_manager *man,
> +                        struct ttm_resource_cursor *cursor)
> +{
> +     struct ttm_resource *res;

assert_lockdep_held for the lru spinlock here and in the _next() one pls,
just to be on the safe side.

> +
> +     for (cursor->priority = 0; cursor->priority < TTM_MAX_BO_PRIORITY;
> +          ++cursor->priority)
> +             list_for_each_entry(res, &man->lru[cursor->priority], lru)
> +                     return res;
> +
> +     return NULL;
> +}
> +
> +/**
> + * ttm_resource_manager_next
> + *
> + * @man: resource manager to iterate over
> + * @cursor: cursor to record the position
> + *
> + * Returns the next resource from the resource manager.
> + */
> +struct ttm_resource *
> +ttm_resource_manager_next(struct ttm_resource_manager *man,
> +                       struct ttm_resource_cursor *cursor,
> +                       struct ttm_resource *res)
> +{
> +     list_for_each_entry_continue(res, &man->lru[cursor->priority], lru)
> +             return res;
> +
> +     for (; cursor->priority < TTM_MAX_BO_PRIORITY; ++cursor->priority)
> +             list_for_each_entry(res, &man->lru[cursor->priority], lru)
> +                     return res;
> +
> +     return NULL;
> +}
> +
>  static void ttm_kmap_iter_iomap_map_local(struct ttm_kmap_iter *iter,
>                                         struct dma_buf_map *dmap,
>                                         pgoff_t i)
> diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h
> index a54d52517a30..13da5e337350 100644
> --- a/include/drm/ttm/ttm_resource.h
> +++ b/include/drm/ttm/ttm_resource.h
> @@ -183,6 +183,17 @@ struct ttm_resource {
>       struct list_head lru;
>  };
>  
> +/**
> + * struct ttm_resource_cursor
> + *
> + * @priority: the current priority
> + *
> + * Cursor to iterate over the resources in a manager.
> + */
> +struct ttm_resource_cursor {
> +     unsigned int priority;
> +};
> +
>  /**
>   * struct ttm_lru_bulk_move_pos
>   *
> @@ -339,6 +350,18 @@ int ttm_resource_manager_evict_all(struct ttm_device 
> *bdev,
>  void ttm_resource_manager_debug(struct ttm_resource_manager *man,
>                               struct drm_printer *p);
>  
> +struct ttm_resource *
> +ttm_resource_manager_first(struct ttm_resource_manager *man,
> +                        struct ttm_resource_cursor *cursor);
> +struct ttm_resource *
> +ttm_resource_manager_next(struct ttm_resource_manager *man,
> +                       struct ttm_resource_cursor *cursor,
> +                       struct ttm_resource *res);
> +

Kerneldoc for this one would be nice too.

> +#define ttm_resource_manager_for_each_res(man, cursor, res)          \
> +     for (res = ttm_resource_manager_first(man, cursor); res;        \
> +          res = ttm_resource_manager_next(man, cursor, res))
> +
>  struct ttm_kmap_iter *
>  ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io,
>                        struct io_mapping *iomap,

I really like this, looks neat and tidy. With the two nits addressed.

Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>


> -- 
> 2.25.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

Reply via email to