Subject : 2.6.26-rc5: SLUB debug, lockdep warning... Submitter : "Daniel J Blueman" <daniel.blueman@gmail.com> Date : 2008-06-14 10:54 References : http://marc.info/?l=linux-kernel&m=121344091109597&w=4 Handled-By : "Vegard Nossum" <vegard.nossum@gmail.com> This entry is being used for tracking a regression from 2.6.25. Please don't close it until the problem is fixed in the mainline.
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
Fix committed: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=70c85057e0bde35eb56352a293ecb5d1641a0334;hp=e6100f23375c0c71ce595d04551fa6553b611918