Commit 5d05b988 authored by Christian König's avatar Christian König
Browse files

drm/ttm: add resource iterator v4



Instead of duplicating that at different places add an iterator over all
the resources in a resource manager.

v2: add lockdep annotation and kerneldoc
v3: fix various bugs pointed out by Felix
v4: simplify the code a bit more

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Tested-by: default avatarBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v2)
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220321132601.2161-2-christian.koenig@amd.com
parent 6a9b0289
Loading
Loading
Loading
Loading
+14 −23
Original line number Diff line number Diff line
@@ -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) {
	ttm_resource_manager_for_each_res(man, &cursor, res) {
		bool busy;

			bo = res->bo;
			if (!ttm_bo_evict_swapout_allowable(bo, ctx, place,
		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 = bo;
			    dma_resv_locking_ctx(res->bo->base.resv))
				busy_bo = res->bo;
			continue;
		}

			if (!ttm_bo_get_unless_zero(bo)) {
				if (locked)
					dma_resv_unlock(bo->base.resv);
				continue;
			}
		if (ttm_bo_get_unless_zero(res->bo)) {
			bo = res->bo;
			break;
		}

		/* If the inner loop terminated early, we have our candidate */
		if (&res->lru != &man->lru[i])
			break;

		bo = NULL;
		if (locked)
			dma_resv_unlock(res->bo->base.resv);
	}

	if (!bo) {
+11 −15
Original line number Diff line number Diff line
@@ -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,12 +154,9 @@ 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 */
@@ -169,7 +166,6 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
				return ret;
		}
	}
	}
	spin_unlock(&bdev->lru_lock);
	return 0;
}
+51 −0
Original line number Diff line number Diff line
@@ -385,6 +385,57 @@ 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
 * @res: the current resource pointer
 *
 * 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; 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)
+23 −0
Original line number Diff line number Diff line
@@ -188,6 +188,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
 *
@@ -333,6 +344,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,