/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/**************************************************************************
 *
 * Copyright (c) 2007-2010 VMware, Inc., Palo Alto, CA., USA
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/
/*
 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
 */

#include <drm/ttm/ttm_device.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_range_manager.h>
#include <drm/ttm/ttm_bo.h>
#include <drm/drm_mm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

/*
 * Currently we use a spinlock for the lock, but a mutex *may* be
 * more appropriate to reduce scheduling latency if the range manager
 * ends up with very fragmented allocation patterns.
 */

struct ttm_range_manager {
	struct ttm_resource_manager manager;
	struct drm_mm mm;
	spinlock_t lock;
};

static inline struct ttm_range_manager *
to_range_manager(struct ttm_resource_manager *man)
{
	return container_of(man, struct ttm_range_manager, manager);
}

static int ttm_range_man_alloc(struct ttm_resource_manager *man,
			       struct ttm_buffer_object *bo,
			       const struct ttm_place *place,
			       struct ttm_resource **res)
{
	struct ttm_range_manager *rman = to_range_manager(man);
	struct ttm_range_mgr_node *node;
	struct drm_mm *mm = &rman->mm;
	enum drm_mm_insert_mode mode;
	unsigned long lpfn;
	int ret;

	lpfn = place->lpfn;
	if (!lpfn)
		lpfn = man->size;

	node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL);
	if (!node)
		return -ENOMEM;

	mode = DRM_MM_INSERT_BEST;
	if (place->flags & TTM_PL_FLAG_TOPDOWN)
		mode = DRM_MM_INSERT_HIGH;

	ttm_resource_init(bo, place, &node->base);

	spin_lock(&rman->lock);
	ret = drm_mm_insert_node_in_range(mm, &node->mm_nodes[0],
					  PFN_UP(node->base.size),
					  bo->page_alignment, 0,
					  place->fpfn, lpfn, mode);
	spin_unlock(&rman->lock);

	if (unlikely(ret)) {
		ttm_resource_fini(man, &node->base);
		kfree(node);
		return ret;
	}

	node->base.start = node->mm_nodes[0].start;
	*res = &node->base;
	return 0;
}

static void ttm_range_man_free(struct ttm_resource_manager *man,
			       struct ttm_resource *res)
{
	struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res);
	struct ttm_range_manager *rman = to_range_manager(man);

	spin_lock(&rman->lock);
	drm_mm_remove_node(&node->mm_nodes[0]);
	spin_unlock(&rman->lock);

	ttm_resource_fini(man, res);
	kfree(node);
}

static bool ttm_range_man_intersects(struct ttm_resource_manager *man,
				     struct ttm_resource *res,
				     const struct ttm_place *place,
				     size_t size)
{
	struct drm_mm_node *node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
	u32 num_pages = PFN_UP(size);

	/* Don't evict BOs outside of the requested placement range */
	if (place->fpfn >= (node->start + num_pages) ||
	    (place->lpfn && place->lpfn <= node->start))
		return false;

	return true;
}

static bool ttm_range_man_compatible(struct ttm_resource_manager *man,
				     struct ttm_resource *res,
				     const struct ttm_place *place,
				     size_t size)
{
	struct drm_mm_node *node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
	u32 num_pages = PFN_UP(size);

	if (node->start < place->fpfn ||
	    (place->lpfn && (node->start + num_pages) > place->lpfn))
		return false;

	return true;
}

static void ttm_range_man_debug(struct ttm_resource_manager *man,
				struct drm_printer *printer)
{
	struct ttm_range_manager *rman = to_range_manager(man);

	spin_lock(&rman->lock);
	drm_mm_print(&rman->mm, printer);
	spin_unlock(&rman->lock);
}

static const struct ttm_resource_manager_func ttm_range_manager_func = {
	.alloc = ttm_range_man_alloc,
	.free = ttm_range_man_free,
	.intersects = ttm_range_man_intersects,
	.compatible = ttm_range_man_compatible,
	.debug = ttm_range_man_debug
};

/**
 * ttm_range_man_init_nocheck - Initialise a generic range manager for the
 * selected memory type.
 *
 * @bdev: ttm device
 * @type: memory manager type
 * @use_tt: if the memory manager uses tt
 * @p_size: size of area to be managed in pages.
 *
 * The range manager is installed for this device in the type slot.
 *
 * Return: %0 on success or a negative error code on failure
 */
int ttm_range_man_init_nocheck(struct ttm_device *bdev,
		       unsigned type, bool use_tt,
		       unsigned long p_size)
{
	struct ttm_resource_manager *man;
	struct ttm_range_manager *rman;

	rman = kzalloc(sizeof(*rman), GFP_KERNEL);
	if (!rman)
		return -ENOMEM;

	man = &rman->manager;
	man->use_tt = use_tt;

	man->func = &ttm_range_manager_func;

	ttm_resource_manager_init(man, bdev, p_size);

	drm_mm_init(&rman->mm, 0, p_size);
	spin_lock_init(&rman->lock);

	ttm_set_driver_manager(bdev, type, &rman->manager);
	ttm_resource_manager_set_used(man, true);
	return 0;
}
EXPORT_SYMBOL(ttm_range_man_init_nocheck);

/**
 * ttm_range_man_fini_nocheck - Remove the generic range manager from a slot
 * and tear it down.
 *
 * @bdev: ttm device
 * @type: memory manager type
 *
 * Return: %0 on success or a negative error code on failure
 */
int ttm_range_man_fini_nocheck(struct ttm_device *bdev,
		       unsigned type)
{
	struct ttm_resource_manager *man = ttm_manager_type(bdev, type);
	struct ttm_range_manager *rman = to_range_manager(man);
	struct drm_mm *mm = &rman->mm;
	int ret;

	if (!man)
		return 0;

	ttm_resource_manager_set_used(man, false);

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

	spin_lock(&rman->lock);
	drm_mm_takedown(mm);
	spin_unlock(&rman->lock);

	ttm_resource_manager_cleanup(man);
	ttm_set_driver_manager(bdev, type, NULL);
	kfree(rman);
	return 0;
}
EXPORT_SYMBOL(ttm_range_man_fini_nocheck);
