Commit 02754103 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'rxrpc-miscellaneous-fixes'

David Howells says:

====================
rxrpc: Miscellaneous fixes (part)

Here some miscellaneous fixes for AF_RXRPC:

 (1) Fix the congestion control algorithm to start cwnd at 4 and to not cut
     ssthresh when the peer cuts its rwind size.

 (2) Only transmit a single ACK for all the DATA packets glued together
     into a jumbo packet to reduce the number of ACKs being generated.
====================

Link: https://lore.kernel.org/r/20240503150749.1001323-1-dhowells@redhat.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 9a169c26 012b7206
...@@ -697,7 +697,7 @@ struct rxrpc_call { ...@@ -697,7 +697,7 @@ struct rxrpc_call {
* packets) rather than bytes. * packets) rather than bytes.
*/ */
#define RXRPC_TX_SMSS RXRPC_JUMBO_DATALEN #define RXRPC_TX_SMSS RXRPC_JUMBO_DATALEN
#define RXRPC_MIN_CWND (RXRPC_TX_SMSS > 2190 ? 2 : RXRPC_TX_SMSS > 1095 ? 3 : 4) #define RXRPC_MIN_CWND 4
u8 cong_cwnd; /* Congestion window size */ u8 cong_cwnd; /* Congestion window size */
u8 cong_extra; /* Extra to send for congestion management */ u8 cong_extra; /* Extra to send for congestion management */
u8 cong_ssthresh; /* Slow-start threshold */ u8 cong_ssthresh; /* Slow-start threshold */
......
...@@ -174,12 +174,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp, ...@@ -174,12 +174,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
call->rx_winsize = rxrpc_rx_window_size; call->rx_winsize = rxrpc_rx_window_size;
call->tx_winsize = 16; call->tx_winsize = 16;
if (RXRPC_TX_SMSS > 2190) call->cong_cwnd = RXRPC_MIN_CWND;
call->cong_cwnd = 2;
else if (RXRPC_TX_SMSS > 1095)
call->cong_cwnd = 3;
else
call->cong_cwnd = 4;
call->cong_ssthresh = RXRPC_TX_MAX_WINDOW; call->cong_ssthresh = RXRPC_TX_MAX_WINDOW;
call->rxnet = rxnet; call->rxnet = rxnet;
......
...@@ -9,6 +9,17 @@ ...@@ -9,6 +9,17 @@
#include "ar-internal.h" #include "ar-internal.h"
/* Override priority when generating ACKs for received DATA */
static const u8 rxrpc_ack_priority[RXRPC_ACK__INVALID] = {
[RXRPC_ACK_IDLE] = 1,
[RXRPC_ACK_DELAY] = 2,
[RXRPC_ACK_REQUESTED] = 3,
[RXRPC_ACK_DUPLICATE] = 4,
[RXRPC_ACK_EXCEEDS_WINDOW] = 5,
[RXRPC_ACK_NOSPACE] = 6,
[RXRPC_ACK_OUT_OF_SEQUENCE] = 7,
};
static void rxrpc_proto_abort(struct rxrpc_call *call, rxrpc_seq_t seq, static void rxrpc_proto_abort(struct rxrpc_call *call, rxrpc_seq_t seq,
enum rxrpc_abort_reason why) enum rxrpc_abort_reason why)
{ {
...@@ -365,7 +376,7 @@ static void rxrpc_input_queue_data(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -365,7 +376,7 @@ static void rxrpc_input_queue_data(struct rxrpc_call *call, struct sk_buff *skb,
* Process a DATA packet. * Process a DATA packet.
*/ */
static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb, static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
bool *_notify) bool *_notify, rxrpc_serial_t *_ack_serial, int *_ack_reason)
{ {
struct rxrpc_skb_priv *sp = rxrpc_skb(skb); struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
struct sk_buff *oos; struct sk_buff *oos;
...@@ -418,8 +429,6 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -418,8 +429,6 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
/* Send an immediate ACK if we fill in a hole */ /* Send an immediate ACK if we fill in a hole */
else if (!skb_queue_empty(&call->rx_oos_queue)) else if (!skb_queue_empty(&call->rx_oos_queue))
ack_reason = RXRPC_ACK_DELAY; ack_reason = RXRPC_ACK_DELAY;
else
call->ackr_nr_unacked++;
window++; window++;
if (after(window, wtop)) { if (after(window, wtop)) {
...@@ -497,12 +506,16 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb, ...@@ -497,12 +506,16 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
} }
send_ack: send_ack:
if (ack_reason >= 0) if (ack_reason >= 0) {
rxrpc_send_ACK(call, ack_reason, serial, if (rxrpc_ack_priority[ack_reason] > rxrpc_ack_priority[*_ack_reason]) {
rxrpc_propose_ack_input_data); *_ack_serial = serial;
else *_ack_reason = ack_reason;
rxrpc_propose_delay_ACK(call, serial, } else if (rxrpc_ack_priority[ack_reason] == rxrpc_ack_priority[*_ack_reason] &&
rxrpc_propose_ack_input_data); ack_reason == RXRPC_ACK_REQUESTED) {
*_ack_serial = serial;
*_ack_reason = ack_reason;
}
}
} }
/* /*
...@@ -513,9 +526,11 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb ...@@ -513,9 +526,11 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
struct rxrpc_jumbo_header jhdr; struct rxrpc_jumbo_header jhdr;
struct rxrpc_skb_priv *sp = rxrpc_skb(skb), *jsp; struct rxrpc_skb_priv *sp = rxrpc_skb(skb), *jsp;
struct sk_buff *jskb; struct sk_buff *jskb;
rxrpc_serial_t ack_serial = 0;
unsigned int offset = sizeof(struct rxrpc_wire_header); unsigned int offset = sizeof(struct rxrpc_wire_header);
unsigned int len = skb->len - offset; unsigned int len = skb->len - offset;
bool notify = false; bool notify = false;
int ack_reason = 0;
while (sp->hdr.flags & RXRPC_JUMBO_PACKET) { while (sp->hdr.flags & RXRPC_JUMBO_PACKET) {
if (len < RXRPC_JUMBO_SUBPKTLEN) if (len < RXRPC_JUMBO_SUBPKTLEN)
...@@ -535,7 +550,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb ...@@ -535,7 +550,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
jsp = rxrpc_skb(jskb); jsp = rxrpc_skb(jskb);
jsp->offset = offset; jsp->offset = offset;
jsp->len = RXRPC_JUMBO_DATALEN; jsp->len = RXRPC_JUMBO_DATALEN;
rxrpc_input_data_one(call, jskb, &notify); rxrpc_input_data_one(call, jskb, &notify, &ack_serial, &ack_reason);
rxrpc_free_skb(jskb, rxrpc_skb_put_jumbo_subpacket); rxrpc_free_skb(jskb, rxrpc_skb_put_jumbo_subpacket);
sp->hdr.flags = jhdr.flags; sp->hdr.flags = jhdr.flags;
...@@ -548,7 +563,16 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb ...@@ -548,7 +563,16 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
sp->offset = offset; sp->offset = offset;
sp->len = len; sp->len = len;
rxrpc_input_data_one(call, skb, &notify); rxrpc_input_data_one(call, skb, &notify, &ack_serial, &ack_reason);
if (ack_reason > 0) {
rxrpc_send_ACK(call, ack_reason, ack_serial,
rxrpc_propose_ack_input_data);
} else {
call->ackr_nr_unacked++;
rxrpc_propose_delay_ACK(call, sp->hdr.serial,
rxrpc_propose_ack_input_data);
}
if (notify) { if (notify) {
trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial); trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial);
rxrpc_notify_socket(call); rxrpc_notify_socket(call);
...@@ -685,9 +709,6 @@ static void rxrpc_input_ack_trailer(struct rxrpc_call *call, struct sk_buff *skb ...@@ -685,9 +709,6 @@ static void rxrpc_input_ack_trailer(struct rxrpc_call *call, struct sk_buff *skb
call->tx_winsize = rwind; call->tx_winsize = rwind;
} }
if (call->cong_ssthresh > rwind)
call->cong_ssthresh = rwind;
mtu = min(ntohl(trailer->maxMTU), ntohl(trailer->ifMTU)); mtu = min(ntohl(trailer->maxMTU), ntohl(trailer->ifMTU));
peer = call->peer; peer = call->peer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment