Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2007-10-25 12:48:32.000000000 -0700 +++ linux-2.6/mm/slub.c 2007-10-25 12:57:19.000000000 -0700 @@ -1255,7 +1255,8 @@ * * Must hold list_lock. */ -static inline int lock_and_freeze_slab(struct kmem_cache_node *n, struct page *page) +static inline unsigned long lock_and_freeze_slab(struct kmem_cache_node *n, + struct kmem_cache_cpu *c, struct page *page) { unsigned long state; @@ -1263,8 +1264,8 @@ if (state) { list_del(&page->lru); n->nr_partial--; - page->flags = state | FROZEN | LOCKED; - return 1; + c->page = page; + return state | FROZEN; } return 0; } @@ -1272,9 +1273,11 @@ /* * Try to allocate a partial slab from a specific node. */ -static struct page *get_partial_node(struct kmem_cache_node *n) +static unsigned long get_partial_node(struct kmem_cache_node *n, + struct kmem_cache_cpu *c) { struct page *page; + unsigned long state; /* * Racy check. If we mistakenly see no partial slabs then we @@ -1283,27 +1286,30 @@ * will return NULL. */ if (!n || !n->nr_partial) - return NULL; + return 0; spin_lock(&n->list_lock); - list_for_each_entry(page, &n->partial, lru) - if (lock_and_freeze_slab(n, page)) + list_for_each_entry(page, &n->partial, lru) { + state = lock_and_freeze_slab(n, c, page); + if (state) goto out; - page = NULL; + } + state = 0; out: spin_unlock(&n->list_lock); - return page; + return state; } /* * Get a page from somewhere. Search in increasing NUMA distances. */ -static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags) +static unsigned long get_any_partial(struct kmem_cache *s, + struct kmem_cache_cpu *c, gfp_t flags) { #ifdef CONFIG_NUMA struct zonelist *zonelist; struct zone **z; - struct page *page; + unsigned long state; /* * The defrag ratio allows a configuration of the tradeoffs between @@ -1335,13 +1341,13 @@ if (n && cpuset_zone_allowed_hardwall(*z, flags) && n->nr_partial > MIN_PARTIAL) { - page = get_partial_node(n); - if (page) - return page; + state = get_partial_node(n, c); + if (state) + return state; } } #endif - return NULL; + return 0; } /* @@ -1350,16 +1356,15 @@ static noinline unsigned long get_partial(struct kmem_cache *s, struct kmem_cache_cpu *c, gfp_t flags, int node) { - struct page *page; + unsigned long state; int searchnode = (node == -1) ? numa_node_id() : node; - page = get_partial_node(get_node(s, searchnode)); - if (!page && !(flags & __GFP_THISNODE)) - page = get_any_partial(s, flags); - if (!page) + state = get_partial_node(get_node(s, searchnode), c); + if (!state && !(flags & __GFP_THISNODE)) + state = get_any_partial(s, c, flags); + if (!state) return 0; - c->page = page; - return page->flags & ~LOCKED; + return state; } /*