// SPDX-License-Identifier: MIT
/*
 * Copyright © 2022 Intel Corporation
 */

#include "xe_bo_evict.h"

#include "xe_bo.h"
#include "xe_device.h"
#include "xe_ggtt.h"
#include "xe_tile.h"

/**
 * xe_bo_evict_all - evict all BOs from VRAM
 *
 * @xe: xe device
 *
 * Evict non-pinned user BOs first (via GPU), evict pinned external BOs next
 * (via GPU), wait for evictions, and finally evict pinned kernel BOs via CPU.
 * All eviction magic done via TTM calls.
 *
 * Evict == move VRAM BOs to temporary (typically system) memory.
 *
 * This function should be called before the device goes into a suspend state
 * where the VRAM loses power.
 */
int xe_bo_evict_all(struct xe_device *xe)
{
	struct ttm_device *bdev = &xe->ttm;
	struct xe_bo *bo;
	struct xe_tile *tile;
	struct list_head still_in_list;
	u32 mem_type;
	u8 id;
	int ret;

	if (!IS_DGFX(xe))
		return 0;

	/* User memory */
	for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) {
		struct ttm_resource_manager *man =
			ttm_manager_type(bdev, mem_type);

		if (man) {
			ret = ttm_resource_manager_evict_all(bdev, man);
			if (ret)
				return ret;
		}
	}

	/* Pinned user memory in VRAM */
	INIT_LIST_HEAD(&still_in_list);
	spin_lock(&xe->pinned.lock);
	for (;;) {
		bo = list_first_entry_or_null(&xe->pinned.external_vram,
					      typeof(*bo), pinned_link);
		if (!bo)
			break;
		xe_bo_get(bo);
		list_move_tail(&bo->pinned_link, &still_in_list);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, false);
		ret = xe_bo_evict_pinned(bo);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		if (ret) {
			spin_lock(&xe->pinned.lock);
			list_splice_tail(&still_in_list,
					 &xe->pinned.external_vram);
			spin_unlock(&xe->pinned.lock);
			return ret;
		}

		spin_lock(&xe->pinned.lock);
	}
	list_splice_tail(&still_in_list, &xe->pinned.external_vram);
	spin_unlock(&xe->pinned.lock);

	/*
	 * Wait for all user BO to be evicted as those evictions depend on the
	 * memory moved below.
	 */
	for_each_tile(tile, xe, id)
		xe_tile_migrate_wait(tile);

	spin_lock(&xe->pinned.lock);
	for (;;) {
		bo = list_first_entry_or_null(&xe->pinned.kernel_bo_present,
					      typeof(*bo), pinned_link);
		if (!bo)
			break;
		xe_bo_get(bo);
		list_move_tail(&bo->pinned_link, &xe->pinned.evicted);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, false);
		ret = xe_bo_evict_pinned(bo);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		if (ret)
			return ret;

		spin_lock(&xe->pinned.lock);
	}
	spin_unlock(&xe->pinned.lock);

	return 0;
}

/**
 * xe_bo_restore_kernel - restore kernel BOs to VRAM
 *
 * @xe: xe device
 *
 * Move kernel BOs from temporary (typically system) memory to VRAM via CPU. All
 * moves done via TTM calls.
 *
 * This function should be called early, before trying to init the GT, on device
 * resume.
 */
int xe_bo_restore_kernel(struct xe_device *xe)
{
	struct xe_bo *bo;
	int ret;

	if (!IS_DGFX(xe))
		return 0;

	spin_lock(&xe->pinned.lock);
	for (;;) {
		bo = list_first_entry_or_null(&xe->pinned.evicted,
					      typeof(*bo), pinned_link);
		if (!bo)
			break;
		xe_bo_get(bo);
		list_move_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, false);
		ret = xe_bo_restore_pinned(bo);
		xe_bo_unlock(bo);
		if (ret) {
			xe_bo_put(bo);
			return ret;
		}

		if (bo->flags & XE_BO_FLAG_GGTT) {
			struct xe_tile *tile = bo->tile;

			mutex_lock(&tile->mem.ggtt->lock);
			xe_ggtt_map_bo(tile->mem.ggtt, bo);
			mutex_unlock(&tile->mem.ggtt->lock);
		}

		/*
		 * We expect validate to trigger a move VRAM and our move code
		 * should setup the iosys map.
		 */
		xe_assert(xe, !iosys_map_is_null(&bo->vmap));
		xe_assert(xe, xe_bo_is_vram(bo));

		xe_bo_put(bo);

		spin_lock(&xe->pinned.lock);
	}
	spin_unlock(&xe->pinned.lock);

	return 0;
}

/**
 * xe_bo_restore_user - restore pinned user BOs to VRAM
 *
 * @xe: xe device
 *
 * Move pinned user BOs from temporary (typically system) memory to VRAM via
 * CPU. All moves done via TTM calls.
 *
 * This function should be called late, after GT init, on device resume.
 */
int xe_bo_restore_user(struct xe_device *xe)
{
	struct xe_bo *bo;
	struct xe_tile *tile;
	struct list_head still_in_list;
	u8 id;
	int ret;

	if (!IS_DGFX(xe))
		return 0;

	/* Pinned user memory in VRAM should be validated on resume */
	INIT_LIST_HEAD(&still_in_list);
	spin_lock(&xe->pinned.lock);
	for (;;) {
		bo = list_first_entry_or_null(&xe->pinned.external_vram,
					      typeof(*bo), pinned_link);
		if (!bo)
			break;
		list_move_tail(&bo->pinned_link, &still_in_list);
		xe_bo_get(bo);
		spin_unlock(&xe->pinned.lock);

		xe_bo_lock(bo, false);
		ret = xe_bo_restore_pinned(bo);
		xe_bo_unlock(bo);
		xe_bo_put(bo);
		if (ret) {
			spin_lock(&xe->pinned.lock);
			list_splice_tail(&still_in_list,
					 &xe->pinned.external_vram);
			spin_unlock(&xe->pinned.lock);
			return ret;
		}

		spin_lock(&xe->pinned.lock);
	}
	list_splice_tail(&still_in_list, &xe->pinned.external_vram);
	spin_unlock(&xe->pinned.lock);

	/* Wait for restore to complete */
	for_each_tile(tile, xe, id)
		xe_tile_migrate_wait(tile);

	return 0;
}
