Am 2022-02-14 um 04:34 schrieb Christian König:
Instead of duplicating that at different places add an iterator over all the resources in a resource manager.
v2: add lockdep annotation and kerneldoc
Signed-off-by: Christian König christian.koenig@amd.com Tested-by: Bas Nieuwenhuizen bas@basnieuwenhuizen.nl Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch
drivers/gpu/drm/ttm/ttm_bo.c | 41 ++++++++++--------------- drivers/gpu/drm/ttm/ttm_device.c | 26 +++++++--------- drivers/gpu/drm/ttm/ttm_resource.c | 49 ++++++++++++++++++++++++++++++ include/drm/ttm/ttm_resource.h | 23 ++++++++++++++ 4 files changed, 99 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)
} } spin_unlock(&bdev->lru_lock);return ret;
diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 411b3f001eeb..1f9b8205b3a5 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -385,6 +385,55 @@ 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;
- lockdep_assert_held(&man->bdev->lru_lock);
- 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
Documentation of the "res" parameter is missing.
- 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)
+{
- lockdep_assert_held(&man->bdev->lru_lock);
- list_for_each_entry_continue(res, &man->lru[cursor->priority], lru)
return res;
- for (; cursor->priority < TTM_MAX_BO_PRIORITY; ++cursor->priority)
If you get here, the previous loop has finished iterating over the current cursor->priority level. Therefore I think you need to increment cursor->priority before the first loop iteration here. Otherwise you'll just keep iterating over the same priority level over and over.
Regards, Felix
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 181e82e3d806..ef0ec700e896 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -184,6 +184,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
@@ -328,6 +339,18 @@ uint64_t ttm_resource_manager_usage(struct ttm_resource_manager *man); 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);
+#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,