| From | Greg Kroah-Hartman <> | Subject | [PATCH 5.0 236/238] SUNRPC: Prevent thundering herd when the socket is not connected | Date | Fri, 22 Mar 2019 12:17:35 +0100 |
| |
5.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <trond.myklebust@hammerspace.com>
commit ed7dc973bd91da234d93aff6d033a5206a6c9885 upstream.
If the socket is not connected, then we want to initiate a reconnect rather that trying to transmit requests. If there is a large number of requests queued and waiting for the lock in call_transmit(), then it can take a while for one of the to loop back and retake the lock in call_connect.
Fixes: 89f90fe1ad8b ("SUNRPC: Allow calls to xprt_transmit() to drain...") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- net/sunrpc/clnt.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
--- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1786,7 +1786,12 @@ call_encode(struct rpc_task *task) xprt_request_enqueue_receive(task); xprt_request_enqueue_transmit(task); out: - task->tk_action = call_bind; + task->tk_action = call_transmit; + /* Check that the connection is OK */ + if (!xprt_bound(task->tk_xprt)) + task->tk_action = call_bind; + else if (!xprt_connected(task->tk_xprt)) + task->tk_action = call_connect; } /* @@ -1978,13 +1983,19 @@ call_transmit(struct rpc_task *task) { dprint_status(task); - task->tk_status = 0; + task->tk_action = call_transmit_status; if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) { if (!xprt_prepare_transmit(task)) return; - xprt_transmit(task); + task->tk_status = 0; + if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) { + if (!xprt_connected(task->tk_xprt)) { + task->tk_status = -ENOTCONN; + return; + } + xprt_transmit(task); + } } - task->tk_action = call_transmit_status; xprt_end_transmit(task); } @@ -2046,6 +2057,8 @@ call_transmit_status(struct rpc_task *ta case -EADDRINUSE: case -ENOTCONN: case -EPIPE: + task->tk_action = call_bind; + task->tk_status = 0; break; } }
|