]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xprtrdma: Scale receive batch size with credit window
authorChuck Lever <chuck.lever@oracle.com>
Fri, 6 Mar 2026 21:56:27 +0000 (16:56 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 13 Apr 2026 19:05:00 +0000 (12:05 -0700)
The fixed RPCRDMA_MAX_RECV_BATCH of 7 results in frequent
small ib_post_recv batches during high-rate workloads. With
a 128-slot credit window, receives are reposted every 7th
completion, each batch incurring atomic serialization and a
doorbell write.

Replace the fixed batch constant with a per-endpoint value
scaled to 25% of the negotiated credit window. For a typical
128-credit connection this raises the batch from 7 to 32,
reducing doorbell frequency by roughly 4x and amortizing the
per-batch atomic and MMIO costs over a larger group of
receive WRs.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtrdma/xprt_rdma.h

index 229057d35fb8063ee49c473db863195e09535427..7f79a0a2601e65ca1b78f4e1bef621a80af106b9 100644 (file)
@@ -244,9 +244,10 @@ int frwr_query_device(struct rpcrdma_ep *ep, const struct ib_device *device)
        }
        ep->re_attr.cap.max_send_wr += RPCRDMA_BACKWARD_WRS;
        ep->re_attr.cap.max_send_wr += 1; /* for ib_drain_sq */
+       ep->re_recv_batch = ep->re_max_requests >> 2;
        ep->re_attr.cap.max_recv_wr = ep->re_max_requests;
        ep->re_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS;
-       ep->re_attr.cap.max_recv_wr += RPCRDMA_MAX_RECV_BATCH;
+       ep->re_attr.cap.max_recv_wr += ep->re_recv_batch;
        ep->re_attr.cap.max_recv_wr += 1; /* for ib_drain_rq */
 
        ep->re_max_rdma_segs =
index 90fd83f2d8469c84e66bdefc57c6b2fd9522ef8e..aecf9c0a153f365991210b46cb3714e347b0c81c 100644 (file)
@@ -1374,7 +1374,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed)
        if (likely(ep->re_receive_count > needed))
                goto out;
        needed -= ep->re_receive_count;
-       needed += RPCRDMA_MAX_RECV_BATCH;
+       needed += ep->re_recv_batch;
 
        if (atomic_inc_return(&ep->re_receiving) > 1)
                goto out_dec;
index 37bba72065e8fa39fb24534acb1ff505f88fc94f..f53a7747272451f8280fcfda61d1b1f94ee3876a 100644 (file)
@@ -96,6 +96,7 @@ struct rpcrdma_ep {
        struct rpcrdma_notification     re_rn;
        int                     re_receive_count;
        unsigned int            re_max_requests; /* depends on device */
+       unsigned int            re_recv_batch;
        unsigned int            re_inline_send; /* negotiated */
        unsigned int            re_inline_recv; /* negotiated */