lkml.org 
[lkml]   [2011]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: list corruption in the last few days. (block ? crypto ?)
Hi Linus,

On Sun, Aug 7, 2011 at 11:58 AM, Pekka Enberg <penberg@kernel.org> wrote:
>>
>> Christoph, I've been reading the code and spotted two potential issues in
>> __slab_free(). The first one seems like an off-by-one where our comparison
>> in deactivate_slab() doesn't match __slab_free.
>>
>> The other one is remove_full() call in __slab_free() that can get called
>> even if cache debugging is not enabled.
>>
>> Hmm?

On Sun, 7 Aug 2011, Linus Torvalds wrote:
> I'd like to do -rc1 today, regardless of whether this fixes things or
> not (-rc1 is already a few days delayed).
>
> The patch seems to be a good fix, and a likely candidate for the
> corruption. Commit log and sign-off? I assume you've given it some
> testing, even if you couldn't reproduce the original issue?

No, I haven't tested the patch myself but here's one in proper format in
case someone wants to test it.

Pekka

From 85380c605764927576d6ef54e4e8a3354df05d47 Mon Sep 17 00:00:00 2001
From: Pekka Enberg <penberg@kernel.org>
Date: Mon, 8 Aug 2011 07:56:49 +0300
Subject: [PATCH] slub: Fix partial and full list handling in __slab_free

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@redhat.com>
Reported-by: Xiaotian Feng <xtfeng@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
---
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


\
 
 \ /
  Last update: 2011-08-08 07:21    [from the cache]
©2003-2011 Jasper Spaans