Index: linux-2.6.18-rc5-mm1/mm/slabifier.c =================================================================== --- linux-2.6.18-rc5-mm1.orig/mm/slabifier.c 2006-09-02 13:27:24.799157503 -0700 +++ linux-2.6.18-rc5-mm1/mm/slabifier.c 2006-09-02 14:19:54.813743981 -0700 @@ -121,6 +121,9 @@ static struct page *get_partial(struct s struct page *page; int searchnode = (node == -1) ? numa_node_id() : node; + if (!s->nr_partial) + return NULL; + spin_lock(&s->list_lock); /* * Search for slab on the right node @@ -151,6 +154,13 @@ static struct page *get_partial(struct s { struct page *page; + /* Racy check. If we mistakenly see no partial slabs then we + * just allocate an empty slab. If we mistakenly try to get a + * partial slab then get_partials() will return NULL. + */ + if (!s->nr_partial) + return NULL; + spin_lock(&s->list_lock); list_for_each_entry(page, &s->partial, lru) if (likely(lock_and_del_slab(s, page))) @@ -459,36 +469,25 @@ another_slab: deactivate_slab(s, page, cpu); new_slab: - /* - * This was moved out of line since it dereferences s and thus - * potentially touches an extra cacheline - */ - if (unlikely(s->objects == 1)) { - page = new_slab(s, gfpflags, node); - local_irq_restore(flags); - if (page) - return page_address(page); - else - return NULL; - } - - /* Racy check. If we mistakenly see no partial slabs then we - * just allocate an empty slab. If we mistakenly try to get a - * partial slab then get_partials() will return NULL. - */ - if (s->nr_partial) { - page = get_partial(s, node); - if (page) - goto gotpage; - } + page = get_partial(s, node); + if (page) + goto gotpage; page = new_slab(s, flags, node); - if (!page) { local_irq_restore(flags); return NULL; } + /* + * There is no point in putting single object slabs + * on an active list. + */ + if (unlikely(s->objects == 1)) { + local_irq_restore(flags); + return page_address(page); + } + slab_lock(page); gotpage: @@ -548,9 +547,6 @@ void slab_free(struct slab_cache *sc, co if (!s) s = (void *)page->slab; - if (unlikely(PageSlabsingle(page))) - goto single_object_slab; - #ifdef SLABIFIER_DEBUG if (unlikely(s != (void *)page->slab)) goto slab_mismatch; @@ -559,6 +555,8 @@ void slab_free(struct slab_cache *sc, co #endif local_irq_save(flags); + if (unlikely(PageSlabsingle(page))) + goto single_object_slab; slab_lock(page); #ifdef SLABIFIER_DEBUG @@ -591,12 +589,9 @@ out_unlock: */ remove_partial(s, page); slab_unlock(page); - discard_slab(s, page); - local_irq_restore(flags); - return; - single_object_slab: discard_slab(s, page); + local_irq_restore(flags); return; #ifdef SLABIFIER_DEBUG