Re: [PATCH RFC 2/3] SUNRPC: dispatch idle transports ahead of backlogged ones

Benjamin Coddington <ben.coddington-F/[email protected]>
Newsgroups gmane.linux.nfs
Message-ID <[email protected]>
On 25 Jun 2026, at 12:09, Chuck Lever wrote:

> On Wed, Jun 24, 2026, at 1:04 PM, Benjamin Coddington wrote:
>> A pool dispatches ready transports in FIFO order, so a connection that
>> already has requests in flight sits in the same queue, on equal terms,
>> as one that has been idle.  A client driving many concurrent requests
>> therefore delays the next request of an interactive client whose
>> previous reply has already completed: the interactive request waits
>> behind the busy client's backlog even though servicing it costs a
>> single round trip.
>
>> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
>> index 63d1002e63e7..ec4c05094e9a 100644
>> --- a/net/sunrpc/svc_xprt.c
>> +++ b/net/sunrpc/svc_xprt.c
>> @@ -523,7 +523,10 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
>>
>>  	percpu_counter_inc(&pool->sp_sockets_queued);
>>  	xprt->xpt_qtime = ktime_get();
>> -	lwq_enqueue(&xprt->xpt_ready, &pool->sp_xprts);
>> +	if (atomic_read(&xprt->xpt_nr_rqsts))
>> +		lwq_enqueue(&xprt->xpt_ready, &pool->sp_xprts);
>> +	else
>> +		lwq_enqueue(&xprt->xpt_ready, &pool->sp_xprts_hi);
>>
>>  	svc_pool_wake_idle_thread(pool);
>>  }
>
> The classification is keyed on in-flight request count, but a deferred
> close is enqueued the same way.  svc_xprt_deferred_close() sets
> XPT_CLOSE and calls svc_xprt_enqueue() while the slot is still held;
> svc_rdma_sendto() on a send error is one such path, and
> svc_check_conn_limits() is another.  svc_handle_xprt() reserves the
> slot before calling recvfrom and releases it only after svc_process()
> returns; recvfrom clears XPT_BUSY in between (svc_rdma_recvfrom ->
> svc_xprt_received).  So the deferred close is enqueued with XPT_BUSY
> clear and xpt_nr_rqsts != 0, and the close lands on sp_xprts.  Since
> svc_xprt_dequeue() drains sp_xprts_hi first, the teardown waits behind
> idle-flow traffic precisely when the server is busy and wants the
> resources back.
>
> Control work isn't request work, and svc_xprt_ready() already treats
> XPT_CONN|XPT_CLOSE|XPT_HANDSHAKE as a class distinct from XPT_DATA.
> Routing that class to the high-priority queue regardless of the request
> count keeps the two consistent:
>
>   if (xprt->xpt_flags & (BIT(XPT_CONN) | BIT(XPT_CLOSE) |
>                        BIT(XPT_HANDSHAKE)) ||
>       !atomic_read(&xprt->xpt_nr_rqsts))
>         lwq_enqueue(&xprt->xpt_ready, &pool->sp_xprts_hi);
>   else
>         lwq_enqueue(&xprt->xpt_ready, &pool->sp_xprts);
>
> The burst-allowance patch narrows this -- a close with credit left
> rides sp_xprts_hi -- but a flow that has spent its budget still routes
> its close to the bulk queue, so the gap remains for exactly the
> backlogged connections most worth closing promptly.

Excellent - if we v1, I'll add this fix.

> You should also have a look at the pre-existing issue that sashiko
> identified: it might be amplified by this patch, so we should
> consider addressing that issue as a pre-requisite to this series.
>
> https://sashiko.dev/#/patchset/[email protected]?part=2

I'll head over there (cool - sashiko looks smart) and give that issue attention for any v1.

Ben
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.