]> git.neil.brown.name Git - history.git/commitdiff
[SPARC32]: Reduce fragmentation in the bitmap allocator
authorKeith M. Wesolowski <wesolows@foobazco.org>
Mon, 3 May 2004 16:11:44 +0000 (09:11 -0700)
committerKeith M. Wesolowski <wesolows@foobazco.org>
Mon, 3 May 2004 16:11:44 +0000 (09:11 -0700)
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.

arch/sparc/lib/bitext.c
include/asm-sparc/bitext.h

index 7f1bf90bb92c8957de9487da39d8ddd2ab01c966..f375c8e361dfe0d4bac0ac1093260811780613aa 100644 (file)
@@ -42,7 +42,10 @@ int bit_map_string_get(struct bit_map *t, int len, int align)
                BUG();
 
        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;
        for (;;) {
                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)
                        if (i == len) {
                                for (i = 0; i < len; i++)
                                        __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)
                                        t->last_off = 0;
                                t->used += len;
+                               t->last_size = len;
                                spin_unlock(&t->lock);
                                return offset;
                        }
@@ -96,6 +104,8 @@ void bit_map_clear(struct bit_map *t, int offset, int len)
                        BUG();
                __clear_bit(offset + i, t->map);
        }
+       if (offset < t->first_free)
+               t->first_free = offset;
        t->used -= len;
        spin_unlock(&t->lock);
 }
@@ -111,4 +121,6 @@ void bit_map_init(struct bit_map *t, unsigned long *map, int size)
        spin_lock_init(&t->lock);
        t->map = map;
        t->size = size;
+       t->last_size = 0;
+       t->first_free = 0;
 }
index b589241b5bfa3e648649f8730ce49d0d6142f553..a9cd154d620692e66e8b52bed745de1600d627ce 100644 (file)
@@ -15,6 +15,8 @@ struct bit_map {
        int size;
        int used;
        int last_off;
+       int last_size;
+       int first_free;
 };
 
 extern int bit_map_string_get(struct bit_map *t, int len, int align);