Index: linux-2.6.18-rc4-mm3/mm/slabifier.c =================================================================== --- linux-2.6.18-rc4-mm3.orig/mm/slabifier.c 2006-08-31 17:12:40.421159561 -0700 +++ linux-2.6.18-rc4-mm3/mm/slabifier.c 2006-08-31 17:47:18.063247515 -0700 @@ -472,10 +472,10 @@ static __always_inline void *__slab_allo slab_lock(page); if (unlikely(!page->freelist)) - goto full_slab; + goto another_slab; if (unlikely(node != -1 && page_to_nid(page) != node)) - goto full_slab; + goto another_slab; redo: page->inuse++; object = page->freelist; @@ -486,13 +486,13 @@ redo: local_irq_restore(flags); return object; -full_slab: +another_slab: deactivate_slab(s, page, cpu); new_slab: /* * This was moved out of line since it dereferences s and thus - * touches an extra cacheline + * potentially touches an extra cacheline */ if (unlikely(s->objects == 1)) { local_irq_restore(flags); @@ -558,20 +558,6 @@ static void *slab_alloc_node(struct slab #endif } -/* Figure out on which slab object the object resides */ -static __always_inline struct page *get_object_page(const void *x) -{ - struct page * page = virt_to_page(x); - - if (unlikely(PageCompound(page))) - page = page->first_page; - - if (!PageSlab(page)) - return NULL; - - return page; -} - static void slab_free(struct slab_cache *sc, const void *x) { struct slab *s = (void *)sc; @@ -585,20 +571,21 @@ static void slab_free(struct slab_cache page = virt_to_page(x); + if (!s) + s = (void *)page->slab; + if (unlikely(PageCompound(page))) page = page->first_page; - if (unlikely(!PageSlab(page))) - goto bad_slab; - - if (unlikely(sc != page->slab)) - goto slab_mismatch; -redo: if (unlikely(PageSlabsingle(page))) goto single_object_slab; +#ifdef SLABIFIER_DEBUG + if (unlikely(sc != page->slab)) + goto slab_mismatch; if (unlikely(!check_valid_pointer(s, page, object, NULL))) goto dumpret; +#endif local_irq_save(flags); slab_lock(page); @@ -638,8 +625,6 @@ out_unlock: local_irq_restore(flags); return; - - single_object_slab: discard_slab(s, page); return; @@ -650,18 +635,15 @@ double_free: s->sc.name, object); dump_stack(); goto out_unlock; -#endif - -bad_slab: - printk(KERN_CRIT "slab_free %s size %d: attempt to free object" - "(%p) outside of slab.\n", s->sc.name, s->size, object); -dumpret: - dump_stack(); - printk(KERN_CRIT "***** Trying to continue by not" - "freeing object.\n"); - return; slab_mismatch: + if (unlikely(!PageSlab(page))) { + printk(KERN_CRIT "slab_free %s size %d: attempt to free " + "object(%p) outside of slab.\n", + s->sc.name, s->size, object); + goto dumpret; + } + if (unlikely(!page->slab)) { printk(KERN_CRIT "slab_free : no slab(NULL) for object %p.\n", @@ -669,16 +651,30 @@ slab_mismatch: goto dumpret; } - if (s) { - printk(KERN_CRIT "slab_free %s: object at %p" - " belongs to slab %s\n", - s->sc.name, object, page->slab->name); - dump_stack(); - } - sc = page->slab; - s = (void *) sc; - goto redo; + printk(KERN_CRIT "slab_free %s: object at %p" + " belongs to slab %s\n", + s->sc.name, object, page->slab->name); +dumpret: + dump_stack(); + printk(KERN_CRIT "***** Trying to continue by not" + "freeing object.\n"); + return; +#endif +} + +/* Figure out on which slab object the object resides */ +static __always_inline struct page *get_object_page(const void *x) +{ + struct page * page = virt_to_page(x); + + if (unlikely(PageCompound(page))) + page = page->first_page; + + if (!PageSlab(page)) + return NULL; + + return page; } /* @@ -828,15 +824,21 @@ static struct slab_cache *slab_dup(struc return &s->sc; } -static void free_list(struct slab *s, struct list_head *list) +static int free_list(struct slab *s, struct list_head *list) { + int slabs_inuse = 0; unsigned long flags; + struct page *page, *h; spin_lock_irqsave(&s->list_lock, flags); - while (!list_empty(list)) - discard_slab(s, lru_to_last_page(list)); + list_for_each_entry_safe(page, h, list, lru) + if (!page->inuse) + discard_slab(s, lru_to_last_page(list)); + else + slabs_inuse++; spin_unlock_irqrestore(&s->list_lock, flags); + return slabs_inuse; } static int slab_destroy(struct slab_cache *sc)