• David Howells's avatar
    rxrpc: Fix locking issues in rxrpc_put_peer_locked() · 608aecd1
    David Howells authored
    Now that rxrpc_put_local() may call kthread_stop(), it can't be called
    under spinlock as it might sleep.  This can cause a problem in the peer
    keepalive code in rxrpc as it tries to avoid dropping the peer_hash_lock
    from the point it needs to re-add peer->keepalive_link to going round the
    loop again in rxrpc_peer_keepalive_dispatch().
    
    Fix this by just dropping the lock when we don't need it and accepting that
    we'll have to take it again.  This code is only called about every 20s for
    each peer, so not very often.
    
    This allows rxrpc_put_peer_unlocked() to be removed also.
    
    If triggered, this bug produces an oops like the following, as reproduced
    by a syzbot reproducer for a different oops[1]:
    
    BUG: sleeping function called from invalid context at kernel/sched/completion.c:101
    ...
    RCU nest depth: 0, expected: 0
    3 locks held by kworker/u9:0/50:
     #0: ffff88810e74a138 ((wq_completion)krxrpcd){+.+.}-{0:0}, at: process_one_work+0x294/0x636
     #1: ffff8881013a7e20 ((work_completion)(&rxnet->peer_keepalive_work)){+.+.}-{0:0}, at: process_one_work+0x294/0x636
     #2: ffff88817d366390 (&rxnet->peer_hash_lock){+.+.}-{2:2}, at: rxrpc_peer_keepalive_dispatch+0x2bd/0x35f
    ...
    Call Trace:
     <TASK>
     dump_stack_lvl+0x4c/0x5f
     __might_resched+0x2cf/0x2f2
     __wait_for_common+0x87/0x1e8
     kthread_stop+0x14d/0x255
     rxrpc_peer_keepalive_dispatch+0x333/0x35f
     rxrpc_peer_keepalive_worker+0x2e9/0x449
     process_one_work+0x3c1/0x636
     worker_thread+0x25f/0x359
     kthread+0x1a6/0x1b5
     ret_from_fork+0x1f/0x30
    
    Fixes: a275da62 ("rxrpc: Create a per-local endpoint receive queue and I/O thread")
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    cc: Marc Dionne <marc.dionne@auristor.com>
    cc: linux-afs@lists.infradead.org
    Link: https://lore.kernel.org/r/0000000000002b4a9f05ef2b616f@google.com/ [1]
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    608aecd1
peer_event.c 8.82 KB