Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2007-10-23 02:11:25.000000000 -0700 +++ linux-2.6/mm/slub.c 2007-10-23 02:21:31.000000000 -0700 @@ -1166,26 +1166,10 @@ free_slab(s, page); } +#ifdef CONFIG_FAST_CMPXCHG_LOCAL /* * Per slab locking using the pagelock */ -static __always_inline unsigned long slab_lock(struct page *page) -{ - unsigned long state; - - preempt_disable(); -#ifdef CONFIG_SMP - do { - state = page->flags; - } while (cmpxchg(&page->flags, state, - state | LOCKED) != state); -#else - state = page->flags; -#endif - __acquire(bitlock); - return state; -} - static __always_inline void slab_unlock(struct page *page, unsigned long state) { @@ -1210,6 +1194,31 @@ __acquire(bitlock); return state; } +#else +static __always_inline void slab_unlock(struct page *page, + unsigned long state) +{ + page->flags = state; + __bit_spin_unlock(PG_locked, &page->flags); +} + +static __always_inline unsigned long slab_trylock(struct page *page) +{ + if (!bit_spin_trylock(PG_locked, &page->flags)) + return 0; + return page->flags; +} +#endif + +static __always_inline unsigned long slab_lock(struct page *page) +{ + unsigned long state; + + do { + state = slab_trylock(page); + } while (!state); + return state; +} /* * Management of partially allocated slabs