xprtrdma: Plant XID in on-the-wire RDMA offset (FRWR)
authorChuck Lever <chuck.lever@oracle.com>
Wed, 19 Dec 2018 15:59:07 +0000 (10:59 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 2 Jan 2019 17:05:17 +0000 (12:05 -0500)
Place the associated RPC transaction's XID in the upper 32 bits of
each RDMA segment's rdma_offset field. There are two reasons to do
this:

- The R_key only has 8 bits that are different from registration to
  registration. The XID adds more uniqueness to each RDMA segment to
  reduce the likelihood of a software bug on the server reading from
  or writing into memory it's not supposed to.

- On-the-wire RDMA Read and Write requests do not otherwise carry
  any identifier that matches them up to an RPC. The XID in the
  upper 32 bits will act as an eye-catcher in network captures.

Suggested-by: Tom Talpey <ttalpey@microsoft.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/xprt_rdma.h

index fb0944d854c9213cc3b3229590a6966a535ef1c3..97f88bbc9047428b9ecf6b9bbe854ceb1a892d1b 100644 (file)
@@ -379,6 +379,7 @@ frwr_wc_localinv_wake(struct ib_cq *cq, struct ib_wc *wc)
  * @seg: memory region co-ordinates
  * @nsegs: number of segments remaining
  * @writing: true when RDMA Write will be used
+ * @xid: XID of RPC using the registered memory
  * @out: initialized MR
  *
  * Prepare a REG_MR Work Request to register a memory region
@@ -389,7 +390,7 @@ frwr_wc_localinv_wake(struct ib_cq *cq, struct ib_wc *wc)
  */
 struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
                                struct rpcrdma_mr_seg *seg,
-                               int nsegs, bool writing,
+                               int nsegs, bool writing, u32 xid,
                                struct rpcrdma_mr **out)
 {
        struct rpcrdma_ia *ia = &r_xprt->rx_ia;
@@ -444,6 +445,8 @@ struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
        if (unlikely(n != mr->mr_nents))
                goto out_mapmr_err;
 
+       ibmr->iova &= 0x00000000ffffffff;
+       ibmr->iova |= ((u64)cpu_to_be32(xid)) << 32;
        key = (u8)(ibmr->rkey & 0x000000FF);
        ib_update_fast_reg_key(ibmr, ++key);
 
index 2a2023d320e7a271f5bc32b8c0a6f786a35212a9..3804fb30bdcfa232a2ed42f9e23635a13b7a03c1 100644 (file)
@@ -356,7 +356,7 @@ rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
                return nsegs;
 
        do {
-               seg = frwr_map(r_xprt, seg, nsegs, false, &mr);
+               seg = frwr_map(r_xprt, seg, nsegs, false, rqst->rq_xid, &mr);
                if (IS_ERR(seg))
                        return PTR_ERR(seg);
                rpcrdma_mr_push(mr, &req->rl_registered);
@@ -413,7 +413,7 @@ rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
 
        nchunks = 0;
        do {
-               seg = frwr_map(r_xprt, seg, nsegs, true, &mr);
+               seg = frwr_map(r_xprt, seg, nsegs, true, rqst->rq_xid, &mr);
                if (IS_ERR(seg))
                        return PTR_ERR(seg);
                rpcrdma_mr_push(mr, &req->rl_registered);
@@ -470,7 +470,7 @@ rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
 
        nchunks = 0;
        do {
-               seg = frwr_map(r_xprt, seg, nsegs, true, &mr);
+               seg = frwr_map(r_xprt, seg, nsegs, true, rqst->rq_xid, &mr);
                if (IS_ERR(seg))
                        return PTR_ERR(seg);
                rpcrdma_mr_push(mr, &req->rl_registered);
index c42a0036a0bd48c17bdcb9c55898d42644f9fd1c..ff4eab1c3bf132f3e9f0057aa00eefbc0acdb802 100644 (file)
@@ -580,7 +580,7 @@ void frwr_release_mr(struct rpcrdma_mr *mr);
 size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt);
 struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
                                struct rpcrdma_mr_seg *seg,
-                               int nsegs, bool writing,
+                               int nsegs, bool writing, u32 xid,
                                struct rpcrdma_mr **mr);
 int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req);
 void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs);