drm/mm: add "best_match" flag to drm_mm_insert_node()
Add a "best_match" flag similar to the drm_mm_search_*() helpers so we can convert TTM to use them in follow up patches. We can also inline the non-generic helpers and move them into the header to allow compile-time optimizations. To make calls to drm_mm_{search,insert}_node() more readable, this converts the boolean argument to a flagset. There are pending patches that add additional flags for top-down allocators and more. v2: - use flag parameter instead of boolean "best_match" - convert *_search_free() helpers to also use flags argument Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Родитель
7fc65eb731
Коммит
31e5d7c67b
|
@ -212,12 +212,13 @@ EXPORT_SYMBOL(drm_mm_get_block_generic);
|
|||
*/
|
||||
int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
|
||||
unsigned long size, unsigned alignment,
|
||||
unsigned long color)
|
||||
unsigned long color,
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
struct drm_mm_node *hole_node;
|
||||
|
||||
hole_node = drm_mm_search_free_generic(mm, size, alignment,
|
||||
color, 0);
|
||||
color, flags);
|
||||
if (!hole_node)
|
||||
return -ENOSPC;
|
||||
|
||||
|
@ -226,13 +227,6 @@ int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_mm_insert_node_generic);
|
||||
|
||||
int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
|
||||
unsigned long size, unsigned alignment)
|
||||
{
|
||||
return drm_mm_insert_node_generic(mm, node, size, alignment, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_insert_node);
|
||||
|
||||
static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
|
||||
struct drm_mm_node *node,
|
||||
unsigned long size, unsigned alignment,
|
||||
|
@ -313,13 +307,14 @@ EXPORT_SYMBOL(drm_mm_get_block_range_generic);
|
|||
*/
|
||||
int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node,
|
||||
unsigned long size, unsigned alignment, unsigned long color,
|
||||
unsigned long start, unsigned long end)
|
||||
unsigned long start, unsigned long end,
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
struct drm_mm_node *hole_node;
|
||||
|
||||
hole_node = drm_mm_search_free_in_range_generic(mm,
|
||||
size, alignment, color,
|
||||
start, end, 0);
|
||||
start, end, flags);
|
||||
if (!hole_node)
|
||||
return -ENOSPC;
|
||||
|
||||
|
@ -330,14 +325,6 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *n
|
|||
}
|
||||
EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic);
|
||||
|
||||
int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node,
|
||||
unsigned long size, unsigned alignment,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, 0, start, end);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mm_insert_node_in_range);
|
||||
|
||||
/**
|
||||
* Remove a memory node from the allocator.
|
||||
*/
|
||||
|
@ -413,7 +400,7 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
|
|||
unsigned long size,
|
||||
unsigned alignment,
|
||||
unsigned long color,
|
||||
bool best_match)
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
struct drm_mm_node *entry;
|
||||
struct drm_mm_node *best;
|
||||
|
@ -436,7 +423,7 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
|
|||
if (!check_free_hole(adj_start, adj_end, size, alignment))
|
||||
continue;
|
||||
|
||||
if (!best_match)
|
||||
if (!(flags & DRM_MM_SEARCH_BEST))
|
||||
return entry;
|
||||
|
||||
if (entry->size < best_size) {
|
||||
|
@ -455,7 +442,7 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
|
|||
unsigned long color,
|
||||
unsigned long start,
|
||||
unsigned long end,
|
||||
bool best_match)
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
struct drm_mm_node *entry;
|
||||
struct drm_mm_node *best;
|
||||
|
@ -483,7 +470,7 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
|
|||
if (!check_free_hole(adj_start, adj_end, size, alignment))
|
||||
continue;
|
||||
|
||||
if (!best_match)
|
||||
if (!(flags & DRM_MM_SEARCH_BEST))
|
||||
return entry;
|
||||
|
||||
if (entry->size < best_size) {
|
||||
|
@ -629,8 +616,8 @@ EXPORT_SYMBOL(drm_mm_scan_add_block);
|
|||
* corrupted.
|
||||
*
|
||||
* When the scan list is empty, the selected memory nodes can be freed. An
|
||||
* immediately following drm_mm_search_free with best_match = 0 will then return
|
||||
* the just freed block (because its at the top of the free_stack list).
|
||||
* immediately following drm_mm_search_free with !DRM_MM_SEARCH_BEST will then
|
||||
* return the just freed block (because its at the top of the free_stack list).
|
||||
*
|
||||
* Returns one if this block should be evicted, zero otherwise. Will always
|
||||
* return zero when no hole has been found.
|
||||
|
|
|
@ -241,8 +241,8 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr,
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = drm_mm_insert_node_generic(&mgr->vm_addr_space_mm,
|
||||
&node->vm_node, pages, 0, 0);
|
||||
ret = drm_mm_insert_node(&mgr->vm_addr_space_mm, &node->vm_node,
|
||||
pages, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
|
|
|
@ -3085,7 +3085,8 @@ search_free:
|
|||
ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space,
|
||||
&obj->gtt_space,
|
||||
size, alignment,
|
||||
obj->cache_level, 0, gtt_max);
|
||||
obj->cache_level, 0, gtt_max,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
if (ret) {
|
||||
ret = i915_gem_evict_something(dev, size, alignment,
|
||||
obj->cache_level,
|
||||
|
|
|
@ -115,10 +115,12 @@ static int i915_setup_compression(struct drm_device *dev, int size)
|
|||
|
||||
/* Try to over-allocate to reduce reallocations and fragmentation */
|
||||
compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
|
||||
size <<= 1, 4096, 0);
|
||||
size <<= 1, 4096,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
if (!compressed_fb)
|
||||
compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
|
||||
size >>= 1, 4096, 0);
|
||||
size >>= 1, 4096,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
if (compressed_fb)
|
||||
compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
|
||||
if (!compressed_fb)
|
||||
|
@ -130,7 +132,8 @@ static int i915_setup_compression(struct drm_device *dev, int size)
|
|||
I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
|
||||
} else {
|
||||
compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen,
|
||||
4096, 4096, 0);
|
||||
4096, 4096,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
if (compressed_llb)
|
||||
compressed_llb = drm_mm_get_block(compressed_llb,
|
||||
4096, 4096);
|
||||
|
@ -328,7 +331,8 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
|
|||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0);
|
||||
stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
if (stolen)
|
||||
stolen = drm_mm_get_block(stolen, size, 4096);
|
||||
if (stolen == NULL)
|
||||
|
|
|
@ -109,7 +109,8 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
|
|||
if (pool == AGP_TYPE) {
|
||||
retval = drm_mm_insert_node(&dev_priv->agp_mm,
|
||||
&item->mm_node,
|
||||
mem->size, 0);
|
||||
mem->size, 0,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
offset = item->mm_node.start;
|
||||
} else {
|
||||
#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
|
||||
|
@ -121,7 +122,8 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
|
|||
#else
|
||||
retval = drm_mm_insert_node(&dev_priv->vram_mm,
|
||||
&item->mm_node,
|
||||
mem->size, 0);
|
||||
mem->size, 0,
|
||||
DRM_MM_SEARCH_DEFAULT);
|
||||
offset = item->mm_node.start;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -69,7 +69,8 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
|
|||
spin_lock(&rman->lock);
|
||||
node = drm_mm_search_free_in_range(mm,
|
||||
mem->num_pages, mem->page_alignment,
|
||||
placement->fpfn, lpfn, 1);
|
||||
placement->fpfn, lpfn,
|
||||
DRM_MM_SEARCH_BEST);
|
||||
if (unlikely(node == NULL)) {
|
||||
spin_unlock(&rman->lock);
|
||||
return 0;
|
||||
|
|
|
@ -140,11 +140,11 @@ int via_mem_alloc(struct drm_device *dev, void *data,
|
|||
if (mem->type == VIA_MEM_AGP)
|
||||
retval = drm_mm_insert_node(&dev_priv->agp_mm,
|
||||
&item->mm_node,
|
||||
tmpSize, 0);
|
||||
tmpSize, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
else
|
||||
retval = drm_mm_insert_node(&dev_priv->vram_mm,
|
||||
&item->mm_node,
|
||||
tmpSize, 0);
|
||||
tmpSize, 0, DRM_MM_SEARCH_DEFAULT);
|
||||
if (retval)
|
||||
goto fail_alloc;
|
||||
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
#include <linux/seq_file.h>
|
||||
#endif
|
||||
|
||||
enum drm_mm_search_flags {
|
||||
DRM_MM_SEARCH_DEFAULT = 0,
|
||||
DRM_MM_SEARCH_BEST = 1 << 0,
|
||||
};
|
||||
|
||||
struct drm_mm_node {
|
||||
struct list_head node_list;
|
||||
struct list_head hole_stack;
|
||||
|
@ -189,28 +194,41 @@ static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
|
|||
start, end, 1);
|
||||
}
|
||||
|
||||
extern int drm_mm_insert_node(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment);
|
||||
extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
unsigned long start,
|
||||
unsigned long end);
|
||||
extern int drm_mm_insert_node_generic(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
unsigned long color);
|
||||
unsigned long color,
|
||||
enum drm_mm_search_flags flags);
|
||||
static inline int drm_mm_insert_node(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags);
|
||||
}
|
||||
|
||||
extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
unsigned long color,
|
||||
unsigned long start,
|
||||
unsigned long end);
|
||||
unsigned long end,
|
||||
enum drm_mm_search_flags flags);
|
||||
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
|
||||
struct drm_mm_node *node,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
unsigned long start,
|
||||
unsigned long end,
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
|
||||
0, start, end, flags);
|
||||
}
|
||||
|
||||
extern void drm_mm_put_block(struct drm_mm_node *cur);
|
||||
extern void drm_mm_remove_node(struct drm_mm_node *node);
|
||||
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
|
||||
|
@ -218,7 +236,7 @@ extern struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
|
|||
unsigned long size,
|
||||
unsigned alignment,
|
||||
unsigned long color,
|
||||
bool best_match);
|
||||
enum drm_mm_search_flags flags);
|
||||
extern struct drm_mm_node *drm_mm_search_free_in_range_generic(
|
||||
const struct drm_mm *mm,
|
||||
unsigned long size,
|
||||
|
@ -226,13 +244,13 @@ extern struct drm_mm_node *drm_mm_search_free_in_range_generic(
|
|||
unsigned long color,
|
||||
unsigned long start,
|
||||
unsigned long end,
|
||||
bool best_match);
|
||||
enum drm_mm_search_flags flags);
|
||||
static inline struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
|
||||
unsigned long size,
|
||||
unsigned alignment,
|
||||
bool best_match)
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
return drm_mm_search_free_generic(mm,size, alignment, 0, best_match);
|
||||
return drm_mm_search_free_generic(mm,size, alignment, 0, flags);
|
||||
}
|
||||
static inline struct drm_mm_node *drm_mm_search_free_in_range(
|
||||
const struct drm_mm *mm,
|
||||
|
@ -240,10 +258,10 @@ static inline struct drm_mm_node *drm_mm_search_free_in_range(
|
|||
unsigned alignment,
|
||||
unsigned long start,
|
||||
unsigned long end,
|
||||
bool best_match)
|
||||
enum drm_mm_search_flags flags)
|
||||
{
|
||||
return drm_mm_search_free_in_range_generic(mm, size, alignment, 0,
|
||||
start, end, best_match);
|
||||
start, end, flags);
|
||||
}
|
||||
|
||||
extern void drm_mm_init(struct drm_mm *mm,
|
||||
|
|
Загрузка…
Ссылка в новой задаче