aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-07-27 07:36:27 -0400
committerDave Airlie <airlied@redhat.com>2013-08-06 20:08:58 -0400
commit31e5d7c67bd492fd0b2988440e21e31809c7c9af (patch)
tree833339e49a2d739068e92f01d2f47c5e9cc6d5d0
parent7fc65eb731cda8304865669166fb9a4c519bee69 (diff)
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>
-rw-r--r--drivers/gpu/drm/drm_mm.c37
-rw-r--r--drivers/gpu/drm/drm_vma_manager.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c12
-rw-r--r--drivers/gpu/drm/sis/sis_mm.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_manager.c3
-rw-r--r--drivers/gpu/drm/via/via_mm.c4
-rw-r--r--include/drm/drm_mm.h54
8 files changed, 68 insertions, 55 deletions
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index fe304f903b13..9a383272c8c7 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -212,12 +212,13 @@ EXPORT_SYMBOL(drm_mm_get_block_generic);
212 */ 212 */
213int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, 213int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
214 unsigned long size, unsigned alignment, 214 unsigned long size, unsigned alignment,
215 unsigned long color) 215 unsigned long color,
216 enum drm_mm_search_flags flags)
216{ 217{
217 struct drm_mm_node *hole_node; 218 struct drm_mm_node *hole_node;
218 219
219 hole_node = drm_mm_search_free_generic(mm, size, alignment, 220 hole_node = drm_mm_search_free_generic(mm, size, alignment,
220 color, 0); 221 color, flags);
221 if (!hole_node) 222 if (!hole_node)
222 return -ENOSPC; 223 return -ENOSPC;
223 224
@@ -226,13 +227,6 @@ int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
226} 227}
227EXPORT_SYMBOL(drm_mm_insert_node_generic); 228EXPORT_SYMBOL(drm_mm_insert_node_generic);
228 229
229int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
230 unsigned long size, unsigned alignment)
231{
232 return drm_mm_insert_node_generic(mm, node, size, alignment, 0);
233}
234EXPORT_SYMBOL(drm_mm_insert_node);
235
236static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, 230static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
237 struct drm_mm_node *node, 231 struct drm_mm_node *node,
238 unsigned long size, unsigned alignment, 232 unsigned long size, unsigned alignment,
@@ -313,13 +307,14 @@ EXPORT_SYMBOL(drm_mm_get_block_range_generic);
313 */ 307 */
314int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node, 308int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node,
315 unsigned long size, unsigned alignment, unsigned long color, 309 unsigned long size, unsigned alignment, unsigned long color,
316 unsigned long start, unsigned long end) 310 unsigned long start, unsigned long end,
311 enum drm_mm_search_flags flags)
317{ 312{
318 struct drm_mm_node *hole_node; 313 struct drm_mm_node *hole_node;
319 314
320 hole_node = drm_mm_search_free_in_range_generic(mm, 315 hole_node = drm_mm_search_free_in_range_generic(mm,
321 size, alignment, color, 316 size, alignment, color,
322 start, end, 0); 317 start, end, flags);
323 if (!hole_node) 318 if (!hole_node)
324 return -ENOSPC; 319 return -ENOSPC;
325 320
@@ -330,14 +325,6 @@ int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *n
330} 325}
331EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic); 326EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic);
332 327
333int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node,
334 unsigned long size, unsigned alignment,
335 unsigned long start, unsigned long end)
336{
337 return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, 0, start, end);
338}
339EXPORT_SYMBOL(drm_mm_insert_node_in_range);
340
341/** 328/**
342 * Remove a memory node from the allocator. 329 * Remove a memory node from the allocator.
343 */ 330 */
@@ -413,7 +400,7 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
413 unsigned long size, 400 unsigned long size,
414 unsigned alignment, 401 unsigned alignment,
415 unsigned long color, 402 unsigned long color,
416 bool best_match) 403 enum drm_mm_search_flags flags)
417{ 404{
418 struct drm_mm_node *entry; 405 struct drm_mm_node *entry;
419 struct drm_mm_node *best; 406 struct drm_mm_node *best;
@@ -436,7 +423,7 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
436 if (!check_free_hole(adj_start, adj_end, size, alignment)) 423 if (!check_free_hole(adj_start, adj_end, size, alignment))
437 continue; 424 continue;
438 425
439 if (!best_match) 426 if (!(flags & DRM_MM_SEARCH_BEST))
440 return entry; 427 return entry;
441 428
442 if (entry->size < best_size) { 429 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,
455 unsigned long color, 442 unsigned long color,
456 unsigned long start, 443 unsigned long start,
457 unsigned long end, 444 unsigned long end,
458 bool best_match) 445 enum drm_mm_search_flags flags)
459{ 446{
460 struct drm_mm_node *entry; 447 struct drm_mm_node *entry;
461 struct drm_mm_node *best; 448 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,
483 if (!check_free_hole(adj_start, adj_end, size, alignment)) 470 if (!check_free_hole(adj_start, adj_end, size, alignment))
484 continue; 471 continue;
485 472
486 if (!best_match) 473 if (!(flags & DRM_MM_SEARCH_BEST))
487 return entry; 474 return entry;
488 475
489 if (entry->size < best_size) { 476 if (entry->size < best_size) {
@@ -629,8 +616,8 @@ EXPORT_SYMBOL(drm_mm_scan_add_block);
629 * corrupted. 616 * corrupted.
630 * 617 *
631 * When the scan list is empty, the selected memory nodes can be freed. An 618 * When the scan list is empty, the selected memory nodes can be freed. An
632 * immediately following drm_mm_search_free with best_match = 0 will then return 619 * immediately following drm_mm_search_free with !DRM_MM_SEARCH_BEST will then
633 * the just freed block (because its at the top of the free_stack list). 620 * return the just freed block (because its at the top of the free_stack list).
634 * 621 *
635 * Returns one if this block should be evicted, zero otherwise. Will always 622 * Returns one if this block should be evicted, zero otherwise. Will always
636 * return zero when no hole has been found. 623 * return zero when no hole has been found.
diff --git a/drivers/gpu/drm/drm_vma_manager.c b/drivers/gpu/drm/drm_vma_manager.c
index b966cea95f11..3837481d5607 100644
--- a/drivers/gpu/drm/drm_vma_manager.c
+++ b/drivers/gpu/drm/drm_vma_manager.c
@@ -241,8 +241,8 @@ int drm_vma_offset_add(struct drm_vma_offset_manager *mgr,
241 goto out_unlock; 241 goto out_unlock;
242 } 242 }
243 243
244 ret = drm_mm_insert_node_generic(&mgr->vm_addr_space_mm, 244 ret = drm_mm_insert_node(&mgr->vm_addr_space_mm, &node->vm_node,
245 &node->vm_node, pages, 0, 0); 245 pages, 0, DRM_MM_SEARCH_DEFAULT);
246 if (ret) 246 if (ret)
247 goto out_unlock; 247 goto out_unlock;
248 248
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2aa0894b59cd..ea2d83d7324e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3085,7 +3085,8 @@ search_free:
3085 ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, 3085 ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space,
3086 &obj->gtt_space, 3086 &obj->gtt_space,
3087 size, alignment, 3087 size, alignment,
3088 obj->cache_level, 0, gtt_max); 3088 obj->cache_level, 0, gtt_max,
3089 DRM_MM_SEARCH_DEFAULT);
3089 if (ret) { 3090 if (ret) {
3090 ret = i915_gem_evict_something(dev, size, alignment, 3091 ret = i915_gem_evict_something(dev, size, alignment,
3091 obj->cache_level, 3092 obj->cache_level,
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 55218332e625..e3551706f4ff 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -115,10 +115,12 @@ static int i915_setup_compression(struct drm_device *dev, int size)
115 115
116 /* Try to over-allocate to reduce reallocations and fragmentation */ 116 /* Try to over-allocate to reduce reallocations and fragmentation */
117 compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, 117 compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
118 size <<= 1, 4096, 0); 118 size <<= 1, 4096,
119 DRM_MM_SEARCH_DEFAULT);
119 if (!compressed_fb) 120 if (!compressed_fb)
120 compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, 121 compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
121 size >>= 1, 4096, 0); 122 size >>= 1, 4096,
123 DRM_MM_SEARCH_DEFAULT);
122 if (compressed_fb) 124 if (compressed_fb)
123 compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); 125 compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
124 if (!compressed_fb) 126 if (!compressed_fb)
@@ -130,7 +132,8 @@ static int i915_setup_compression(struct drm_device *dev, int size)
130 I915_WRITE(DPFC_CB_BASE, compressed_fb->start); 132 I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
131 } else { 133 } else {
132 compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, 134 compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen,
133 4096, 4096, 0); 135 4096, 4096,
136 DRM_MM_SEARCH_DEFAULT);
134 if (compressed_llb) 137 if (compressed_llb)
135 compressed_llb = drm_mm_get_block(compressed_llb, 138 compressed_llb = drm_mm_get_block(compressed_llb,
136 4096, 4096); 139 4096, 4096);
@@ -328,7 +331,8 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
328 if (size == 0) 331 if (size == 0)
329 return NULL; 332 return NULL;
330 333
331 stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0); 334 stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096,
335 DRM_MM_SEARCH_DEFAULT);
332 if (stolen) 336 if (stolen)
333 stolen = drm_mm_get_block(stolen, size, 4096); 337 stolen = drm_mm_get_block(stolen, size, 4096);
334 if (stolen == NULL) 338 if (stolen == NULL)
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index 9a43d98e5003..23a234985941 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -109,7 +109,8 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
109 if (pool == AGP_TYPE) { 109 if (pool == AGP_TYPE) {
110 retval = drm_mm_insert_node(&dev_priv->agp_mm, 110 retval = drm_mm_insert_node(&dev_priv->agp_mm,
111 &item->mm_node, 111 &item->mm_node,
112 mem->size, 0); 112 mem->size, 0,
113 DRM_MM_SEARCH_DEFAULT);
113 offset = item->mm_node.start; 114 offset = item->mm_node.start;
114 } else { 115 } else {
115#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE) 116#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,
121#else 122#else
122 retval = drm_mm_insert_node(&dev_priv->vram_mm, 123 retval = drm_mm_insert_node(&dev_priv->vram_mm,
123 &item->mm_node, 124 &item->mm_node,
124 mem->size, 0); 125 mem->size, 0,
126 DRM_MM_SEARCH_DEFAULT);
125 offset = item->mm_node.start; 127 offset = item->mm_node.start;
126#endif 128#endif
127 } 129 }
diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c
index e4367f91472a..e4be29efba6b 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c
@@ -69,7 +69,8 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
69 spin_lock(&rman->lock); 69 spin_lock(&rman->lock);
70 node = drm_mm_search_free_in_range(mm, 70 node = drm_mm_search_free_in_range(mm,
71 mem->num_pages, mem->page_alignment, 71 mem->num_pages, mem->page_alignment,
72 placement->fpfn, lpfn, 1); 72 placement->fpfn, lpfn,
73 DRM_MM_SEARCH_BEST);
73 if (unlikely(node == NULL)) { 74 if (unlikely(node == NULL)) {
74 spin_unlock(&rman->lock); 75 spin_unlock(&rman->lock);
75 return 0; 76 return 0;
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index 0ab93ff09873..7e3ad87c366c 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -140,11 +140,11 @@ int via_mem_alloc(struct drm_device *dev, void *data,
140 if (mem->type == VIA_MEM_AGP) 140 if (mem->type == VIA_MEM_AGP)
141 retval = drm_mm_insert_node(&dev_priv->agp_mm, 141 retval = drm_mm_insert_node(&dev_priv->agp_mm,
142 &item->mm_node, 142 &item->mm_node,
143 tmpSize, 0); 143 tmpSize, 0, DRM_MM_SEARCH_DEFAULT);
144 else 144 else
145 retval = drm_mm_insert_node(&dev_priv->vram_mm, 145 retval = drm_mm_insert_node(&dev_priv->vram_mm,
146 &item->mm_node, 146 &item->mm_node,
147 tmpSize, 0); 147 tmpSize, 0, DRM_MM_SEARCH_DEFAULT);
148 if (retval) 148 if (retval)
149 goto fail_alloc; 149 goto fail_alloc;
150 150
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 98cb50ea6acb..439d1a17d3b1 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -44,6 +44,11 @@
44#include <linux/seq_file.h> 44#include <linux/seq_file.h>
45#endif 45#endif
46 46
47enum drm_mm_search_flags {
48 DRM_MM_SEARCH_DEFAULT = 0,
49 DRM_MM_SEARCH_BEST = 1 << 0,
50};
51
47struct drm_mm_node { 52struct drm_mm_node {
48 struct list_head node_list; 53 struct list_head node_list;
49 struct list_head hole_stack; 54 struct list_head hole_stack;
@@ -189,28 +194,41 @@ static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
189 start, end, 1); 194 start, end, 1);
190} 195}
191 196
192extern int drm_mm_insert_node(struct drm_mm *mm,
193 struct drm_mm_node *node,
194 unsigned long size,
195 unsigned alignment);
196extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
197 struct drm_mm_node *node,
198 unsigned long size,
199 unsigned alignment,
200 unsigned long start,
201 unsigned long end);
202extern int drm_mm_insert_node_generic(struct drm_mm *mm, 197extern int drm_mm_insert_node_generic(struct drm_mm *mm,
203 struct drm_mm_node *node, 198 struct drm_mm_node *node,
204 unsigned long size, 199 unsigned long size,
205 unsigned alignment, 200 unsigned alignment,
206 unsigned long color); 201 unsigned long color,
202 enum drm_mm_search_flags flags);
203static inline int drm_mm_insert_node(struct drm_mm *mm,
204 struct drm_mm_node *node,
205 unsigned long size,
206 unsigned alignment,
207 enum drm_mm_search_flags flags)
208{
209 return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags);
210}
211
207extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, 212extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
208 struct drm_mm_node *node, 213 struct drm_mm_node *node,
209 unsigned long size, 214 unsigned long size,
210 unsigned alignment, 215 unsigned alignment,
211 unsigned long color, 216 unsigned long color,
212 unsigned long start, 217 unsigned long start,
213 unsigned long end); 218 unsigned long end,
219 enum drm_mm_search_flags flags);
220static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
221 struct drm_mm_node *node,
222 unsigned long size,
223 unsigned alignment,
224 unsigned long start,
225 unsigned long end,
226 enum drm_mm_search_flags flags)
227{
228 return drm_mm_insert_node_in_range_generic(mm, node, size, alignment,
229 0, start, end, flags);
230}
231
214extern void drm_mm_put_block(struct drm_mm_node *cur); 232extern void drm_mm_put_block(struct drm_mm_node *cur);
215extern void drm_mm_remove_node(struct drm_mm_node *node); 233extern void drm_mm_remove_node(struct drm_mm_node *node);
216extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); 234extern 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,
218 unsigned long size, 236 unsigned long size,
219 unsigned alignment, 237 unsigned alignment,
220 unsigned long color, 238 unsigned long color,
221 bool best_match); 239 enum drm_mm_search_flags flags);
222extern struct drm_mm_node *drm_mm_search_free_in_range_generic( 240extern struct drm_mm_node *drm_mm_search_free_in_range_generic(
223 const struct drm_mm *mm, 241 const struct drm_mm *mm,
224 unsigned long size, 242 unsigned long size,
@@ -226,13 +244,13 @@ extern struct drm_mm_node *drm_mm_search_free_in_range_generic(
226 unsigned long color, 244 unsigned long color,
227 unsigned long start, 245 unsigned long start,
228 unsigned long end, 246 unsigned long end,
229 bool best_match); 247 enum drm_mm_search_flags flags);
230static inline struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, 248static inline struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
231 unsigned long size, 249 unsigned long size,
232 unsigned alignment, 250 unsigned alignment,
233 bool best_match) 251 enum drm_mm_search_flags flags)
234{ 252{
235 return drm_mm_search_free_generic(mm,size, alignment, 0, best_match); 253 return drm_mm_search_free_generic(mm,size, alignment, 0, flags);
236} 254}
237static inline struct drm_mm_node *drm_mm_search_free_in_range( 255static inline struct drm_mm_node *drm_mm_search_free_in_range(
238 const struct drm_mm *mm, 256 const struct drm_mm *mm,
@@ -240,10 +258,10 @@ static inline struct drm_mm_node *drm_mm_search_free_in_range(
240 unsigned alignment, 258 unsigned alignment,
241 unsigned long start, 259 unsigned long start,
242 unsigned long end, 260 unsigned long end,
243 bool best_match) 261 enum drm_mm_search_flags flags)
244{ 262{
245 return drm_mm_search_free_in_range_generic(mm, size, alignment, 0, 263 return drm_mm_search_free_in_range_generic(mm, size, alignment, 0,
246 start, end, best_match); 264 start, end, flags);
247} 265}
248 266
249extern void drm_mm_init(struct drm_mm *mm, 267extern void drm_mm_init(struct drm_mm *mm,