Skip to content

Commit be798f9

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Decode credits field in rpcrdma_reply_handler
We need to decode and save the incoming rdma_credits field _after_ we know that the direction of the message is "forward direction Reply". Otherwise, the credits value in reverse direction Calls is also used to update the forward direction credits. It is safe to decode the rdma_credits field in rpcrdma_reply_handler now that rpcrdma_reply_handler is single-threaded. Receives complete in the same order as they were sent on the NFS server. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent d8f532d commit be798f9

File tree

3 files changed

+14
-27
lines changed

3 files changed

+14
-27
lines changed

net/sunrpc/xprtrdma/rpc_rdma.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ void rpcrdma_complete_rqst(struct rpcrdma_rep *rep)
12441244
out:
12451245
spin_lock(&xprt->recv_lock);
12461246
cwnd = xprt->cwnd;
1247-
xprt->cwnd = atomic_read(&r_xprt->rx_buf.rb_credits) << RPC_CWNDSHIFT;
1247+
xprt->cwnd = r_xprt->rx_buf.rb_credits << RPC_CWNDSHIFT;
12481248
if (xprt->cwnd > cwnd)
12491249
xprt_release_rqst_cong(rqst->rq_task);
12501250

@@ -1297,8 +1297,10 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
12971297
{
12981298
struct rpcrdma_xprt *r_xprt = rep->rr_rxprt;
12991299
struct rpc_xprt *xprt = &r_xprt->rx_xprt;
1300+
struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
13001301
struct rpcrdma_req *req;
13011302
struct rpc_rqst *rqst;
1303+
u32 credits;
13021304
__be32 *p;
13031305

13041306
dprintk("RPC: %s: incoming rep %p\n", __func__, rep);
@@ -1315,7 +1317,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
13151317
goto out_shortreply;
13161318
rep->rr_xid = *p++;
13171319
rep->rr_vers = *p++;
1318-
p++; /* credits */
1320+
credits = be32_to_cpu(*p++);
13191321
rep->rr_proc = *p++;
13201322

13211323
if (rep->rr_vers != rpcrdma_version)
@@ -1332,7 +1334,15 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
13321334
if (!rqst)
13331335
goto out_norqst;
13341336
xprt_pin_rqst(rqst);
1337+
1338+
if (credits == 0)
1339+
credits = 1; /* don't deadlock */
1340+
else if (credits > buf->rb_max_requests)
1341+
credits = buf->rb_max_requests;
1342+
buf->rb_credits = credits;
1343+
13351344
spin_unlock(&xprt->recv_lock);
1345+
13361346
req = rpcr_to_rdmar(rqst);
13371347
req->rl_reply = rep;
13381348
rep->rr_rqst = rqst;

net/sunrpc/xprtrdma/verbs.c

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -133,25 +133,6 @@ rpcrdma_wc_send(struct ib_cq *cq, struct ib_wc *wc)
133133
wc->status, wc->vendor_err);
134134
}
135135

136-
/* Perform basic sanity checking to avoid using garbage
137-
* to update the credit grant value.
138-
*/
139-
static void
140-
rpcrdma_update_granted_credits(struct rpcrdma_rep *rep)
141-
{
142-
struct rpcrdma_buffer *buffer = &rep->rr_rxprt->rx_buf;
143-
__be32 *p = rep->rr_rdmabuf->rg_base;
144-
u32 credits;
145-
146-
credits = be32_to_cpup(p + 2);
147-
if (credits == 0)
148-
credits = 1; /* don't deadlock */
149-
else if (credits > buffer->rb_max_requests)
150-
credits = buffer->rb_max_requests;
151-
152-
atomic_set(&buffer->rb_credits, credits);
153-
}
154-
155136
/**
156137
* rpcrdma_wc_receive - Invoked by RDMA provider for each polled Receive WC
157138
* @cq: completion queue (ignored)
@@ -181,9 +162,6 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
181162
rdmab_addr(rep->rr_rdmabuf),
182163
wc->byte_len, DMA_FROM_DEVICE);
183164

184-
if (wc->byte_len >= RPCRDMA_HDRLEN_ERR)
185-
rpcrdma_update_granted_credits(rep);
186-
187165
out_schedule:
188166
rpcrdma_reply_handler(rep);
189167
return;
@@ -295,7 +273,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
295273
case RDMA_CM_EVENT_DISCONNECTED:
296274
connstate = -ECONNABORTED;
297275
connected:
298-
atomic_set(&xprt->rx_buf.rb_credits, 1);
276+
xprt->rx_buf.rb_credits = 1;
299277
ep->rep_connected = connstate;
300278
rpcrdma_conn_func(ep);
301279
wake_up_all(&ep->rep_connect_wait);
@@ -995,7 +973,6 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
995973

996974
buf->rb_max_requests = r_xprt->rx_data.max_requests;
997975
buf->rb_bc_srv_max_requests = 0;
998-
atomic_set(&buf->rb_credits, 1);
999976
spin_lock_init(&buf->rb_mwlock);
1000977
spin_lock_init(&buf->rb_lock);
1001978
spin_lock_init(&buf->rb_recovery_lock);

net/sunrpc/xprtrdma/xprt_rdma.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ struct rpcrdma_buffer {
407407
struct list_head rb_send_bufs;
408408
struct list_head rb_recv_bufs;
409409
u32 rb_max_requests;
410-
atomic_t rb_credits; /* most recent credit grant */
410+
u32 rb_credits; /* most recent credit grant */
411411

412412
u32 rb_bc_srv_max_requests;
413413
spinlock_t rb_reqslock; /* protect rb_allreqs */

0 commit comments

Comments
 (0)