diff options
author | Nick Piggin <nickpiggin@yahoo.com.au> | 2009-03-16 06:00:28 -0400 |
---|---|---|
committer | Pekka Enberg <penberg@cs.helsinki.fi> | 2009-03-23 04:40:45 -0400 |
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
@@ -393,10 +393,11 @@ static void slob_free(void *block, int size) | |||
393 | /* Go directly to page allocator. Do not pass slob allocator */ | 393 | /* Go directly to page allocator. Do not pass slob allocator */ |
394 | if (slob_page_free(sp)) | 394 | if (slob_page_free(sp)) |
395 | clear_slob_page_free(sp); | 395 | clear_slob_page_free(sp); |
396 | spin_unlock_irqrestore(&slob_lock, flags); | ||
396 | clear_slob_page(sp); | 397 | clear_slob_page(sp); |
397 | free_slob_page(sp); | 398 | free_slob_page(sp); |
398 | free_page((unsigned long)b); | 399 | free_page((unsigned long)b); |
399 | goto out; | 400 | return; |
400 | } | 401 | } |
401 | 402 | ||
402 | if (!slob_page_free(sp)) { | 403 | if (!slob_page_free(sp)) { |