• J
    nfs4: queue free_lock_state job submission to nfsiod · 49a4bda2
    Jeff Layton 提交于
    We got a report of the following warning in Fedora:
    
    BUG: sleeping function called from invalid context at mm/slub.c:969
    in_atomic(): 1, irqs_disabled(): 0, pid: 533, name: bash
    3 locks held by bash/533:
     #0:  (&sp->so_delegreturn_mutex){+.+...}, at: [<ffffffffa033da62>] nfs4_proc_lock+0x262/0x910 [nfsv4]
     #1:  (&nfsi->rwsem){.+.+.+}, at: [<ffffffffa033da6a>] nfs4_proc_lock+0x26a/0x910 [nfsv4]
     #2:  (&sb->s_type->i_lock_key#23){+.+...}, at: [<ffffffff812998dc>] flock_lock_file_wait+0x8c/0x3a0
    CPU: 0 PID: 533 Comm: bash Not tainted 3.15.0-0.rc1.git1.1.fc21.x86_64 #1
    Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
     0000000000000000 00000000d664ff3c ffff880078b69a70 ffffffff817e82e0
     0000000000000000 ffff880078b69a98 ffffffff810cf1a4 0000000000000050
     0000000000000050 ffff88007cc01a00 ffff880078b69ad8 ffffffff8121449e
    Call Trace:
     [<ffffffff817e82e0>] dump_stack+0x4d/0x66
     [<ffffffff810cf1a4>] __might_sleep+0x184/0x240
     [<ffffffff8121449e>] kmem_cache_alloc_trace+0x4e/0x330
     [<ffffffffa0331124>] ? nfs4_release_lockowner+0x74/0x110 [nfsv4]
     [<ffffffffa0331124>] nfs4_release_lockowner+0x74/0x110 [nfsv4]
     [<ffffffffa0352340>] nfs4_put_lock_state+0x90/0xb0 [nfsv4]
     [<ffffffffa0352375>] nfs4_fl_release_lock+0x15/0x20 [nfsv4]
     [<ffffffff81297515>] locks_free_lock+0x45/0x90
     [<ffffffff8129996c>] flock_lock_file_wait+0x11c/0x3a0
     [<ffffffffa033da6a>] ? nfs4_proc_lock+0x26a/0x910 [nfsv4]
     [<ffffffffa033301e>] do_vfs_lock+0x1e/0x30 [nfsv4]
     [<ffffffffa033da79>] nfs4_proc_lock+0x279/0x910 [nfsv4]
     [<ffffffff810dbb26>] ? local_clock+0x16/0x30
     [<ffffffff810f5a3f>] ? lock_release_holdtime.part.28+0xf/0x200
     [<ffffffffa02f820c>] do_unlk+0x8c/0xc0 [nfs]
     [<ffffffffa02f85c5>] nfs_flock+0xa5/0xf0 [nfs]
     [<ffffffff8129a6f6>] locks_remove_file+0xb6/0x1e0
     [<ffffffff812159d8>] ? kfree+0xd8/0x2d0
     [<ffffffff8123bc63>] __fput+0xd3/0x210
     [<ffffffff8123bdee>] ____fput+0xe/0x10
     [<ffffffff810bfb6d>] task_work_run+0xcd/0xf0
     [<ffffffff81019cd1>] do_notify_resume+0x61/0x90
     [<ffffffff817fbea2>] int_signal+0x12/0x17
    
    The problem is that NFSv4 is trying to do an allocation from
    fl_release_private (in order to send a RELEASE_LOCKOWNER call). That
    function can be called while holding the inode->i_lock, and it's
    currently set up to do __GFP_WAIT allocations. v4.1 code has a
    similar problem.
    
    This patch adds a work_struct to the nfs4_lock_state and has the code
    queue the free_lock_state operation to nfsiod.
    Reported-by: NJosh Stone <jistone@redhat.com>
    Signed-off-by: NJeff Layton <jlayton@poochiereds.net>
    Signed-off-by: NTrond Myklebust <trond.myklebust@primarydata.com>
    49a4bda2
nfs4state.c 63.5 KB