diff options
author | Nick Piggin <nickpiggin@yahoo.com.au> | 2009-03-16 21:00:28 +1100 |
---|---|---|
committer | Pekka Enberg <penberg@cs.helsinki.fi> | 2009-03-23 10:40:45 +0200 |
commit | 6fb8f424393025674fde7869b59f485d1e352182 (patch) | |
tree | 1ba7de5a6c9cba9cf3c3e57b2355b56cb5eb670f /mm/slob.c | |
parent | b578f3fcca1e78624dfb5f358776e63711d7fda2 (diff) |
slob: fix lockup in slob_free()
Don't hold SLOB lock when freeing the page. Reduces lock hold width. See
the following thread for discussion of the bug:
http://marc.info/?l=linux-kernel&m=123709983214143&w=2
Reported-by: Ingo Molnar <mingo@elte.hu>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Diffstat (limited to 'mm/slob.c')
-rw-r--r-- | mm/slob.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/mm/slob.c b/mm/slob.c index bf7e8fc3aed8..f901653707a4 100644 --- a/mm/slob.c +++ b/mm/slob.c @@ -393,10 +393,11 @@ static void slob_free(void *block, int size) /* Go directly to page allocator. Do not pass slob allocator */ if (slob_page_free(sp)) clear_slob_page_free(sp); + spin_unlock_irqrestore(&slob_lock, flags); clear_slob_page(sp); free_slob_page(sp); free_page((unsigned long)b); - goto out; + return; } if (!slob_page_free(sp)) { |