diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2009-06-17 12:29:56 +0200 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-06-19 09:01:12 +1000 |
commit | 89579f778266d5a4d08d0c64c46b1565218de9f9 (patch) | |
tree | f7a2389d1277bf285e790b660e0f6a6019ff857f | |
parent | 78ecf091aa592a9e160ebbbfa5873c2bb2e2d0f8 (diff) | |
download | linux-89579f778266d5a4d08d0c64c46b1565218de9f9.tar.bz2 |
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>
-rw-r--r-- | drivers/gpu/drm/drm_mm.c | 48 | ||||
-rw-r--r-- | include/drm/drm_mm.h | 21 |
2 files changed, 22 insertions, 47 deletions
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index a912a0ff11cc..3e47869d6dae 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/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. diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 5662f4278ef3..f8332073d277 100644 --- a/include/drm/drm_mm.h +++ b/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, |