Browse Source

drm: Memory fragmentation from lost alignment blocks

If the block needs an alignment but otherwise fits exactly into the tail,
then the split-off block from the start would remain marked as non-free.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Chris Wilson 16 years ago
parent
commit
e6c03c5b40
1 changed files with 9 additions and 11 deletions
  1. 9 11
      drivers/gpu/drm/drm_mm.c

+ 9 - 11
drivers/gpu/drm/drm_mm.c

@@ -188,36 +188,34 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
 
 
 
 
 
 
-struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
-				unsigned long size, unsigned alignment)
+struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node,
+				     unsigned long size, unsigned alignment)
 {
 {
 
 
 	struct drm_mm_node *align_splitoff = NULL;
 	struct drm_mm_node *align_splitoff = NULL;
-	struct drm_mm_node *child;
 	unsigned tmp = 0;
 	unsigned tmp = 0;
 
 
 	if (alignment)
 	if (alignment)
-		tmp = parent->start % alignment;
+		tmp = node->start % alignment;
 
 
 	if (tmp) {
 	if (tmp) {
 		align_splitoff =
 		align_splitoff =
-		    drm_mm_split_at_start(parent, alignment - tmp, 0);
+		    drm_mm_split_at_start(node, alignment - tmp, 0);
 		if (unlikely(align_splitoff == NULL))
 		if (unlikely(align_splitoff == NULL))
 			return NULL;
 			return NULL;
 	}
 	}
 
 
-	if (parent->size == size) {
-		list_del_init(&parent->fl_entry);
-		parent->free = 0;
-		return parent;
+	if (node->size == size) {
+		list_del_init(&node->fl_entry);
+		node->free = 0;
 	} else {
 	} else {
-		child = drm_mm_split_at_start(parent, size, 0);
+		node = drm_mm_split_at_start(node, size, 0);
 	}
 	}
 
 
 	if (align_splitoff)
 	if (align_splitoff)
 		drm_mm_put_block(align_splitoff);
 		drm_mm_put_block(align_splitoff);
 
 
-	return child;
+	return node;
 }
 }
 
 
 EXPORT_SYMBOL(drm_mm_get_block);
 EXPORT_SYMBOL(drm_mm_get_block);