Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

SUNRPC: avoid soft lockup when transmitting UDP to reachable server.

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>

authored by

NeilBrown and committed by
Anna Schumaker
6258cf25 0e13dd9e

+2 -1
+2 -1
net/sunrpc/clnt.c
··· 2326 2326 task->tk_action = call_transmit; 2327 2327 task->tk_status = 0; 2328 2328 break; 2329 - case -ECONNREFUSED: 2330 2329 case -EHOSTDOWN: 2331 2330 case -ENETDOWN: 2332 2331 case -EHOSTUNREACH: 2333 2332 case -ENETUNREACH: 2334 2333 case -EPERM: 2334 + break; 2335 + case -ECONNREFUSED: 2335 2336 if (RPC_IS_SOFTCONN(task)) { 2336 2337 if (!task->tk_msg.rpc_proc->p_proc) 2337 2338 trace_xprt_ping(task->tk_xprt,