summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2024-06-19 11:05:13 +1000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-08-03 09:00:04 +0200
commit030fdc351225cc427455a99dd24874c28474d595 (patch)
tree3b102247771e309216acef149f7912d76182d552 /net
parentfb778472ba46685581b176e24acd49067edd31b6 (diff)
downloadlinux-stable-030fdc351225cc427455a99dd24874c28474d595.tar.gz
linux-stable-030fdc351225cc427455a99dd24874c28474d595.tar.bz2
linux-stable-030fdc351225cc427455a99dd24874c28474d595.zip
SUNRPC: avoid soft lockup when transmitting UDP to reachable server.
[ Upstream commit 6258cf25d5e3155c3219ab5a79b970eef7996356 ] Prior to the commit identified below, call_transmit_status() would handle -EPERM and other errors related to an unreachable server by falling through to call_status() which added a 3-second delay and handled the failure as a timeout. Since that commit, call_transmit_status() falls through to handle_bind(). For UDP this moves straight on to handle_connect() and handle_transmit() so we immediately retransmit - and likely get the same error. This results in an indefinite loop in __rpc_execute() which triggers a soft-lockup warning. For the errors that indicate an unreachable server, call_transmit_status() should fall back to call_status() as it did before. This cannot cause the thundering herd that the previous patch was avoiding, as the call_status() will insert a delay. Fixes: ed7dc973bd91 ("SUNRPC: Prevent thundering herd when the socket is not connected") Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/clnt.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index cfd1b1bf7e35..09f29a95f2bc 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2326,12 +2326,13 @@ call_transmit_status(struct rpc_task *task)
task->tk_action = call_transmit;
task->tk_status = 0;
break;
- case -ECONNREFUSED:
case -EHOSTDOWN:
case -ENETDOWN:
case -EHOSTUNREACH:
case -ENETUNREACH:
case -EPERM:
+ break;
+ case -ECONNREFUSED:
if (RPC_IS_SOFTCONN(task)) {
if (!task->tk_msg.rpc_proc->p_proc)
trace_xprt_ping(task->tk_xprt,