Skip to content

Commit 6ab5994

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Update rkeys after transport reconnect
Various reports of: rpcrdma_qp_async_error_upcall: QP error 3 on device mlx4_0 ep ffff8800bfd3e848 Ensure that rkeys in already-marshalled RPC/RDMA headers are refreshed after the QP has been replaced by a reconnect. BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=249 Suggested-by: Selvin Xavier <[email protected]> Signed-off-by: Chuck Lever <[email protected]> Tested-by: Steve Wise <[email protected]> Tested-by: Shirley Ma <[email protected]> Tested-by: Devesh Sharma <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 43e9598 commit 6ab5994

File tree

3 files changed

+54
-42
lines changed

3 files changed

+54
-42
lines changed

net/sunrpc/xprtrdma/rpc_rdma.c

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,6 @@
5353
# define RPCDBG_FACILITY RPCDBG_TRANS
5454
#endif
5555

56-
enum rpcrdma_chunktype {
57-
rpcrdma_noch = 0,
58-
rpcrdma_readch,
59-
rpcrdma_areadch,
60-
rpcrdma_writech,
61-
rpcrdma_replych
62-
};
63-
6456
#ifdef RPC_DEBUG
6557
static const char transfertypes[][12] = {
6658
"pure inline", /* no chunks */
@@ -285,6 +277,28 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
285277
return n;
286278
}
287279

280+
/*
281+
* Marshal chunks. This routine returns the header length
282+
* consumed by marshaling.
283+
*
284+
* Returns positive RPC/RDMA header size, or negative errno.
285+
*/
286+
287+
ssize_t
288+
rpcrdma_marshal_chunks(struct rpc_rqst *rqst, ssize_t result)
289+
{
290+
struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
291+
struct rpcrdma_msg *headerp = (struct rpcrdma_msg *)req->rl_base;
292+
293+
if (req->rl_rtype != rpcrdma_noch)
294+
result = rpcrdma_create_chunks(rqst, &rqst->rq_snd_buf,
295+
headerp, req->rl_rtype);
296+
else if (req->rl_wtype != rpcrdma_noch)
297+
result = rpcrdma_create_chunks(rqst, &rqst->rq_rcv_buf,
298+
headerp, req->rl_wtype);
299+
return result;
300+
}
301+
288302
/*
289303
* Copy write data inline.
290304
* This function is used for "small" requests. Data which is passed
@@ -377,7 +391,6 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
377391
char *base;
378392
size_t rpclen, padlen;
379393
ssize_t hdrlen;
380-
enum rpcrdma_chunktype rtype, wtype;
381394
struct rpcrdma_msg *headerp;
382395

383396
/*
@@ -415,13 +428,13 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
415428
* into pages; otherwise use reply chunks.
416429
*/
417430
if (rqst->rq_rcv_buf.buflen <= RPCRDMA_INLINE_READ_THRESHOLD(rqst))
418-
wtype = rpcrdma_noch;
431+
req->rl_wtype = rpcrdma_noch;
419432
else if (rqst->rq_rcv_buf.page_len == 0)
420-
wtype = rpcrdma_replych;
433+
req->rl_wtype = rpcrdma_replych;
421434
else if (rqst->rq_rcv_buf.flags & XDRBUF_READ)
422-
wtype = rpcrdma_writech;
435+
req->rl_wtype = rpcrdma_writech;
423436
else
424-
wtype = rpcrdma_replych;
437+
req->rl_wtype = rpcrdma_replych;
425438

426439
/*
427440
* Chunks needed for arguments?
@@ -438,16 +451,16 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
438451
* TBD check NFSv4 setacl
439452
*/
440453
if (rqst->rq_snd_buf.len <= RPCRDMA_INLINE_WRITE_THRESHOLD(rqst))
441-
rtype = rpcrdma_noch;
454+
req->rl_rtype = rpcrdma_noch;
442455
else if (rqst->rq_snd_buf.page_len == 0)
443-
rtype = rpcrdma_areadch;
456+
req->rl_rtype = rpcrdma_areadch;
444457
else
445-
rtype = rpcrdma_readch;
458+
req->rl_rtype = rpcrdma_readch;
446459

447460
/* The following simplification is not true forever */
448-
if (rtype != rpcrdma_noch && wtype == rpcrdma_replych)
449-
wtype = rpcrdma_noch;
450-
if (rtype != rpcrdma_noch && wtype != rpcrdma_noch) {
461+
if (req->rl_rtype != rpcrdma_noch && req->rl_wtype == rpcrdma_replych)
462+
req->rl_wtype = rpcrdma_noch;
463+
if (req->rl_rtype != rpcrdma_noch && req->rl_wtype != rpcrdma_noch) {
451464
dprintk("RPC: %s: cannot marshal multiple chunk lists\n",
452465
__func__);
453466
return -EIO;
@@ -461,7 +474,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
461474
* When padding is in use and applies to the transfer, insert
462475
* it and change the message type.
463476
*/
464-
if (rtype == rpcrdma_noch) {
477+
if (req->rl_rtype == rpcrdma_noch) {
465478

466479
padlen = rpcrdma_inline_pullup(rqst,
467480
RPCRDMA_INLINE_PAD_VALUE(rqst));
@@ -476,7 +489,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
476489
headerp->rm_body.rm_padded.rm_pempty[1] = xdr_zero;
477490
headerp->rm_body.rm_padded.rm_pempty[2] = xdr_zero;
478491
hdrlen += 2 * sizeof(u32); /* extra words in padhdr */
479-
if (wtype != rpcrdma_noch) {
492+
if (req->rl_wtype != rpcrdma_noch) {
480493
dprintk("RPC: %s: invalid chunk list\n",
481494
__func__);
482495
return -EIO;
@@ -497,30 +510,18 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
497510
* on receive. Therefore, we request a reply chunk
498511
* for non-writes wherever feasible and efficient.
499512
*/
500-
if (wtype == rpcrdma_noch)
501-
wtype = rpcrdma_replych;
513+
if (req->rl_wtype == rpcrdma_noch)
514+
req->rl_wtype = rpcrdma_replych;
502515
}
503516
}
504517

505-
/*
506-
* Marshal chunks. This routine will return the header length
507-
* consumed by marshaling.
508-
*/
509-
if (rtype != rpcrdma_noch) {
510-
hdrlen = rpcrdma_create_chunks(rqst,
511-
&rqst->rq_snd_buf, headerp, rtype);
512-
wtype = rtype; /* simplify dprintk */
513-
514-
} else if (wtype != rpcrdma_noch) {
515-
hdrlen = rpcrdma_create_chunks(rqst,
516-
&rqst->rq_rcv_buf, headerp, wtype);
517-
}
518+
hdrlen = rpcrdma_marshal_chunks(rqst, hdrlen);
518519
if (hdrlen < 0)
519520
return hdrlen;
520521

521522
dprintk("RPC: %s: %s: hdrlen %zd rpclen %zd padlen %zd"
522523
" headerp 0x%p base 0x%p lkey 0x%x\n",
523-
__func__, transfertypes[wtype], hdrlen, rpclen, padlen,
524+
__func__, transfertypes[req->rl_wtype], hdrlen, rpclen, padlen,
524525
headerp, base, req->rl_iov.lkey);
525526

526527
/*

net/sunrpc/xprtrdma/transport.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -597,13 +597,14 @@ xprt_rdma_send_request(struct rpc_task *task)
597597
struct rpc_xprt *xprt = rqst->rq_xprt;
598598
struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
599599
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
600-
int rc;
600+
int rc = 0;
601601

602-
if (req->rl_niovs == 0) {
602+
if (req->rl_niovs == 0)
603603
rc = rpcrdma_marshal_req(rqst);
604-
if (rc < 0)
605-
goto failed_marshal;
606-
}
604+
else if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
605+
rc = rpcrdma_marshal_chunks(rqst, 0);
606+
if (rc < 0)
607+
goto failed_marshal;
607608

608609
if (req->rl_reply == NULL) /* e.g. reconnection */
609610
rpcrdma_recv_buffer_get(req);

net/sunrpc/xprtrdma/xprt_rdma.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ struct rpcrdma_ep {
9999
#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
100100
#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
101101

102+
enum rpcrdma_chunktype {
103+
rpcrdma_noch = 0,
104+
rpcrdma_readch,
105+
rpcrdma_areadch,
106+
rpcrdma_writech,
107+
rpcrdma_replych
108+
};
109+
102110
/*
103111
* struct rpcrdma_rep -- this structure encapsulates state required to recv
104112
* and complete a reply, asychronously. It needs several pieces of
@@ -192,6 +200,7 @@ struct rpcrdma_req {
192200
unsigned int rl_niovs; /* 0, 2 or 4 */
193201
unsigned int rl_nchunks; /* non-zero if chunks */
194202
unsigned int rl_connect_cookie; /* retry detection */
203+
enum rpcrdma_chunktype rl_rtype, rl_wtype;
195204
struct rpcrdma_buffer *rl_buffer; /* home base for this structure */
196205
struct rpcrdma_rep *rl_reply;/* holder for reply buffer */
197206
struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];/* chunk segments */
@@ -347,6 +356,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *);
347356
/*
348357
* RPC/RDMA protocol calls - xprtrdma/rpc_rdma.c
349358
*/
359+
ssize_t rpcrdma_marshal_chunks(struct rpc_rqst *, ssize_t);
350360
int rpcrdma_marshal_req(struct rpc_rqst *);
351361
size_t rpcrdma_max_payload(struct rpcrdma_xprt *);
352362

0 commit comments

Comments
 (0)