* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
-#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_device.h>
#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_range_manager.h>
+#include <drm/ttm/ttm_bo_api.h>
#include <drm/drm_mm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/module.h>
/*
* Currently we use a spinlock for the lock, but a mutex *may* be
struct ttm_resource *mem)
{
struct ttm_range_manager *rman = to_range_manager(man);
+ struct ttm_range_mgr_node *node;
struct drm_mm *mm = &rman->mm;
- struct drm_mm_node *node;
enum drm_mm_insert_mode mode;
unsigned long lpfn;
int ret;
if (!lpfn)
lpfn = man->size;
- node = kzalloc(sizeof(*node), GFP_KERNEL);
+ node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL);
if (!node)
return -ENOMEM;
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, mem->num_pages,
- bo->page_alignment, 0,
+ ret = drm_mm_insert_node_in_range(mm, &node->mm_nodes[0],
+ mem->num_pages, bo->page_alignment, 0,
place->fpfn, lpfn, mode);
spin_unlock(&rman->lock);
if (unlikely(ret)) {
kfree(node);
} else {
- mem->mm_node = node;
- mem->start = node->start;
+ mem->mm_node = &node->mm_nodes[0];
+ mem->start = node->mm_nodes[0].start;
}
return ret;
struct ttm_resource *mem)
{
struct ttm_range_manager *rman = to_range_manager(man);
+ struct ttm_range_mgr_node *node;
- if (mem->mm_node) {
- spin_lock(&rman->lock);
- drm_mm_remove_node(mem->mm_node);
- spin_unlock(&rman->lock);
+ if (!mem->mm_node)
+ return;
- kfree(mem->mm_node);
- mem->mm_node = NULL;
- }
+ node = to_ttm_range_mgr_node(mem);
+
+ spin_lock(&rman->lock);
+ drm_mm_remove_node(&node->mm_nodes[0]);
+ spin_unlock(&rman->lock);
+
+ kfree(node);
+ mem->mm_node = NULL;
}
static void ttm_range_man_debug(struct ttm_resource_manager *man,
.debug = ttm_range_man_debug
};
+/**
+ * ttm_range_man_init
+ *
+ * @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.
+ *
+ * Initialise a generic range manager for the selected memory type.
+ * The range manager is installed for this device in the type slot.
+ */
int ttm_range_man_init(struct ttm_device *bdev,
unsigned type, bool use_tt,
unsigned long p_size)
}
EXPORT_SYMBOL(ttm_range_man_init);
+/**
+ * ttm_range_man_fini
+ *
+ * @bdev: ttm device
+ * @type: memory manager type
+ *
+ * Remove the generic range manager from a slot and tear it down.
+ */
int ttm_range_man_fini(struct ttm_device *bdev,
unsigned type)
{