Commit 0cd3e3f3 authored by Marc Dionne's avatar Marc Dionne Committed by Jakub Kicinski
Browse files

rxrpc: Fix to request an ack if window is limited



Peers may only send immediate acks for every 2 UDP packets received.
When sending a jumbogram, it is important to check that there is
sufficient window space to send another same sized jumbogram following
the current one, and request an ack if there isn't.  Failure to do so may
cause the call to stall waiting for an ack until the resend timer fires.

Where jumbograms are in use this causes a very significant drop in
performance.

Fixes: fe24a549 ("rxrpc: Send jumbo DATA packets")
Signed-off-by: default avatarMarc Dionne <marc.dionne@auristor.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Jeffrey Altman <jaltman@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/20260408121252.2249051-10-dhowells@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent d666540d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -521,6 +521,7 @@
#define rxrpc_req_ack_traces \
	EM(rxrpc_reqack_ack_lost,		"ACK-LOST  ")	\
	EM(rxrpc_reqack_app_stall,		"APP-STALL ")	\
	EM(rxrpc_reqack_jumbo_win,		"JUMBO-WIN ")	\
	EM(rxrpc_reqack_more_rtt,		"MORE-RTT  ")	\
	EM(rxrpc_reqack_no_srv_last,		"NO-SRVLAST")	\
	EM(rxrpc_reqack_old_rtt,		"OLD-RTT   ")	\
+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ struct rxrpc_net {
	atomic_t		stat_tx_jumbo[10];
	atomic_t		stat_rx_jumbo[10];

	atomic_t		stat_why_req_ack[8];
	atomic_t		stat_why_req_ack[9];

	atomic_t		stat_io_loop;
};
+2 −0
Original line number Diff line number Diff line
@@ -479,6 +479,8 @@ static size_t rxrpc_prepare_data_subpacket(struct rxrpc_call *call,
		why = rxrpc_reqack_old_rtt;
	else if (!last && !after(READ_ONCE(call->send_top), txb->seq))
		why = rxrpc_reqack_app_stall;
	else if (call->tx_winsize <= (2 * req->n) || call->cong_cwnd <= (2 * req->n))
		why = rxrpc_reqack_jumbo_win;
	else
		goto dont_set_request_ack;

+3 −2
Original line number Diff line number Diff line
@@ -518,11 +518,12 @@ int rxrpc_stats_show(struct seq_file *seq, void *v)
		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_IDLE]),
		   atomic_read(&rxnet->stat_rx_acks[0]));
	seq_printf(seq,
		   "Why-Req-A: acklost=%u mrtt=%u ortt=%u stall=%u\n",
		   "Why-Req-A: acklost=%u mrtt=%u ortt=%u stall=%u jwin=%u\n",
		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_ack_lost]),
		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_more_rtt]),
		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_old_rtt]),
		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_app_stall]));
		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_app_stall]),
		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_jumbo_win]));
	seq_printf(seq,
		   "Why-Req-A: nolast=%u retx=%u slows=%u smtxw=%u\n",
		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_no_srv_last]),