summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Liu <lliubbo@gmail.com>2010-07-10 18:05:33 +0800
committerPekka Enberg <penberg@cs.helsinki.fi>2010-07-16 11:03:20 +0300
commitd602dabaeba79df90cc67c32d5fe4ee0d5e2b73a (patch)
tree7aa3b395f4c2934adde7b07a6678c347c84a7d35
parent1c5474a65bf15a4cb162dfff86d6d0b5a08a740c (diff)
SLOB: Free objects to their own list
SLOB has alloced smaller objects from their own list in reduce overall external fragmentation and increase repeatability, free to their own list also. This is /proc/meminfo result in my test machine: without this patch: === MemTotal: 1030720 kB MemFree: 750012 kB Buffers: 15496 kB Cached: 160396 kB SwapCached: 0 kB Active: 105024 kB Inactive: 145604 kB Active(anon): 74816 kB Inactive(anon): 2180 kB Active(file): 30208 kB Inactive(file): 143424 kB Unevictable: 16 kB .... with this patch: === MemTotal: 1030720 kB MemFree: 751908 kB Buffers: 15492 kB Cached: 160280 kB SwapCached: 0 kB Active: 102720 kB Inactive: 146140 kB Active(anon): 73168 kB Inactive(anon): 2180 kB Active(file): 29552 kB Inactive(file): 143960 kB Unevictable: 16 kB ... The result shows an improvement of 1 MB! And when I tested it on a embeded system with 64 MB, I found this path is never called during kernel bootup. Acked-by: Matt Mackall <mpm@selenic.com> Signed-off-by: Bob Liu <lliubbo@gmail.com> Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
-rw-r--r--mm/slob.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/mm/slob.c b/mm/slob.c
index 23631e2bb57a..6a208f81888a 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -394,6 +394,7 @@ static void slob_free(void *block, int size)
slob_t *prev, *next, *b = (slob_t *)block;
slobidx_t units;
unsigned long flags;
+ struct list_head *slob_list;
if (unlikely(ZERO_OR_NULL_PTR(block)))
return;
@@ -422,7 +423,13 @@ static void slob_free(void *block, int size)
set_slob(b, units,
(void *)((unsigned long)(b +
SLOB_UNITS(PAGE_SIZE)) & PAGE_MASK));
- set_slob_page_free(sp, &free_slob_small);
+ if (size < SLOB_BREAK1)
+ slob_list = &free_slob_small;
+ else if (size < SLOB_BREAK2)
+ slob_list = &free_slob_medium;
+ else
+ slob_list = &free_slob_large;
+ set_slob_page_free(sp, slob_list);
goto out;
}