| From 59091c56f3cbd00d8b353827559198767db1abb3 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sun, 4 Feb 2024 18:16:56 -0500 |
| Subject: svcrdma: Increase the per-transport rw_ctx count |
| |
| From: Chuck Lever <chuck.lever@oracle.com> |
| |
| [ Upstream commit 2da0f610e733606e06284ac3c1f188b9dec75d68 ] |
| |
| rdma_rw_mr_factor() returns the smallest number of MRs needed to |
| move a particular number of pages. svcrdma currently asks for the |
| number of MRs needed to move RPCSVC_MAXPAGES (a little over one |
| megabyte), as that is the number of pages in the largest r/wsize |
| the server supports. |
| |
| This call assumes that the client's NIC can bundle a full one |
| megabyte payload in a single rdma_segment. In fact, most NICs cannot |
| handle a full megabyte with a single rkey / rdma_segment. Clients |
| will typically split even a single Read chunk into many segments. |
| |
| The server needs one MR to read each rdma_segment in a Read chunk, |
| and thus each one needs an rw_ctx. |
| |
| svcrdma has been vastly underestimating the number of rw_ctxs needed |
| to handle 64 RPC requests with large Read chunks using small |
| rdma_segments. |
| |
| Unfortunately there doesn't seem to be a good way to estimate this |
| number without knowing the client NIC's capabilities. Even then, |
| the client RPC/RDMA implementation is still free to split a chunk |
| into smaller segments (for example, it might be using physical |
| registration, which needs an rdma_segment per page). |
| |
| The best we can do for now is choose a number that will guarantee |
| forward progress in the worst case (one page per segment). |
| |
| At some later point, we could add some mechanisms to make this |
| much less of a problem: |
| - Add a core API to add more rw_ctxs to an already-established QP |
| - svcrdma could treat rw_ctx exhaustion as a temporary error and |
| try again |
| - Limit the number of Reads in flight |
| |
| Signed-off-by: Chuck Lever <chuck.lever@oracle.com> |
| Stable-dep-of: afcae7d7b8a2 ("RDMA/core: add rdma_rw_max_sge() helper for SQ sizing") |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/sunrpc/xprtrdma/svc_rdma_transport.c | 9 +++++++-- |
| 1 file changed, 7 insertions(+), 2 deletions(-) |
| |
| diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c |
| index 31e6f4a14bbc0..3d3b15f9d6d51 100644 |
| --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c |
| +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c |
| @@ -417,8 +417,13 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) |
| newxprt->sc_max_requests = rq_depth - 2; |
| newxprt->sc_max_bc_requests = 2; |
| } |
| - ctxts = rdma_rw_mr_factor(dev, newxprt->sc_port_num, RPCSVC_MAXPAGES); |
| - ctxts *= newxprt->sc_max_requests; |
| + |
| + /* Arbitrarily estimate the number of rw_ctxs needed for |
| + * this transport. This is enough rw_ctxs to make forward |
| + * progress even if the client is using one rkey per page |
| + * in each Read chunk. |
| + */ |
| + ctxts = 3 * RPCSVC_MAXPAGES; |
| newxprt->sc_sq_depth = rq_depth + ctxts; |
| if (newxprt->sc_sq_depth > dev->attrs.max_qp_wr) |
| newxprt->sc_sq_depth = dev->attrs.max_qp_wr; |
| -- |
| 2.51.0 |
| |