aboutsummaryrefslogtreecommitdiffstats
path: root/include/drm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2011-02-18 11:59:12 -0500
committerDave Airlie <airlied@redhat.com>2011-02-22 19:32:34 -0500
commitea7b1dd44867e9cd6bac67e7c9fc3f128b5b255c (patch)
tree2feb9852ab18e2f726136ae460e414ef40425129 /include/drm
parent31a5b8ce8f3bf20799eb68da9602de2bee58fdd3 (diff)
drm: mm: track free areas implicitly
The idea is to track free holes implicitly by marking the allocation immediatly preceeding a hole. To avoid an ugly corner case add a dummy head_node to struct drm_mm to track the hole that spans to complete allocation area when the memory manager is empty. To guarantee that there's always a preceeding/following node (that might be marked as hole_follows == 1), move the mm->node_list list_head to the head_node. The main allocator and fair-lru scan code actually becomes simpler. Only the debug code slightly suffers because free areas are no longer explicit. Also add drm_mm_for_each_node (which will be much more useful when struct drm_mm_node is embeddable). Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/drm_mm.h21
1 files changed, 12 insertions, 9 deletions
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 0d791462f7b2..34fa36f2de70 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -42,23 +42,24 @@
42#endif 42#endif
43 43
44struct drm_mm_node { 44struct drm_mm_node {
45 struct list_head free_stack;
46 struct list_head node_list; 45 struct list_head node_list;
47 unsigned free : 1; 46 struct list_head hole_stack;
47 unsigned hole_follows : 1;
48 unsigned scanned_block : 1; 48 unsigned scanned_block : 1;
49 unsigned scanned_prev_free : 1; 49 unsigned scanned_prev_free : 1;
50 unsigned scanned_next_free : 1; 50 unsigned scanned_next_free : 1;
51 unsigned scanned_preceeds_hole : 1;
51 unsigned long start; 52 unsigned long start;
52 unsigned long size; 53 unsigned long size;
53 struct drm_mm *mm; 54 struct drm_mm *mm;
54}; 55};
55 56
56struct drm_mm { 57struct drm_mm {
57 /* List of free memory blocks, most recently freed ordered. */ 58 /* List of all memory nodes that immediatly preceed a free hole. */
58 struct list_head free_stack; 59 struct list_head hole_stack;
59 /* List of all memory nodes, ordered according to the (increasing) start 60 /* head_node.node_list is the list of all memory nodes, ordered
60 * address of the memory node. */ 61 * according to the (increasing) start address of the memory node. */
61 struct list_head node_list; 62 struct drm_mm_node head_node;
62 struct list_head unused_nodes; 63 struct list_head unused_nodes;
63 int num_unused; 64 int num_unused;
64 spinlock_t unused_lock; 65 spinlock_t unused_lock;
@@ -74,9 +75,11 @@ struct drm_mm {
74 75
75static inline bool drm_mm_initialized(struct drm_mm *mm) 76static inline bool drm_mm_initialized(struct drm_mm *mm)
76{ 77{
77 return mm->free_stack.next; 78 return mm->hole_stack.next;
78} 79}
79 80#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
81 &(mm)->head_node.node_list, \
82 node_list);
80/* 83/*
81 * Basic range manager support (drm_mm.c) 84 * Basic range manager support (drm_mm.c)
82 */ 85 */