--- mm/slub.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2008-04-02 18:58:09.723765947 -0700 +++ linux-2.6/mm/slub.c 2008-04-02 18:58:24.288074518 -0700 @@ -2903,17 +2903,23 @@ int kmem_cache_reclaim(struct list_head * slabs with less than a quarter of objects allocated. */ static unsigned long __kmem_cache_shrink(struct kmem_cache *s, - struct kmem_cache_node *n) + int node, unsigned long limit) { unsigned long flags; struct page *page, *page2; LIST_HEAD(zaplist); int freed = 0; + struct kmem_cache_node *n = get_node(s, node); + if (n->nr_partial <= limit) + return 0; spin_lock_irqsave(&n->list_lock, flags); list_for_each_entry_safe(page, page2, &n->partial, lru) { - if (page->inuse > page->objects / 4 || - (s->kick && !SlabKickable(page))) + if (s->kick && !SlabKickable(page)) + continue; + + if (page->inuse * 100 >= + s->defrag_ratio * page->objects) continue; if (!slab_trylock(page))