浏览代码

drm: Apply "Memory fragmentation from lost alignment blocks"

also for the atomic path by using a common code-path.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Thomas Hellstrom 16 年之前
父节点
当前提交
89579f7782
共有 2 个文件被更改,包括 22 次插入47 次删除
  1. 7 41
      drivers/gpu/drm/drm_mm.c
  2. 15 6
      include/drm/drm_mm.h

+ 7 - 41
drivers/gpu/drm/drm_mm.c

@@ -187,9 +187,10 @@ 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 *node,
-				     unsigned long size, unsigned alignment)
+struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
+					     unsigned long size,
+					     unsigned alignment,
+					     int atomic)
 {
 
 	struct drm_mm_node *align_splitoff = NULL;
@@ -200,7 +201,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node,
 
 	if (tmp) {
 		align_splitoff =
-		    drm_mm_split_at_start(node, alignment - tmp, 0);
+		    drm_mm_split_at_start(node, alignment - tmp, atomic);
 		if (unlikely(align_splitoff == NULL))
 			return NULL;
 	}
@@ -209,7 +210,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node,
 		list_del_init(&node->fl_entry);
 		node->free = 0;
 	} else {
-		node = drm_mm_split_at_start(node, size, 0);
+		node = drm_mm_split_at_start(node, size, atomic);
 	}
 
 	if (align_splitoff)
@@ -217,42 +218,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node,
 
 	return node;
 }
-
-EXPORT_SYMBOL(drm_mm_get_block);
-
-struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
-					    unsigned long size,
-					    unsigned alignment)
-{
-
-	struct drm_mm_node *align_splitoff = NULL;
-	struct drm_mm_node *child;
-	unsigned tmp = 0;
-
-	if (alignment)
-		tmp = parent->start % alignment;
-
-	if (tmp) {
-		align_splitoff =
-		    drm_mm_split_at_start(parent, alignment - tmp, 1);
-		if (unlikely(align_splitoff == NULL))
-			return NULL;
-	}
-
-	if (parent->size == size) {
-		list_del_init(&parent->fl_entry);
-		parent->free = 0;
-		return parent;
-	} else {
-		child = drm_mm_split_at_start(parent, size, 1);
-	}
-
-	if (align_splitoff)
-		drm_mm_put_block(align_splitoff);
-
-	return child;
-}
-EXPORT_SYMBOL(drm_mm_get_block_atomic);
+EXPORT_SYMBOL(drm_mm_get_block_generic);
 
 /*
  * Put a block. Merge with the previous and / or next block if they are free.

+ 15 - 6
include/drm/drm_mm.h

@@ -59,13 +59,22 @@ struct drm_mm {
 /*
  * Basic range manager support (drm_mm.c)
  */
-
-extern struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
-					    unsigned long size,
-					    unsigned alignment);
-extern struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
+extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
+						    unsigned long size,
+						    unsigned alignment,
+						    int atomic);
+static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
 						   unsigned long size,
-						   unsigned alignment);
+						   unsigned alignment)
+{
+	return drm_mm_get_block_generic(parent, size, alignment, 0);
+}
+static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
+							  unsigned long size,
+							  unsigned alignment)
+{
+	return drm_mm_get_block_generic(parent, size, alignment, 1);
+}
 extern void drm_mm_put_block(struct drm_mm_node *cur);
 extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
 					      unsigned long size,