Skip to content

Commit

Permalink
drm: Apply "Memory fragmentation from lost alignment blocks"
Browse files Browse the repository at this point in the history
also for the atomic path by using a common code-path.

Signed-off-by: Thomas Hellstrom <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
  • Loading branch information
thomashvmw authored and airlied committed Jun 18, 2009
1 parent 78ecf09 commit 89579f7
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 47 deletions.
48 changes: 7 additions & 41 deletions drivers/gpu/drm/drm_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand All @@ -209,50 +210,15 @@ 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)
drm_mm_put_block(align_splitoff);

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.
Expand Down
21 changes: 15 additions & 6 deletions include/drm/drm_mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 89579f7

Please sign in to comment.