--- mm/slub.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2007-11-18 15:12:50.429806426 -0800 +++ linux-2.6/mm/slub.c 2007-11-18 15:21:49.160056311 -0800 @@ -1485,10 +1485,10 @@ static void flush_all(struct kmem_cache * Check if the objects in a per cpu structure fit numa * locality expectations. */ -static inline int node_match(struct kmem_cache_cpu *c, int node) +static inline int node_match(int cnode, int node) { #ifdef CONFIG_NUMA - if (node != -1 && c->node != node) + if (node != -1 && cnode != node) return 0; #endif return 1; @@ -1537,20 +1537,22 @@ static noinline unsigned long get_new_sl * we need to allocate a new slab. This is slowest path since we may sleep. */ static void *__slab_alloc(struct kmem_cache *s, - gfp_t gfpflags, int node, void *addr, struct kmem_cache_cpu *c) + gfp_t gfpflags, int node, void *addr) { void **object; unsigned long state; + struct kmem_cache_cpu *c; #ifdef CONFIG_FAST_CMPXCHG_LOCAL unsigned long flags; local_irq_save(flags); preempt_enable_no_resched(); #endif + c = THIS_CPU(s->cpu_slab); if (likely(c->page)) { state = slab_lock(c->page); - if (unlikely(node_match(c, node) && + if (unlikely(node_match(c->node, node) && c->page->freelist != c->page->end)) goto load_freelist; @@ -1624,21 +1626,18 @@ static void __always_inline *slab_alloc( struct kmem_cache_cpu *c; #ifdef CONFIG_FAST_CMPXCHG_LOCAL - preempt_disable(); - c = THIS_CPU(s->cpu_slab); + c = s->cpu_slab; do { - object = c->freelist; - if (unlikely(is_end(object) || !node_match(c, node))) { - object = __slab_alloc(s, gfpflags, node, addr, c); - if (unlikely(!object)) { - preempt_enable(); + object = __CPU_READ(c->freelist); + if (unlikely(is_end(object) || + !node_match(__CPU_READ(c->node), node))) { + object = __slab_alloc(s, gfpflags, node, addr); + if (unlikely(!object)) goto out; - } break; } - } while (cmpxchg_local(&c->freelist, object, object[c->offset]) - != object); - preempt_enable(); + } while (CPU_CMPXCHG(c->freelist, object, + object[__CPU_READ(c->offset)]) != object); #else unsigned long flags; @@ -1768,11 +1767,10 @@ static void __always_inline slab_free(st #ifdef CONFIG_FAST_CMPXCHG_LOCAL void **freelist; - preempt_disable(); - c = THIS_CPU(s->cpu_slab); + c = s->cpu_slab; debug_check_no_locks_freed(object, s->objsize); do { - freelist = c->freelist; + freelist = __CPU_READ(c->freelist); barrier(); /* * If the compiler would reorder the retrieval of c->page to @@ -1785,13 +1783,13 @@ static void __always_inline slab_free(st * then any change of cpu_slab will cause the cmpxchg to fail * since the freelist pointers are unique per slab. */ - if (unlikely(page != c->page || c->node < 0)) { + if (unlikely(page != __CPU_READ(c->page) || + __CPU_READ(c->node) < 0)) { __slab_free(s, page, x, addr, c->offset); break; } object[c->offset] = freelist; - } while (cmpxchg_local(&c->freelist, freelist, object) != freelist); - preempt_enable(); + } while (CPU_CMPXCHG(c->freelist, freelist, object) != freelist); #else unsigned long flags;