mirror of https://gitee.com/openkylin/linux.git
xprtrdma: Fix ri_max_segs and the result of ro_maxpages
With certain combinations of krb5i/p, MR size, and r/wsize, I/O can fail with EMSGSIZE. This is because the calculated value of ri_max_segs (the max number of MRs per RPC) exceeded RPCRDMA_MAX_HDR_SEGS, which caused Read or Write list encoding to walk off the end of the transport header. Once that was addressed, the ro_maxpages result has to be corrected to account for the number of MRs needed for Reply chunks, which is 2 MRs smaller than a normal Read or Write chunk. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
0c0829bcf5
commit
6946f82380
|
@ -176,7 +176,10 @@ fmr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
|||
|
||||
ia->ri_max_segs = max_t(unsigned int, 1, RPCRDMA_MAX_DATA_SEGS /
|
||||
RPCRDMA_MAX_FMR_SGES);
|
||||
ia->ri_max_segs += 2; /* segments for head and tail buffers */
|
||||
/* Reply chunks require segments for head and tail buffers */
|
||||
ia->ri_max_segs += 2;
|
||||
if (ia->ri_max_segs > RPCRDMA_MAX_HDR_SEGS)
|
||||
ia->ri_max_segs = RPCRDMA_MAX_HDR_SEGS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -186,7 +189,7 @@ static size_t
|
|||
fmr_op_maxpages(struct rpcrdma_xprt *r_xprt)
|
||||
{
|
||||
return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
|
||||
RPCRDMA_MAX_HDR_SEGS * RPCRDMA_MAX_FMR_SGES);
|
||||
(r_xprt->rx_ia.ri_max_segs - 2) * RPCRDMA_MAX_FMR_SGES);
|
||||
}
|
||||
|
||||
/* Use the ib_map_phys_fmr() verb to register a memory region
|
||||
|
|
|
@ -244,7 +244,10 @@ frwr_op_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep,
|
|||
|
||||
ia->ri_max_segs = max_t(unsigned int, 1, RPCRDMA_MAX_DATA_SEGS /
|
||||
ia->ri_max_frwr_depth);
|
||||
ia->ri_max_segs += 2; /* segments for head and tail buffers */
|
||||
/* Reply chunks require segments for head and tail buffers */
|
||||
ia->ri_max_segs += 2;
|
||||
if (ia->ri_max_segs > RPCRDMA_MAX_HDR_SEGS)
|
||||
ia->ri_max_segs = RPCRDMA_MAX_HDR_SEGS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -257,7 +260,7 @@ 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_HDR_SEGS * ia->ri_max_frwr_depth);
|
||||
(ia->ri_max_segs - 2) * ia->ri_max_frwr_depth);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -703,8 +703,10 @@ xprt_rdma_free(struct rpc_task *task)
|
|||
* %-ENOTCONN if the caller should reconnect and call again
|
||||
* %-EAGAIN if the caller should call again
|
||||
* %-ENOBUFS if the caller should call again after a delay
|
||||
* %-EIO if a permanent error occurred and the request was not
|
||||
* sent. Do not try to send this message again.
|
||||
* %-EMSGSIZE if encoding ran out of buffer space. The request
|
||||
* was not sent. Do not try to send this message again.
|
||||
* %-EIO if an I/O error occurred. The request was not sent.
|
||||
* Do not try to send this message again.
|
||||
*/
|
||||
static int
|
||||
xprt_rdma_send_request(struct rpc_rqst *rqst)
|
||||
|
|
Loading…
Reference in New Issue