Skip to content

Commit 43e9598

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Limit data payload size for ALLPHYSICAL
When the client uses physical memory registration, each page in the payload gets its own array entry in the RPC/RDMA header's chunk list. Therefore, don't advertise a maximum payload size that would require more array entries than can fit in the RPC buffer where RPC/RDMA headers are built. BugLink: https://bugzilla.linux-nfs.org/show_bug.cgi?id=248 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 73806c8 commit 43e9598

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

net/sunrpc/xprtrdma/transport.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,6 @@ xprt_setup_rdma(struct xprt_create *args)
296296

297297
xprt->resvport = 0; /* privileged port not needed */
298298
xprt->tsh_size = 0; /* RPC-RDMA handles framing */
299-
xprt->max_payload = RPCRDMA_MAX_DATA_SEGS * PAGE_SIZE;
300299
xprt->ops = &xprt_rdma_procs;
301300

302301
/*
@@ -382,6 +381,9 @@ xprt_setup_rdma(struct xprt_create *args)
382381
new_ep->rep_xprt = xprt;
383382

384383
xprt_rdma_format_addresses(xprt);
384+
xprt->max_payload = rpcrdma_max_payload(new_xprt);
385+
dprintk("RPC: %s: transport data payload maximum: %zu bytes\n",
386+
__func__, xprt->max_payload);
385387

386388
if (!try_module_get(THIS_MODULE))
387389
goto out4;

net/sunrpc/xprtrdma/verbs.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,3 +1825,44 @@ rpcrdma_ep_post_recv(struct rpcrdma_ia *ia,
18251825
rc);
18261826
return rc;
18271827
}
1828+
1829+
/* Physical mapping means one Read/Write list entry per-page.
1830+
* All list entries must fit within an inline buffer
1831+
*
1832+
* NB: The server must return a Write list for NFS READ,
1833+
* which has the same constraint. Factor in the inline
1834+
* rsize as well.
1835+
*/
1836+
static size_t
1837+
rpcrdma_physical_max_payload(struct rpcrdma_xprt *r_xprt)
1838+
{
1839+
struct rpcrdma_create_data_internal *cdata = &r_xprt->rx_data;
1840+
unsigned int inline_size, pages;
1841+
1842+
inline_size = min_t(unsigned int,
1843+
cdata->inline_wsize, cdata->inline_rsize);
1844+
inline_size -= RPCRDMA_HDRLEN_MIN;
1845+
pages = inline_size / sizeof(struct rpcrdma_segment);
1846+
return pages << PAGE_SHIFT;
1847+
}
1848+
1849+
static size_t
1850+
rpcrdma_mr_max_payload(struct rpcrdma_xprt *r_xprt)
1851+
{
1852+
return RPCRDMA_MAX_DATA_SEGS << PAGE_SHIFT;
1853+
}
1854+
1855+
size_t
1856+
rpcrdma_max_payload(struct rpcrdma_xprt *r_xprt)
1857+
{
1858+
size_t result;
1859+
1860+
switch (r_xprt->rx_ia.ri_memreg_strategy) {
1861+
case RPCRDMA_ALLPHYSICAL:
1862+
result = rpcrdma_physical_max_payload(r_xprt);
1863+
break;
1864+
default:
1865+
result = rpcrdma_mr_max_payload(r_xprt);
1866+
}
1867+
return result;
1868+
}

net/sunrpc/xprtrdma/xprt_rdma.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *);
348348
* RPC/RDMA protocol calls - xprtrdma/rpc_rdma.c
349349
*/
350350
int rpcrdma_marshal_req(struct rpc_rqst *);
351+
size_t rpcrdma_max_payload(struct rpcrdma_xprt *);
351352

352353
/* Temporary NFS request map cache. Created in svc_rdma.c */
353354
extern struct kmem_cache *svc_rdma_map_cachep;

0 commit comments

Comments
 (0)