lkml.org 
[lkml]   [2019]   [Oct]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 084/112] btrfs: allocate new inode in NOFS context
    Date
    From: Josef Bacik <josef@toxicpanda.com>

    commit 11a19a90870ea5496a8ded69b86f5b476b6d3355 upstream.

    A user reported a lockdep splat

    ======================================================
    WARNING: possible circular locking dependency detected
    5.2.11-gentoo #2 Not tainted
    ------------------------------------------------------
    kswapd0/711 is trying to acquire lock:
    000000007777a663 (sb_internal){.+.+}, at: start_transaction+0x3a8/0x500

    but task is already holding lock:
    000000000ba86300 (fs_reclaim){+.+.}, at: __fs_reclaim_acquire+0x0/0x30

    which lock already depends on the new lock.

    the existing dependency chain (in reverse order) is:

    -> #1 (fs_reclaim){+.+.}:
    kmem_cache_alloc+0x1f/0x1c0
    btrfs_alloc_inode+0x1f/0x260
    alloc_inode+0x16/0xa0
    new_inode+0xe/0xb0
    btrfs_new_inode+0x70/0x610
    btrfs_symlink+0xd0/0x420
    vfs_symlink+0x9c/0x100
    do_symlinkat+0x66/0xe0
    do_syscall_64+0x55/0x1c0
    entry_SYSCALL_64_after_hwframe+0x49/0xbe

    -> #0 (sb_internal){.+.+}:
    __sb_start_write+0xf6/0x150
    start_transaction+0x3a8/0x500
    btrfs_commit_inode_delayed_inode+0x59/0x110
    btrfs_evict_inode+0x19e/0x4c0
    evict+0xbc/0x1f0
    inode_lru_isolate+0x113/0x190
    __list_lru_walk_one.isra.4+0x5c/0x100
    list_lru_walk_one+0x32/0x50
    prune_icache_sb+0x36/0x80
    super_cache_scan+0x14a/0x1d0
    do_shrink_slab+0x131/0x320
    shrink_node+0xf7/0x380
    balance_pgdat+0x2d5/0x640
    kswapd+0x2ba/0x5e0
    kthread+0x147/0x160
    ret_from_fork+0x24/0x30

    other info that might help us debug this:

    Possible unsafe locking scenario:

    CPU0 CPU1
    ---- ----
    lock(fs_reclaim);
    lock(sb_internal);
    lock(fs_reclaim);
    lock(sb_internal);
    ---
    fs/btrfs/inode.c | 3 +++
    1 file changed, 3 insertions(+)

    --- a/fs/btrfs/inode.c
    +++ b/fs/btrfs/inode.c
    @@ -6276,13 +6276,16 @@ static struct inode *btrfs_new_inode(str
    u32 sizes[2];
    int nitems = name ? 2 : 1;
    unsigned long ptr;
    + unsigned int nofs_flag;
    int ret;

    path = btrfs_alloc_path();
    if (!path)
    return ERR_PTR(-ENOMEM);

    + nofs_flag = memalloc_nofs_save();
    inode = new_inode(fs_info->sb);
    + memalloc_nofs_restore(nofs_flag);
    if (!inode) {
    btrfs_free_path(path);
    return ERR_PTR(-ENOMEM);

    \
     
     \ /
      Last update: 2019-10-17 00:00    [W:4.159 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site