Commit c3247afe authored by Keith M. Wesolowski's avatar Keith M. Wesolowski

[SPARC32]: Reduce fragmentation in the bitmap allocator

The existing allocator is first-fit with wraparound.  This allows
a large number of small holes to accumulate in the early part of the
region, leading to heavy fragmentation.  This adjusts the algorithm
to rescan the region when smaller sizes are requested, reducing
early fragmentation.
parent 8928a30a
...@@ -42,7 +42,10 @@ int bit_map_string_get(struct bit_map *t, int len, int align) ...@@ -42,7 +42,10 @@ int bit_map_string_get(struct bit_map *t, int len, int align)
BUG(); BUG();
spin_lock(&t->lock); spin_lock(&t->lock);
offset = t->last_off & ~align1; if (len < t->last_size)
offset = t->first_free;
else
offset = t->last_off & ~align1;
count = 0; count = 0;
for (;;) { for (;;) {
off_new = find_next_zero_bit(t->map, t->size, offset); off_new = find_next_zero_bit(t->map, t->size, offset);
...@@ -71,9 +74,14 @@ int bit_map_string_get(struct bit_map *t, int len, int align) ...@@ -71,9 +74,14 @@ int bit_map_string_get(struct bit_map *t, int len, int align)
if (i == len) { if (i == len) {
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
__set_bit(offset + i, t->map); __set_bit(offset + i, t->map);
if (offset == t->first_free)
t->first_free = find_next_zero_bit
(t->map, t->size,
t->first_free + len);
if ((t->last_off = offset + len) >= t->size) if ((t->last_off = offset + len) >= t->size)
t->last_off = 0; t->last_off = 0;
t->used += len; t->used += len;
t->last_size = len;
spin_unlock(&t->lock); spin_unlock(&t->lock);
return offset; return offset;
} }
...@@ -96,6 +104,8 @@ void bit_map_clear(struct bit_map *t, int offset, int len) ...@@ -96,6 +104,8 @@ void bit_map_clear(struct bit_map *t, int offset, int len)
BUG(); BUG();
__clear_bit(offset + i, t->map); __clear_bit(offset + i, t->map);
} }
if (offset < t->first_free)
t->first_free = offset;
t->used -= len; t->used -= len;
spin_unlock(&t->lock); spin_unlock(&t->lock);
} }
...@@ -111,4 +121,6 @@ void bit_map_init(struct bit_map *t, unsigned long *map, int size) ...@@ -111,4 +121,6 @@ void bit_map_init(struct bit_map *t, unsigned long *map, int size)
spin_lock_init(&t->lock); spin_lock_init(&t->lock);
t->map = map; t->map = map;
t->size = size; t->size = size;
t->last_size = 0;
t->first_free = 0;
} }
...@@ -15,6 +15,8 @@ struct bit_map { ...@@ -15,6 +15,8 @@ struct bit_map {
int size; int size;
int used; int used;
int last_off; int last_off;
int last_size;
int first_free;
}; };
extern int bit_map_string_get(struct bit_map *t, int len, int align); extern int bit_map_string_get(struct bit_map *t, int len, int align);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment