Skip to content

Commit 5924331

Browse files
committed
svcrdma: Reduce the number of rdma_rw contexts per-QP
There is an upper bound on the number of rdma_rw contexts that can be created per QP. This invisible upper bound is because rdma_create_qp() adds one or more additional SQEs for each ctxt that the ULP requests via qp_attr.cap.max_rdma_ctxs. The QP's actual Send Queue length is on the order of the sum of qp_attr.cap.max_send_wr and a factor times qp_attr.cap.max_rdma_ctxs. The factor can be up to three, depending on whether MR operations are required before RDMA Reads. This limit is not visible to RDMA consumers via dev->attrs. When the limit is surpassed, QP creation fails with -ENOMEM. For example: svcrdma's estimate of the number of rdma_rw contexts it needs is three times the number of pages in RPCSVC_MAXPAGES. When MAXPAGES is about 260, the internally-computed SQ length should be: 64 credits + 10 backlog + 3 * (3 * 260) = 2414 Which is well below the advertised qp_max_wr of 32768. If RPCSVC_MAXPAGES is increased to 4MB, that's 1040 pages: 64 credits + 10 backlog + 3 * (3 * 1040) = 9434 However, QP creation fails. Dynamic printk for mlx5 shows: calc_sq_size:618:(pid 1514): send queue size (9326 * 256 / 64 -> 65536) exceeds limits(32768) Although 9326 is still far below qp_max_wr, QP creation still fails. Because the total SQ length calculation is opaque to RDMA consumers, there doesn't seem to be much that can be done about this except for consumers to try to keep the requested rdma_rw ctxt count low. Fixes: 2da0f61 ("svcrdma: Increase the per-transport rw_ctx count") Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 155a141 commit 5924331

1 file changed

Lines changed: 8 additions & 6 deletions

File tree

net/sunrpc/xprtrdma/svc_rdma_transport.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,12 @@ static void svc_rdma_xprt_done(struct rpcrdma_notification *rn)
406406
*/
407407
static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
408408
{
409+
unsigned int ctxts, rq_depth, maxpayload;
409410
struct svcxprt_rdma *listen_rdma;
410411
struct svcxprt_rdma *newxprt = NULL;
411412
struct rdma_conn_param conn_param;
412413
struct rpcrdma_connect_private pmsg;
413414
struct ib_qp_init_attr qp_attr;
414-
unsigned int ctxts, rq_depth;
415415
struct ib_device *dev;
416416
int ret = 0;
417417
RPC_IFDEBUG(struct sockaddr *sap);
@@ -462,12 +462,14 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
462462
newxprt->sc_max_bc_requests = 2;
463463
}
464464

465-
/* Arbitrarily estimate the number of rw_ctxs needed for
466-
* this transport. This is enough rw_ctxs to make forward
467-
* progress even if the client is using one rkey per page
468-
* in each Read chunk.
465+
/* Arbitrary estimate of the needed number of rdma_rw contexts.
469466
*/
470-
ctxts = 3 * RPCSVC_MAXPAGES;
467+
maxpayload = min(xprt->xpt_server->sv_max_payload,
468+
RPCSVC_MAXPAYLOAD_RDMA);
469+
ctxts = newxprt->sc_max_requests * 3 *
470+
rdma_rw_mr_factor(dev, newxprt->sc_port_num,
471+
maxpayload >> PAGE_SHIFT);
472+
471473
newxprt->sc_sq_depth = rq_depth + ctxts;
472474
if (newxprt->sc_sq_depth > dev->attrs.max_qp_wr)
473475
newxprt->sc_sq_depth = dev->attrs.max_qp_wr;

0 commit comments

Comments
 (0)