linux/net/rxrpc
David Howells 608aecd16a rxrpc: Fix locking issues in rxrpc_put_peer_locked()
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: a275da62e8 ("rxrpc: Create a per-local endpoint receive queue and I/O thread")
Signed-off-by: David 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: David S. Miller <davem@davemloft.net>
2022-12-19 09:51:31 +00:00
..
af_rxrpc.c rxrpc: Remove the _bh annotation from all the spinlocks 2022-12-01 13:36:42 +00:00
ar-internal.h rxrpc: Fix locking issues in rxrpc_put_peer_locked() 2022-12-19 09:51:31 +00:00
call_accept.c rxrpc: Remove the _bh annotation from all the spinlocks 2022-12-01 13:36:42 +00:00
call_event.c rxrpc: Transmit ACKs at the point of generation 2022-12-01 13:36:43 +00:00
call_object.c rxrpc: Fix security setting propagation 2022-12-19 09:51:31 +00:00
conn_client.c rxrpc: Fix security setting propagation 2022-12-19 09:51:31 +00:00
conn_event.c rxrpc: Remove the _bh annotation from all the spinlocks 2022-12-01 13:36:42 +00:00
conn_object.c rxrpc: Make the I/O thread take over the call and local processor work 2022-12-01 13:36:42 +00:00
conn_service.c rxrpc: Remove the _bh annotation from all the spinlocks 2022-12-01 13:36:42 +00:00
input.c rxrpc: Move the cwnd degradation after transmitting packets 2022-12-01 13:36:43 +00:00
insecure.c rxrpc: Don't use a ring buffer for call Tx queue 2022-11-08 16:42:28 +00:00
io_thread.c rxrpc: Fix I/O thread startup getting skipped 2022-12-19 09:51:31 +00:00
Kconfig rxrpc: Implement an in-kernel rxperf server for testing purposes 2022-12-01 13:36:37 +00:00
key.c rxrpc: Drop rxrpc_conn_parameters from rxrpc_connection and rxrpc_bundle 2022-12-01 13:36:38 +00:00
local_event.c rxrpc: Make the I/O thread take over the call and local processor work 2022-12-01 13:36:42 +00:00
local_object.c rxrpc: Fix I/O thread startup getting skipped 2022-12-19 09:51:31 +00:00
Makefile rxrpc: Split the receive code 2022-12-01 13:36:40 +00:00
misc.c rxrpc: Get rid of the Rx ring 2022-11-08 16:42:28 +00:00
net_ns.c rxrpc: Don't hold a ref for connection workqueue 2022-12-01 13:36:40 +00:00
output.c rxrpc: Transmit ACKs at the point of generation 2022-12-01 13:36:43 +00:00
peer_event.c rxrpc: Fix locking issues in rxrpc_put_peer_locked() 2022-12-19 09:51:31 +00:00
peer_object.c rxrpc: Fix locking issues in rxrpc_put_peer_locked() 2022-12-19 09:51:31 +00:00
proc.c rxrpc: Move the cwnd degradation after transmitting packets 2022-12-01 13:36:43 +00:00
protocol.h rxrpc: Clone received jumbo subpackets and queue separately 2022-11-08 16:42:28 +00:00
recvmsg.c rxrpc: Transmit ACKs at the point of generation 2022-12-01 13:36:43 +00:00
rtt.c rxrpc: Fix _usecs_to_jiffies() by using usecs_to_jiffies() 2021-09-24 14:18:34 +01:00
rxkad.c rxrpc: Drop rxrpc_conn_parameters from rxrpc_connection and rxrpc_bundle 2022-12-01 13:36:38 +00:00
rxperf.c rxrpc: Implement an in-kernel rxperf server for testing purposes 2022-12-01 13:36:37 +00:00
security.c rxrpc: Fix security setting propagation 2022-12-19 09:51:31 +00:00
sendmsg.c rxrpc: Fix missing unlock in rxrpc_do_sendmsg() 2022-12-19 09:51:31 +00:00
server_key.c rxrpc: Implement an in-kernel rxperf server for testing purposes 2022-12-01 13:36:37 +00:00
skbuff.c rxrpc: trace: Don't use __builtin_return_address for sk_buff tracing 2022-12-01 13:36:39 +00:00
sysctl.c rxrpc: Get rid of the Rx ring 2022-11-08 16:42:28 +00:00
txbuf.c rxrpc: Transmit ACKs at the point of generation 2022-12-01 13:36:43 +00:00
utils.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00