On 2/23/26 11:19 PM, Allison Henderson wrote:
From: Gerd Rausch <[email protected]>Delegate fan-out to a background worker in order to allow kernel_getpeername() to acquire a lock on the socket. This has become necessary since the introduction of commit "9dfc685e0262d ("inet: remove races in inet{6}_getname()") The socket is already locked in the context that "kernel_getpeername" used to get called by either rds_tcp_recv_path" or "tcp_v{4,6}_rcv", and therefore causing a deadlock. Luckily, the fan-out need not happen in-context nor fast, so we can easily just do the same in a background worker. Also, while we're doing this, we get rid of the unused struct members "t_conn_w", "t_send_w", "t_down_w" & "t_recv_w". The fan-out work and the shutdown worker (cp_down_w) are both queued on the same ordered workqueue (cp0->cp_wq), so they cannot execute concurrently. We only need cancel_work_sync() in rds_tcp_conn_free() and rds_tcp_conn_path_connect() because those run from outside the ordered workqueue. Signed-off-by: Gerd Rausch <[email protected]> Signed-off-by: Allison Henderson <[email protected]> --- net/rds/tcp.c | 3 +++ net/rds/tcp.h | 7 ++---- net/rds/tcp_connect.c | 2 ++ net/rds/tcp_listen.c | 54 +++++++++++++++++++++++++++++++------------ 4 files changed, 46 insertions(+), 20 deletions(-)
Isn't this change kind of dangerous since 021fd0f87004 ("net/rds: fix recursive lock in rds_tcp_conn_slots_available") [1]?. Why is kernel_getpeername() needed as only the peer source port is required for the operation?
Thanks, Fernando.
