Bug 10918
Summary: | 2.6.26-rc5: SLUB debug, lockdep warning... | ||
---|---|---|---|
Product: | Memory Management | Reporter: | Rafael J. Wysocki (rjw) |
Component: | Slab Allocator | Assignee: | Daniel J Blueman (daniel.blueman) |
Status: | CLOSED CODE_FIX | ||
Severity: | normal | CC: | daniel.blueman, tglx, vegard.nossum |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
Kernel Version: | 2.6.26-rc5 | Subsystem: | |
Regression: | Yes | Bisected commit-id: | |
Bug Depends on: | |||
Bug Blocks: | 10492 |
Description
Rafael J. Wysocki
2008-06-15 04:10:20 UTC
Probably caused by: commit 3ac7fe5a4aab409bd5674d0b070bce97f9d20872 Author: Thomas Gleixner <tglx@linutronix.de> Date: Wed Apr 30 00:55:01 2008 -0700 infrastructure to debug (dynamic) objects Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Greg KH <greg@kroah.com> Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Candidate fix that resolves the regression. Boot-tested on x86-64 and debugging. Signed-off-by: Daniel J Blueman <daniel.blueman@gmail.com> -> needs Vegard's SOB diff --git a/lib/debugobjects.c b/lib/debugobjects.c index a76a5e1..91109e8 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -66,6 +66,8 @@ static const char *obj_states[ODEBUG_STATE_MAX] = { static int fill_pool(void) { + unsigned long flags; + gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; struct debug_obj *new; @@ -81,10 +83,10 @@ static int fill_pool(void) if (!new) return obj_pool_free; - spin_lock(&pool_lock); + spin_lock_irqsave(&pool_lock, flags); hlist_add_head(&new->node, &obj_pool); obj_pool_free++; - spin_unlock(&pool_lock); + spin_unlock_irqrestore(&pool_lock, flags); } return obj_pool_free; } @@ -117,10 +119,9 @@ static struct debug_obj * alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) { struct debug_obj *obj = NULL; - int retry = 0; + unsigned long flags; -repeat: - spin_lock(&pool_lock); + spin_lock_irqsave(&pool_lock, flags); if (obj_pool.first) { obj = hlist_entry(obj_pool.first, typeof(*obj), node); @@ -139,10 +140,7 @@ repeat: if (obj_pool_free < obj_pool_min_free) obj_pool_min_free = obj_pool_free; } - spin_unlock(&pool_lock); - - if (fill_pool() && !obj && !retry++) - goto repeat; + spin_unlock_irqrestore(&pool_lock, flags); return obj; } @@ -153,17 +151,18 @@ repeat: static void free_object(struct debug_obj *obj) { unsigned long idx = (unsigned long)(obj - obj_static_pool); + unsigned long flags; if (obj_pool_free < ODEBUG_POOL_SIZE || idx < ODEBUG_POOL_SIZE) { - spin_lock(&pool_lock); + spin_lock_irqsave(&pool_lock, flags); hlist_add_head(&obj->node, &obj_pool); obj_pool_free++; obj_pool_used--; - spin_unlock(&pool_lock); + spin_unlock_irqrestore(&pool_lock, flags); } else { - spin_lock(&pool_lock); + spin_lock_irqsave(&pool_lock, flags); obj_pool_used--; - spin_unlock(&pool_lock); + spin_unlock_irqrestore(&pool_lock, flags); kmem_cache_free(obj_cache, obj); } } @@ -261,6 +260,8 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) struct debug_obj *obj; unsigned long flags; + fill_pool(); + db = get_bucket((unsigned long) addr); spin_lock_irqsave(&db->lock, flags); Regressions list annotation: Handled-By : "Daniel J Blueman" <daniel.blueman@gmail.com> Patch : http://bugzilla.kernel.org/show_bug.cgi?id=10918#c2 |