lkml.org 
[lkml]   [2014]   [Feb]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.13 23/40] mm: __set_page_dirty_nobuffers() uses spin_lock_irqsave() instead of spin_lock_irq()
    Date
    3.13-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>

    commit a85d9df1ea1d23682a0ed1e100e6965006595d06 upstream.

    During aio stress test, we observed the following lockdep warning. This
    mean AIO+numa_balancing is currently deadlockable.

    The problem is, aio_migratepage disable interrupt, but
    __set_page_dirty_nobuffers unintentionally enable it again.

    Generally, all helper function should use spin_lock_irqsave() instead of
    spin_lock_irq() because they don't know caller at all.

    other info that might help us debug this:
    Possible unsafe locking scenario:

    CPU0
    ----
    lock(&(&ctx->completion_lock)->rlock);
    <Interrupt>
    lock(&(&ctx->completion_lock)->rlock);

    *** DEADLOCK ***

    dump_stack+0x19/0x1b
    print_usage_bug+0x1f7/0x208
    mark_lock+0x21d/0x2a0
    mark_held_locks+0xb9/0x140
    trace_hardirqs_on_caller+0x105/0x1d0
    trace_hardirqs_on+0xd/0x10
    _raw_spin_unlock_irq+0x2c/0x50
    __set_page_dirty_nobuffers+0x8c/0xf0
    migrate_page_copy+0x434/0x540
    aio_migratepage+0xb1/0x140
    move_to_new_page+0x7d/0x230
    migrate_pages+0x5e5/0x700
    migrate_misplaced_page+0xbc/0xf0
    do_numa_page+0x102/0x190
    handle_pte_fault+0x241/0x970
    handle_mm_fault+0x265/0x370
    __do_page_fault+0x172/0x5a0
    do_page_fault+0x1a/0x70
    page_fault+0x28/0x30

    Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Cc: Larry Woodman <lwoodman@redhat.com>
    Cc: Rik van Riel <riel@redhat.com>
    Cc: Johannes Weiner <jweiner@redhat.com>
    Acked-by: David Rientjes <rientjes@google.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    mm/page-writeback.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    --- a/mm/page-writeback.c
    +++ b/mm/page-writeback.c
    @@ -2173,11 +2173,12 @@ int __set_page_dirty_nobuffers(struct pa
    if (!TestSetPageDirty(page)) {
    struct address_space *mapping = page_mapping(page);
    struct address_space *mapping2;
    + unsigned long flags;

    if (!mapping)
    return 1;

    - spin_lock_irq(&mapping->tree_lock);
    + spin_lock_irqsave(&mapping->tree_lock, flags);
    mapping2 = page_mapping(page);
    if (mapping2) { /* Race with truncate? */
    BUG_ON(mapping2 != mapping);
    @@ -2186,7 +2187,7 @@ int __set_page_dirty_nobuffers(struct pa
    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);
    if (mapping->host) {
    /* !PageAnon && !swapper_space */
    __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);



    \
     
     \ /
      Last update: 2014-02-19 15:41    [W:4.147 / U:0.232 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site