[PATCH] slub: Fix partial and full list handling in __slab_free

From: Pekka Enberg
Date: Mon Aug 08 2011 - 00:56:49 EST


Dave Jones and Xiaotian Feng reported SLUB list corruption:

https://lkml.org/lkml/2011/8/4/375

https://lkml.org/lkml/2011/8/3/37

While I haven't able to reproduce the issue, I spotted two problems in
__slab_free() during code review:

- The ->nr_partial check in __slab_free() has an off-by-one bug
when compared to similar check in deactivate_slab()

- remove_full() is called even if cache debugging has not been enabled

Reported-by: Dave Jones <davej@xxxxxxxxxx>
Reported-by: Xiaotian Feng <xtfeng@xxxxxxxxx>
Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxx>
---
mm/slub.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index eb5a8f9..cee8c20 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2368,7 +2368,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
if (was_frozen)
stat(s, FREE_FROZEN);
else {
- if (unlikely(!inuse && n->nr_partial > s->min_partial))
+ if (unlikely(!inuse && n->nr_partial >= s->min_partial))
goto slab_empty;

/*
@@ -2376,7 +2376,8 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
* then add it.
*/
if (unlikely(!prior)) {
- remove_full(s, page);
+ if (kmem_cache_debug(s))
+ remove_full(s, page);
add_partial(n, page, 0);
stat(s, FREE_ADD_PARTIAL);
}
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/