Skip to content

Commit

Permalink
SUNRPC: Fix backchannel RPC soft lockups
Browse files Browse the repository at this point in the history
Currently, after the forward channel connection goes away,
backchannel operations are causing soft lockups on the server
because call_transmit_status's SOFTCONN logic ignores ENOTCONN.
Such backchannel Calls are aggressively retried until the client
reconnects.

Backchannel Calls should use RPC_TASK_NOCONNECT rather than
RPC_TASK_SOFTCONN. If there is no forward connection, the server is
not capable of establishing a connection back to the client, thus
that backchannel request should fail before the server attempts to
send it. Commit 58255a4 ("NFSD: NFSv4 callback client should
use RPC_TASK_SOFTCONN") was merged several years before
RPC_TASK_NOCONNECT was available.

Because setup_callback_client() explicitly sets NOPING, the NFSv4.0
callback connection depends on the first callback RPC to initiate
a connection to the client. Thus NFSv4.0 needs to continue to use
RPC_TASK_SOFTCONN.

Suggested-by: Trond Myklebust <[email protected]>
Signed-off-by: Chuck Lever <[email protected]>
Cc: <[email protected]> # v4.20+
  • Loading branch information
chucklever committed Apr 17, 2020
1 parent 43e3392 commit 6221f1d
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 1 deletion.
4 changes: 3 additions & 1 deletion fs/nfsd/nfs4callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,7 @@ nfsd4_run_cb_work(struct work_struct *work)
container_of(work, struct nfsd4_callback, cb_work);
struct nfs4_client *clp = cb->cb_clp;
struct rpc_clnt *clnt;
int flags;

if (cb->cb_need_restart) {
cb->cb_need_restart = false;
Expand Down Expand Up @@ -1340,7 +1341,8 @@ nfsd4_run_cb_work(struct work_struct *work)
}

cb->cb_msg.rpc_cred = clp->cl_cb_cred;
rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
flags = clp->cl_minorversion ? RPC_TASK_NOCONNECT : RPC_TASK_SOFTCONN;
rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | flags,
cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb);
}

Expand Down
2 changes: 2 additions & 0 deletions net/sunrpc/svc_xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,8 @@ static void svc_delete_xprt(struct svc_xprt *xprt)

dprintk("svc: svc_delete_xprt(%p)\n", xprt);
xprt->xpt_ops->xpo_detach(xprt);
if (xprt->xpt_bc_xprt)
xprt->xpt_bc_xprt->ops->close(xprt->xpt_bc_xprt);

spin_lock_bh(&serv->sv_lock);
list_del_init(&xprt->xpt_list);
Expand Down
2 changes: 2 additions & 0 deletions net/sunrpc/xprtrdma/svc_rdma_backchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ static void
xprt_rdma_bc_close(struct rpc_xprt *xprt)
{
dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);

xprt_disconnect_done(xprt);
xprt->cwnd = RPC_CWNDSHIFT;
}

Expand Down
1 change: 1 addition & 0 deletions net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -2584,6 +2584,7 @@ static int bc_send_request(struct rpc_rqst *req)

static void bc_close(struct rpc_xprt *xprt)
{
xprt_disconnect_done(xprt);
}

/*
Expand Down

0 comments on commit 6221f1d

Please sign in to comment.