[3.8.y.z extended stable] Patch "mm: __set_page_dirty uses spin_lock_irqsave instead of spin_lock_irq" has been added to staging queue
Kamal Mostafa
kamal at canonical.com
Thu Feb 20 21:38:20 UTC 2014
This is a note to let you know that I have just added a patch titled
mm: __set_page_dirty uses spin_lock_irqsave instead of spin_lock_irq
to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree
which can be found at:
http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue
This patch is scheduled to be released in version 3.8.13.19.
If you, or anyone else, feels it should not be added to this tree, please
reply to this email.
For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
Thanks.
-Kamal
------
>From 016ad67cb57295c6fd1654ac529b11dacc7f35d3 Mon Sep 17 00:00:00 2001
From: KOSAKI Motohiro <kosaki.motohiro at jp.fujitsu.com>
Date: Thu, 6 Feb 2014 12:04:28 -0800
Subject: mm: __set_page_dirty uses spin_lock_irqsave instead of spin_lock_irq
commit 227d53b397a32a7614667b3ecaf1d89902fb6c12 upstream.
To use spin_{un}lock_irq is dangerous if caller disabled interrupt.
During aio buffer migration, we have a possibility to see the following
call stack.
aio_migratepage [disable interrupt]
migrate_page_copy
clear_page_dirty_for_io
set_page_dirty
__set_page_dirty_buffers
__set_page_dirty
spin_lock_irq
This mean, current aio migration is a deadlockable. spin_lock_irqsave
is a safer alternative and we should use it.
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro at jp.fujitsu.com>
Reported-by: David Rientjes rientjes at google.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
fs/buffer.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/buffer.c b/fs/buffer.c
index 7a75c3e..1ab9a41 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -612,14 +612,16 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
static void __set_page_dirty(struct page *page,
struct address_space *mapping, int warn)
{
- spin_lock_irq(&mapping->tree_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mapping->tree_lock, flags);
if (page->mapping) { /* Race with truncate? */
WARN_ON_ONCE(warn && !PageUptodate(page));
account_page_dirtied(page, mapping);
radix_tree_tag_set(&mapping->page_tree,
page_index(page), PAGECACHE_TAG_DIRTY);
}
- spin_unlock_irq(&mapping->tree_lock);
+ spin_unlock_irqrestore(&mapping->tree_lock, flags);
__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
}
--
1.8.3.2
More information about the kernel-team
mailing list