Skip to content

Commit

Permalink
xprtrdma: Limit data payload size for ALLPHYSICAL
Browse files Browse the repository at this point in the history
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 <chuck.lever@oracle.com>
Tested-by: Steve Wise <swise@opengridcomputing.com>
Tested-by: Shirley Ma <shirley.ma@oracle.com>
Tested-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
  • Loading branch information
Chuck Lever authored and Anna Schumaker committed Jul 31, 2014
1 parent 73806c8 commit 43e9598
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
4 changes: 3 additions & 1 deletion net/sunrpc/xprtrdma/transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ xprt_setup_rdma(struct xprt_create *args)

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

/*
Expand Down Expand Up @@ -382,6 +381,9 @@ xprt_setup_rdma(struct xprt_create *args)
new_ep->rep_xprt = xprt;

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

if (!try_module_get(THIS_MODULE))
goto out4;
Expand Down
41 changes: 41 additions & 0 deletions net/sunrpc/xprtrdma/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1825,3 +1825,44 @@ rpcrdma_ep_post_recv(struct rpcrdma_ia *ia,
rc);
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.
*/
static size_t
rpcrdma_physical_max_payload(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;
}

static size_t
rpcrdma_mr_max_payload(struct rpcrdma_xprt *r_xprt)
{
return RPCRDMA_MAX_DATA_SEGS << PAGE_SHIFT;
}

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;
}
1 change: 1 addition & 0 deletions net/sunrpc/xprtrdma/xprt_rdma.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *);
* RPC/RDMA protocol calls - xprtrdma/rpc_rdma.c
*/
int rpcrdma_marshal_req(struct rpc_rqst *);
size_t rpcrdma_max_payload(struct rpcrdma_xprt *);

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

0 comments on commit 43e9598

Please sign in to comment.