From: Christoph Lameter Subject: slub: Var order slabs: Fix freeing of slabs Freeing of slabs assumed that slabs have maximum size. Signed-off-by: Christoph Lameter --- mm/slub.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2008-02-16 09:12:02.000000000 -0800 +++ linux-2.6/mm/slub.c 2008-02-16 09:14:38.000000000 -0800 @@ -1154,7 +1154,7 @@ out: static void __free_slab(struct kmem_cache *s, struct page *page) { - int pages = 1 << s->order; + int order = compound_order(page); if (unlikely(SlabDebug(page))) { void *p; @@ -1166,13 +1166,18 @@ static void __free_slab(struct kmem_cach ClearSlabDebug(page); } + reset_page_mapcount(page); + if (order) + /* mapcount of page + 1 was used for the object count */ + reset_page_mapcount(page + 1); + mod_zone_page_state(page_zone(page), (s->flags & SLAB_RECLAIM_ACCOUNT) ? NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, - -pages); + - (1 << order)); page->mapping = NULL; - __free_pages(page, s->order); + __free_pages(page, order); } static void rcu_free_slab(struct rcu_head *h) @@ -1202,10 +1207,6 @@ static void discard_slab(struct kmem_cac atomic_long_dec(&n->nr_slabs); atomic_long_sub(slab_objects(s, page), &n->total_objects); - reset_page_mapcount(page); - if (PageCompound(page)) - /* mapcount of page + 1 was used for the object count */ - reset_page_mapcount(page + 1); __ClearPageSlab(page); free_slab(s, page); }