drm/ttm: flip over the range manager to self allocated nodes
Start with the range manager to make the resource object the base class for the allocated nodes. While at it cleanup a lot of the code around that. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210602100914.46246-2-christian.koenig@amd.com
This commit is contained in:
Родитель
bfa3357ef9
Коммит
3eb7d96e94
|
@ -45,6 +45,7 @@
|
||||||
#include <drm/ttm/ttm_bo_api.h>
|
#include <drm/ttm/ttm_bo_api.h>
|
||||||
#include <drm/ttm/ttm_bo_driver.h>
|
#include <drm/ttm/ttm_bo_driver.h>
|
||||||
#include <drm/ttm/ttm_placement.h>
|
#include <drm/ttm/ttm_placement.h>
|
||||||
|
#include <drm/ttm/ttm_range_manager.h>
|
||||||
|
|
||||||
#include <drm/amdgpu_drm.h>
|
#include <drm/amdgpu_drm.h>
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <drm/drm_prime.h>
|
#include <drm/drm_prime.h>
|
||||||
#include <drm/drm_simple_kms_helper.h>
|
#include <drm/drm_simple_kms_helper.h>
|
||||||
|
|
||||||
|
#include <drm/ttm/ttm_range_manager.h>
|
||||||
|
|
||||||
static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
|
static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <linux/swiotlb.h>
|
#include <linux/swiotlb.h>
|
||||||
|
|
||||||
|
#include <drm/ttm/ttm_range_manager.h>
|
||||||
|
|
||||||
#include "nouveau_drv.h"
|
#include "nouveau_drv.h"
|
||||||
#include "nouveau_gem.h"
|
#include "nouveau_gem.h"
|
||||||
#include "nouveau_mem.h"
|
#include "nouveau_mem.h"
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <drm/ttm/ttm_bo_api.h>
|
#include <drm/ttm/ttm_bo_api.h>
|
||||||
#include <drm/ttm/ttm_bo_driver.h>
|
#include <drm/ttm/ttm_bo_driver.h>
|
||||||
#include <drm/ttm/ttm_placement.h>
|
#include <drm/ttm/ttm_placement.h>
|
||||||
|
#include <drm/ttm/ttm_range_manager.h>
|
||||||
|
|
||||||
#include "qxl_drv.h"
|
#include "qxl_drv.h"
|
||||||
#include "qxl_object.h"
|
#include "qxl_object.h"
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include <drm/ttm/ttm_bo_api.h>
|
#include <drm/ttm/ttm_bo_api.h>
|
||||||
#include <drm/ttm/ttm_bo_driver.h>
|
#include <drm/ttm/ttm_bo_driver.h>
|
||||||
#include <drm/ttm/ttm_placement.h>
|
#include <drm/ttm/ttm_placement.h>
|
||||||
|
#include <drm/ttm/ttm_range_manager.h>
|
||||||
|
|
||||||
#include "radeon_reg.h"
|
#include "radeon_reg.h"
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
|
|
|
@ -29,12 +29,13 @@
|
||||||
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
|
* 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_placement.h>
|
||||||
|
#include <drm/ttm/ttm_range_manager.h>
|
||||||
|
#include <drm/ttm/ttm_bo_api.h>
|
||||||
#include <drm/drm_mm.h>
|
#include <drm/drm_mm.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/module.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently we use a spinlock for the lock, but a mutex *may* be
|
* Currently we use a spinlock for the lock, but a mutex *may* be
|
||||||
|
@ -60,8 +61,8 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man,
|
||||||
struct ttm_resource *mem)
|
struct ttm_resource *mem)
|
||||||
{
|
{
|
||||||
struct ttm_range_manager *rman = to_range_manager(man);
|
struct ttm_range_manager *rman = to_range_manager(man);
|
||||||
|
struct ttm_range_mgr_node *node;
|
||||||
struct drm_mm *mm = &rman->mm;
|
struct drm_mm *mm = &rman->mm;
|
||||||
struct drm_mm_node *node;
|
|
||||||
enum drm_mm_insert_mode mode;
|
enum drm_mm_insert_mode mode;
|
||||||
unsigned long lpfn;
|
unsigned long lpfn;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -70,7 +71,7 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man,
|
||||||
if (!lpfn)
|
if (!lpfn)
|
||||||
lpfn = man->size;
|
lpfn = man->size;
|
||||||
|
|
||||||
node = kzalloc(sizeof(*node), GFP_KERNEL);
|
node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL);
|
||||||
if (!node)
|
if (!node)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -78,17 +79,19 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man,
|
||||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||||
mode = DRM_MM_INSERT_HIGH;
|
mode = DRM_MM_INSERT_HIGH;
|
||||||
|
|
||||||
|
ttm_resource_init(bo, place, &node->base);
|
||||||
|
|
||||||
spin_lock(&rman->lock);
|
spin_lock(&rman->lock);
|
||||||
ret = drm_mm_insert_node_in_range(mm, node, mem->num_pages,
|
ret = drm_mm_insert_node_in_range(mm, &node->mm_nodes[0],
|
||||||
bo->page_alignment, 0,
|
mem->num_pages, bo->page_alignment, 0,
|
||||||
place->fpfn, lpfn, mode);
|
place->fpfn, lpfn, mode);
|
||||||
spin_unlock(&rman->lock);
|
spin_unlock(&rman->lock);
|
||||||
|
|
||||||
if (unlikely(ret)) {
|
if (unlikely(ret)) {
|
||||||
kfree(node);
|
kfree(node);
|
||||||
} else {
|
} else {
|
||||||
mem->mm_node = node;
|
mem->mm_node = &node->mm_nodes[0];
|
||||||
mem->start = node->start;
|
mem->start = node->mm_nodes[0].start;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -98,15 +101,19 @@ static void ttm_range_man_free(struct ttm_resource_manager *man,
|
||||||
struct ttm_resource *mem)
|
struct ttm_resource *mem)
|
||||||
{
|
{
|
||||||
struct ttm_range_manager *rman = to_range_manager(man);
|
struct ttm_range_manager *rman = to_range_manager(man);
|
||||||
|
struct ttm_range_mgr_node *node;
|
||||||
|
|
||||||
if (mem->mm_node) {
|
if (!mem->mm_node)
|
||||||
spin_lock(&rman->lock);
|
return;
|
||||||
drm_mm_remove_node(mem->mm_node);
|
|
||||||
spin_unlock(&rman->lock);
|
|
||||||
|
|
||||||
kfree(mem->mm_node);
|
node = to_ttm_range_mgr_node(mem);
|
||||||
mem->mm_node = NULL;
|
|
||||||
}
|
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,
|
static void ttm_range_man_debug(struct ttm_resource_manager *man,
|
||||||
|
@ -125,6 +132,17 @@ static const struct ttm_resource_manager_func ttm_range_manager_func = {
|
||||||
.debug = ttm_range_man_debug
|
.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,
|
int ttm_range_man_init(struct ttm_device *bdev,
|
||||||
unsigned type, bool use_tt,
|
unsigned type, bool use_tt,
|
||||||
unsigned long p_size)
|
unsigned long p_size)
|
||||||
|
@ -152,6 +170,14 @@ int ttm_range_man_init(struct ttm_device *bdev,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ttm_range_man_init);
|
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,
|
int ttm_range_man_fini(struct ttm_device *bdev,
|
||||||
unsigned type)
|
unsigned type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,22 @@
|
||||||
#include <drm/ttm/ttm_resource.h>
|
#include <drm/ttm/ttm_resource.h>
|
||||||
#include <drm/ttm/ttm_bo_driver.h>
|
#include <drm/ttm/ttm_bo_driver.h>
|
||||||
|
|
||||||
|
void ttm_resource_init(struct ttm_buffer_object *bo,
|
||||||
|
const struct ttm_place *place,
|
||||||
|
struct ttm_resource *res)
|
||||||
|
{
|
||||||
|
res->mm_node = NULL;
|
||||||
|
res->start = 0;
|
||||||
|
res->num_pages = PFN_UP(bo->base.size);
|
||||||
|
res->mem_type = place->mem_type;
|
||||||
|
res->placement = place->flags;
|
||||||
|
res->bus.addr = NULL;
|
||||||
|
res->bus.offset = 0;
|
||||||
|
res->bus.is_iomem = false;
|
||||||
|
res->bus.caching = ttm_cached;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ttm_resource_init);
|
||||||
|
|
||||||
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
||||||
const struct ttm_place *place,
|
const struct ttm_place *place,
|
||||||
struct ttm_resource **res_ptr)
|
struct ttm_resource **res_ptr)
|
||||||
|
@ -38,15 +54,7 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
||||||
if (!res)
|
if (!res)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
res->mm_node = NULL;
|
ttm_resource_init(bo, place, res);
|
||||||
res->start = 0;
|
|
||||||
res->num_pages = PFN_UP(bo->base.size);
|
|
||||||
res->mem_type = place->mem_type;
|
|
||||||
res->placement = place->flags;
|
|
||||||
res->bus.addr = NULL;
|
|
||||||
res->bus.offset = 0;
|
|
||||||
res->bus.is_iomem = false;
|
|
||||||
res->bus.caching = ttm_cached;
|
|
||||||
r = man->func->alloc(man, bo, place, res);
|
r = man->func->alloc(man, bo, place, res);
|
||||||
if (r) {
|
if (r) {
|
||||||
kfree(res);
|
kfree(res);
|
||||||
|
|
|
@ -304,30 +304,4 @@ int ttm_bo_tt_bind(struct ttm_buffer_object *bo, struct ttm_resource *mem);
|
||||||
*/
|
*/
|
||||||
void ttm_bo_tt_destroy(struct ttm_buffer_object *bo);
|
void ttm_bo_tt_destroy(struct ttm_buffer_object *bo);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||||||
|
|
||||||
|
#ifndef _TTM_RANGE_MANAGER_H_
|
||||||
|
#define _TTM_RANGE_MANAGER_H_
|
||||||
|
|
||||||
|
#include <drm/ttm/ttm_resource.h>
|
||||||
|
#include <drm/drm_mm.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ttm_range_mgr_node
|
||||||
|
*
|
||||||
|
* @base: base clase we extend
|
||||||
|
* @mm_nodes: MM nodes, usually 1
|
||||||
|
*
|
||||||
|
* Extending the ttm_resource object to manage an address space allocation with
|
||||||
|
* one or more drm_mm_nodes.
|
||||||
|
*/
|
||||||
|
struct ttm_range_mgr_node {
|
||||||
|
struct ttm_resource base;
|
||||||
|
struct drm_mm_node mm_nodes[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to_ttm_range_mgr_node
|
||||||
|
*
|
||||||
|
* @res: the resource to upcast
|
||||||
|
*
|
||||||
|
* Upcast the ttm_resource object into a ttm_range_mgr_node object.
|
||||||
|
*/
|
||||||
|
static inline struct ttm_range_mgr_node *
|
||||||
|
to_ttm_range_mgr_node(struct ttm_resource *res)
|
||||||
|
{
|
||||||
|
return container_of(res->mm_node, struct ttm_range_mgr_node,
|
||||||
|
mm_nodes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ttm_range_man_init(struct ttm_device *bdev,
|
||||||
|
unsigned type, bool use_tt,
|
||||||
|
unsigned long p_size);
|
||||||
|
int ttm_range_man_fini(struct ttm_device *bdev,
|
||||||
|
unsigned type);
|
||||||
|
|
||||||
|
#endif
|
|
@ -223,6 +223,9 @@ ttm_resource_manager_cleanup(struct ttm_resource_manager *man)
|
||||||
man->move = NULL;
|
man->move = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ttm_resource_init(struct ttm_buffer_object *bo,
|
||||||
|
const struct ttm_place *place,
|
||||||
|
struct ttm_resource *res);
|
||||||
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
||||||
const struct ttm_place *place,
|
const struct ttm_place *place,
|
||||||
struct ttm_resource **res);
|
struct ttm_resource **res);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче