From 1f25b9850c71d59e91eb145057160fe6dee6465b Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Mon, 7 Jan 2008 23:20:31 -0800 Subject: [PATCH] SLUB: Restructure slab_alloc to flow in execution sequence Restructure slab_alloc so that the code flows in the sequence it is usually executed. Signed-off-by: Christoph Lameter Cc: Pekka Enberg Signed-off-by: Andrew Morton --- mm/slub.c | 40 ++++++++++++++++++++++++---------------- 1 files changed, 24 insertions(+), 16 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index f116edc..5649bf5 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1567,16 +1567,28 @@ static void *__slab_alloc(struct kmem_cache *s, local_irq_save(flags); preempt_enable_no_resched(); #endif - if (!c->page) - goto new_slab; + if (likely(c->page)) { + state = slab_lock(c->page); + + if (unlikely(node_match(c, node) && + c->page->freelist != c->page->end)) + goto load_freelist; + + deactivate_slab(s, c, state); + } + +another_slab: + state = get_partial(s, c, gfpflags, node); + if (!state) + goto grow_slab; - state = slab_lock(c->page); - if (unlikely(!node_match(c, node))) - goto another_slab; load_freelist: - object = c->page->freelist; - if (unlikely(object == c->page->end)) - goto another_slab; + /* + * slabs from the partial list must have at least + * one free object. + */ + VM_BUG_ON(c->page->freelist == c->page->end); + if (unlikely(state & SLABDEBUG)) goto debug; @@ -1594,20 +1606,16 @@ out: #endif return object; -another_slab: - deactivate_slab(s, c, state); - -new_slab: - state = get_partial(s, c, gfpflags, node); - if (state) - goto load_freelist; - +/* Extend the slabcache with a new slab */ +grow_slab: state = get_new_slab(s, &c, gfpflags, node); if (state) goto load_freelist; object = NULL; goto out; + +/* Perform debugging */ debug: object = c->page->freelist; if (!alloc_debug_processing(s, c->page, object, addr)) -- debian.1.5.3.7.1-dirty