Skip to content

Commit 91ca186

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: xprt_release_rqst_cong is called outside of transport_lock
Since commit ce7c252 ("SUNRPC: Add a separate spinlock to protect the RPC request receive list") the RPC/RDMA reply handler has been calling xprt_release_rqst_cong without holding xprt->transport_lock. I think the only way this call is ever made is if the credit grant increases and there are RPCs pending. Current server implementations do not change their credit grant during operation (except at connect time). Commit e7ce710 ("xprtrdma: Avoid deadlock when credit window is reset") added the ->release_rqst call because UDP invokes xprt_adjust_cwnd(), which calls __xprt_put_cong() after adjusting xprt->cwnd. Both xprt_release() and ->xprt_release_xprt already wake another task in this case, so it is safe to remove this call from the reply handler. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 17b57b1 commit 91ca186

File tree

1 file changed

+7
-9
lines changed

1 file changed

+7
-9
lines changed

net/sunrpc/xprtrdma/rpc_rdma.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,6 @@ void rpcrdma_complete_rqst(struct rpcrdma_rep *rep)
12161216
struct rpcrdma_xprt *r_xprt = rep->rr_rxprt;
12171217
struct rpc_xprt *xprt = &r_xprt->rx_xprt;
12181218
struct rpc_rqst *rqst = rep->rr_rqst;
1219-
unsigned long cwnd;
12201219
int status;
12211220

12221221
xprt->reestablish_timeout = 0;
@@ -1239,11 +1238,6 @@ void rpcrdma_complete_rqst(struct rpcrdma_rep *rep)
12391238

12401239
out:
12411240
spin_lock(&xprt->recv_lock);
1242-
cwnd = xprt->cwnd;
1243-
xprt->cwnd = r_xprt->rx_buf.rb_credits << RPC_CWNDSHIFT;
1244-
if (xprt->cwnd > cwnd)
1245-
xprt_release_rqst_cong(rqst->rq_task);
1246-
12471241
xprt_complete_rqst(rqst->rq_task, status);
12481242
xprt_unpin_rqst(rqst);
12491243
spin_unlock(&xprt->recv_lock);
@@ -1350,14 +1344,18 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
13501344
if (!rqst)
13511345
goto out_norqst;
13521346
xprt_pin_rqst(rqst);
1347+
spin_unlock(&xprt->recv_lock);
13531348

13541349
if (credits == 0)
13551350
credits = 1; /* don't deadlock */
13561351
else if (credits > buf->rb_max_requests)
13571352
credits = buf->rb_max_requests;
1358-
buf->rb_credits = credits;
1359-
1360-
spin_unlock(&xprt->recv_lock);
1353+
if (buf->rb_credits != credits) {
1354+
spin_lock_bh(&xprt->transport_lock);
1355+
buf->rb_credits = credits;
1356+
xprt->cwnd = credits << RPC_CWNDSHIFT;
1357+
spin_unlock_bh(&xprt->transport_lock);
1358+
}
13611359

13621360
req = rpcr_to_rdmar(rqst);
13631361
req->rl_reply = rep;

0 commit comments

Comments
 (0)