Merge tag 'nfs-for-4.7-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[deliverable/linux.git] / net / sunrpc / xprtrdma / frwr_ops.c
index 4e0a5c1abea4b9717693999c0812b58e545e251c..c0947544babeb976eea94ae4698ce955bd1a3c37 100644 (file)
@@ -150,9 +150,9 @@ static void
 __frwr_recovery_worker(struct work_struct *work)
 {
        struct rpcrdma_mw *r = container_of(work, struct rpcrdma_mw,
-                                           frmr.fr_work);
+                                           mw_work);
 
-       __frwr_reset_and_unmap(r->frmr.fr_xprt, r);
+       __frwr_reset_and_unmap(r->mw_xprt, r);
        return;
 }
 
@@ -162,8 +162,8 @@ __frwr_recovery_worker(struct work_struct *work)
 static void
 __frwr_queue_recovery(struct rpcrdma_mw *r)
 {
-       INIT_WORK(&r->frmr.fr_work, __frwr_recovery_worker);
-       queue_work(frwr_recovery_wq, &r->frmr.fr_work);
+       INIT_WORK(&r->mw_work, __frwr_recovery_worker);
+       queue_work(frwr_recovery_wq, &r->mw_work);
 }
 
 static int
@@ -378,9 +378,9 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt)
                        return rc;
                }
 
+               r->mw_xprt = r_xprt;
                list_add(&r->mw_list, &buf->rb_mws);
                list_add(&r->mw_all, &buf->rb_all);
-               r->frmr.fr_xprt = r_xprt;
        }
 
        return 0;
@@ -450,7 +450,7 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
                return -ENOMEM;
        }
 
-       n = ib_map_mr_sg(mr, frmr->fr_sg, frmr->fr_nents, PAGE_SIZE);
+       n = ib_map_mr_sg(mr, frmr->fr_sg, frmr->fr_nents, NULL, PAGE_SIZE);
        if (unlikely(n != frmr->fr_nents)) {
                pr_err("RPC:       %s: failed to map mr %p (%u/%u)\n",
                       __func__, frmr->fr_mr, n, frmr->fr_nents);
@@ -614,46 +614,30 @@ reset_mrs:
        goto unmap;
 }
 
-/* Post a LOCAL_INV Work Request to prevent further remote access
- * via RDMA READ or RDMA WRITE.
+/* Use a slow, safe mechanism to invalidate all memory regions
+ * that were registered for "req".
  */
-static int
-frwr_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg)
+static void
+frwr_op_unmap_safe(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
+                  bool sync)
 {
-       struct rpcrdma_mr_seg *seg1 = seg;
-       struct rpcrdma_ia *ia = &r_xprt->rx_ia;
-       struct rpcrdma_mw *mw = seg1->rl_mw;
-       struct rpcrdma_frmr *frmr = &mw->frmr;
-       struct ib_send_wr *invalidate_wr, *bad_wr;
-       int rc, nsegs = seg->mr_nsegs;
-
-       dprintk("RPC:       %s: FRMR %p\n", __func__, mw);
-
-       seg1->rl_mw = NULL;
-       frmr->fr_state = FRMR_IS_INVALID;
-       invalidate_wr = &mw->frmr.fr_invwr;
-
-       memset(invalidate_wr, 0, sizeof(*invalidate_wr));
-       frmr->fr_cqe.done = frwr_wc_localinv;
-       invalidate_wr->wr_cqe = &frmr->fr_cqe;
-       invalidate_wr->opcode = IB_WR_LOCAL_INV;
-       invalidate_wr->ex.invalidate_rkey = frmr->fr_mr->rkey;
-       DECR_CQCOUNT(&r_xprt->rx_ep);
+       struct rpcrdma_mr_seg *seg;
+       struct rpcrdma_mw *mw;
+       unsigned int i;
 
-       ib_dma_unmap_sg(ia->ri_device, frmr->fr_sg, frmr->fr_nents, frmr->fr_dir);
-       read_lock(&ia->ri_qplock);
-       rc = ib_post_send(ia->ri_id->qp, invalidate_wr, &bad_wr);
-       read_unlock(&ia->ri_qplock);
-       if (rc)
-               goto out_err;
+       for (i = 0; req->rl_nchunks; req->rl_nchunks--) {
+               seg = &req->rl_segments[i];
+               mw = seg->rl_mw;
 
-       rpcrdma_put_mw(r_xprt, mw);
-       return nsegs;
+               if (sync)
+                       __frwr_reset_and_unmap(r_xprt, mw);
+               else
+                       __frwr_queue_recovery(mw);
 
-out_err:
-       dprintk("RPC:       %s: ib_post_send status %i\n", __func__, rc);
-       __frwr_queue_recovery(mw);
-       return nsegs;
+               i += seg->mr_nsegs;
+               seg->mr_nsegs = 0;
+               seg->rl_mw = NULL;
+       }
 }
 
 static void
@@ -675,7 +659,7 @@ frwr_op_destroy(struct rpcrdma_buffer *buf)
 const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
        .ro_map                         = frwr_op_map,
        .ro_unmap_sync                  = frwr_op_unmap_sync,
-       .ro_unmap                       = frwr_op_unmap,
+       .ro_unmap_safe                  = frwr_op_unmap_safe,
        .ro_open                        = frwr_op_open,
        .ro_maxpages                    = frwr_op_maxpages,
        .ro_init                        = frwr_op_init,
This page took 0.031449 seconds and 5 git commands to generate.