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

Commit 1c9351ee authored by Chuck Lever's avatar Chuck Lever Committed by Anna Schumaker
Browse files

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



The max_payload computation is generalized to ensure that the
payload maximum is the lesser of RPC_MAX_DATA_SEGS and the number of
data segments that can be transmitted in an inline buffer.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Reviewed-by: default avatarSagi Grimberg <sagig@mellanox.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 a0ce85f5
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -17,6 +17,19 @@
# define RPCDBG_FACILITY	RPCDBG_TRANS
#endif

/* Maximum scatter/gather per FMR */
#define RPCRDMA_MAX_FMR_SGES	(64)

/* FMR mode conveys up to 64 pages of payload per chunk segment.
 */
static size_t
fmr_op_maxpages(struct rpcrdma_xprt *r_xprt)
{
	return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
		     rpcrdma_max_segments(r_xprt) * RPCRDMA_MAX_FMR_SGES);
}

const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
	.ro_maxpages			= fmr_op_maxpages,
	.ro_displayname			= "fmr",
};
+13 −0
Original line number Diff line number Diff line
@@ -17,6 +17,19 @@
# define RPCDBG_FACILITY	RPCDBG_TRANS
#endif

/* FRWR mode conveys a list of pages per chunk segment. The
 * maximum length of that list is the FRWR page list depth.
 */
static size_t
frwr_op_maxpages(struct rpcrdma_xprt *r_xprt)
{
	struct rpcrdma_ia *ia = &r_xprt->rx_ia;

	return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
		     rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth);
}

const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
	.ro_maxpages			= frwr_op_maxpages,
	.ro_displayname			= "frwr",
};
+10 −0
Original line number Diff line number Diff line
@@ -19,6 +19,16 @@
# define RPCDBG_FACILITY	RPCDBG_TRANS
#endif

/* PHYSICAL memory registration conveys one page per chunk segment.
 */
static size_t
physical_op_maxpages(struct rpcrdma_xprt *r_xprt)
{
	return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
		     rpcrdma_max_segments(r_xprt));
}

const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = {
	.ro_maxpages			= physical_op_maxpages,
	.ro_displayname			= "physical",
};
+4 −1
Original line number Diff line number Diff line
@@ -406,7 +406,10 @@ xprt_setup_rdma(struct xprt_create *args)
			  xprt_rdma_connect_worker);

	xprt_rdma_format_addresses(xprt);
	xprt->max_payload = rpcrdma_max_payload(new_xprt);
	xprt->max_payload = new_xprt->rx_ia.ri_ops->ro_maxpages(new_xprt);
	if (xprt->max_payload == 0)
		goto out4;
	xprt->max_payload <<= PAGE_SHIFT;
	dprintk("RPC:       %s: transport data payload maximum: %zu bytes\n",
		__func__, xprt->max_payload);

+15 −34
Original line number Diff line number Diff line
@@ -2212,43 +2212,24 @@ rpcrdma_ep_post_recv(struct rpcrdma_ia *ia,
	return rc;
}

/* Physical mapping means one Read/Write list entry per-page.
 * All list entries must fit within an inline buffer
 *
 * NB: The server must return a Write list for NFS READ,
 *     which has the same constraint. Factor in the inline
 *     rsize as well.
/* How many chunk list items fit within our inline buffers?
 */
static size_t
rpcrdma_physical_max_payload(struct rpcrdma_xprt *r_xprt)
unsigned int
rpcrdma_max_segments(struct rpcrdma_xprt *r_xprt)
{
	struct rpcrdma_create_data_internal *cdata = &r_xprt->rx_data;
	unsigned int inline_size, pages;

	inline_size = min_t(unsigned int,
			    cdata->inline_wsize, cdata->inline_rsize);
	inline_size -= RPCRDMA_HDRLEN_MIN;
	pages = inline_size / sizeof(struct rpcrdma_segment);
	return pages << PAGE_SHIFT;
}
	int bytes, segments;

static size_t
rpcrdma_mr_max_payload(struct rpcrdma_xprt *r_xprt)
{
	return RPCRDMA_MAX_DATA_SEGS << PAGE_SHIFT;
	bytes = min_t(unsigned int, cdata->inline_wsize, cdata->inline_rsize);
	bytes -= RPCRDMA_HDRLEN_MIN;
	if (bytes < sizeof(struct rpcrdma_segment) * 2) {
		pr_warn("RPC:       %s: inline threshold too small\n",
			__func__);
		return 0;
	}

size_t
rpcrdma_max_payload(struct rpcrdma_xprt *r_xprt)
{
	size_t result;

	switch (r_xprt->rx_ia.ri_memreg_strategy) {
	case RPCRDMA_ALLPHYSICAL:
		result = rpcrdma_physical_max_payload(r_xprt);
		break;
	default:
		result = rpcrdma_mr_max_payload(r_xprt);
	}
	return result;
	segments = 1 << (fls(bytes / sizeof(struct rpcrdma_segment)) - 1);
	dprintk("RPC:       %s: max chunk list size = %d segments\n",
		__func__, segments);
	return segments;
}
Loading