Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6814baea authored by Chuck Lever's avatar Chuck Lever Committed by Anna Schumaker
Browse files

xprtrdma: Add a "deregister_external" op for each memreg mode



There is very little common processing among the different external
memory deregistration functions.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Tested-by: default avatarDevesh Sharma <Devesh.Sharma@Emulex.Com>
Tested-by: default avatarMeghana Cheripady <Meghana.Cheripady@Emulex.Com>
Tested-by: default avatarVeeresh U. Kokatnur <veereshuk@chelsio.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 9c1b4d77
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -79,8 +79,35 @@ out_maperr:
	return rc;
}

/* Use the ib_unmap_fmr() verb to prevent further remote
 * access via RDMA READ or RDMA WRITE.
 */
static int
fmr_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg)
{
	struct rpcrdma_ia *ia = &r_xprt->rx_ia;
	struct rpcrdma_mr_seg *seg1 = seg;
	int rc, nsegs = seg->mr_nsegs;
	LIST_HEAD(l);

	list_add(&seg1->rl_mw->r.fmr->list, &l);
	rc = ib_unmap_fmr(&l);
	read_lock(&ia->ri_qplock);
	while (seg1->mr_nsegs--)
		rpcrdma_unmap_one(ia, seg++);
	read_unlock(&ia->ri_qplock);
	if (rc)
		goto out_err;
	return nsegs;

out_err:
	dprintk("RPC:       %s: ib_unmap_fmr status %i\n", __func__, rc);
	return nsegs;
}

const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
	.ro_map				= fmr_op_map,
	.ro_unmap			= fmr_op_unmap,
	.ro_maxpages			= fmr_op_maxpages,
	.ro_displayname			= "fmr",
};
+36 −0
Original line number Diff line number Diff line
@@ -110,8 +110,44 @@ out_senderr:
	return rc;
}

/* Post a LOCAL_INV Work Request to prevent further remote access
 * via RDMA READ or RDMA WRITE.
 */
static int
frwr_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg)
{
	struct rpcrdma_mr_seg *seg1 = seg;
	struct rpcrdma_ia *ia = &r_xprt->rx_ia;
	struct ib_send_wr invalidate_wr, *bad_wr;
	int rc, nsegs = seg->mr_nsegs;

	seg1->rl_mw->r.frmr.fr_state = FRMR_IS_INVALID;

	memset(&invalidate_wr, 0, sizeof(invalidate_wr));
	invalidate_wr.wr_id = (unsigned long)(void *)seg1->rl_mw;
	invalidate_wr.opcode = IB_WR_LOCAL_INV;
	invalidate_wr.ex.invalidate_rkey = seg1->rl_mw->r.frmr.fr_mr->rkey;
	DECR_CQCOUNT(&r_xprt->rx_ep);

	read_lock(&ia->ri_qplock);
	while (seg1->mr_nsegs--)
		rpcrdma_unmap_one(ia, seg++);
	rc = ib_post_send(ia->ri_id->qp, &invalidate_wr, &bad_wr);
	read_unlock(&ia->ri_qplock);
	if (rc)
		goto out_err;
	return nsegs;

out_err:
	/* Force rpcrdma_buffer_get() to retry */
	seg1->rl_mw->r.frmr.fr_state = FRMR_IS_STALE;
	dprintk("RPC:       %s: ib_post_send status %i\n", __func__, rc);
	return nsegs;
}

const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
	.ro_map				= frwr_op_map,
	.ro_unmap			= frwr_op_unmap,
	.ro_maxpages			= frwr_op_maxpages,
	.ro_displayname			= "frwr",
};
+10 −0
Original line number Diff line number Diff line
@@ -44,8 +44,18 @@ physical_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
	return 1;
}

/* Unmap a memory region, but leave it registered.
 */
static int
physical_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg)
{
	rpcrdma_unmap_one(&r_xprt->rx_ia, seg);
	return 1;
}

const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = {
	.ro_map				= physical_op_map,
	.ro_unmap			= physical_op_unmap,
	.ro_maxpages			= physical_op_maxpages,
	.ro_displayname			= "physical",
};
+6 −5
Original line number Diff line number Diff line
@@ -284,11 +284,12 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
	return (unsigned char *)iptr - (unsigned char *)headerp;

out:
	if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_FRMR) {
	if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
		return n;

	for (pos = 0; nchunks--;)
			pos += rpcrdma_deregister_external(
					&req->rl_segments[pos], r_xprt);
	}
		pos += r_xprt->rx_ia.ri_ops->ro_unmap(r_xprt,
						      &req->rl_segments[pos]);
	return n;
}

+2 −2
Original line number Diff line number Diff line
@@ -584,8 +584,8 @@ xprt_rdma_free(void *buffer)

	for (i = 0; req->rl_nchunks;) {
		--req->rl_nchunks;
		i += rpcrdma_deregister_external(
			&req->rl_segments[i], r_xprt);
		i += r_xprt->rx_ia.ri_ops->ro_unmap(r_xprt,
						    &req->rl_segments[i]);
	}

	rpcrdma_buffer_put(req);
Loading