--- mm/slub.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2007-10-18 13:31:20.000000000 -0700 +++ linux-2.6/mm/slub.c 2007-10-18 13:31:28.000000000 -0700 @@ -196,6 +196,8 @@ static inline void ClearSlabDebug(struct /* Enable to test recovery from slab corruption on boot */ #undef SLUB_RESILIENCY_TEST +#define SLUB_ATOMIC + #if PAGE_SHIFT <= 12 /* @@ -1261,6 +1263,7 @@ static void discard_slab(struct kmem_cac free_slab(s, page); } +#ifndef SLUB_ATOMIC /* * Per slab locking using the pagelock */ @@ -1281,6 +1284,7 @@ static __always_inline int slab_trylock( rc = bit_spin_trylock(PG_locked, &page->flags); return rc; } +#endif /* * Management of partially allocated slabs @@ -1440,11 +1444,20 @@ static inline void **free_object(struct { void **prior; +#ifdef SLUB_ATOMIC + do { + prior = page->freelist; + object[offset] = prior; + } while (cmpxchg(&page->freelist, prior, object) != prior); + +#else slab_lock(page); prior = page->freelist; object[offset] = prior; page->freelist = object; slab_unlock(page); +#endif + return prior; } @@ -1455,11 +1468,19 @@ static inline void **alloc_object(struct { void **object; +#ifdef SLUB_ATOMIC + do { + object = page->freelist; + if (!object) + return NULL; + } while (cmpxchg(&page->freelist, object, object[offset]) != object); +#else slab_lock(page); object = page->freelist; if (object) page->freelist = object[offset]; slab_unlock(page); +#endif return object; } @@ -1470,10 +1491,14 @@ static inline void **get_freelist(struct { void **list; +#ifdef SLUB_ATOMIC + list = xchg(&page->freelist, NULL); +#else slab_lock(page); list = page->freelist; page->freelist = NULL; slab_unlock(page); +#endif return list; } @@ -1482,9 +1507,17 @@ static inline void **free_cpu_object(str { void **prior; +#ifdef SLUB_ATOMIC + do { + prior = c->freelist; + object[c->offset] = prior; + } while (cmpxchg_local(&c->freelist, prior, object) != prior); + +#else prior = c->freelist; object[c->offset] = prior; c->freelist = object; +#endif return prior; } @@ -1495,9 +1528,17 @@ static inline void **alloc_cpu_object(st { void **object; +#ifdef SLUB_ATOMIC + do { + object = c->freelist; + if (!object) + return NULL; + } while (cmpxchg_local(&c->freelist, object, object[c->offset]) != object); +#else object = c->freelist; if (object) c->freelist = object[c->offset]; +#endif return object; }