Message ID | 20250514135642.11203-15-chia-yu.chang@nokia-bell-labs.com |
---|---|
State | New |
Headers | show |
Series | [v7,net-next,01/15] tcp: reorganize SYN ECN code | expand |
On 5/14/25 3:56 PM, chia-yu.chang@nokia-bell-labs.com wrote: > From: Ilpo Järvinen <ij@kernel.org> > > As SACK blocks tend to eat all option space when there are > many holes, it is useful to compromise on sending many SACK > blocks in every ACK and try to fit AccECN option there > by reduction the number of SACK blocks. But never go below > two SACK blocks because of AccECN option. > > As AccECN option is often not put to every ACK, the space > hijack is usually only temporary. > > Signed-off-by: Ilpo Järvinen <ij@kernel.org> > Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com> > --- > net/ipv4/tcp_output.c | 15 ++++++++++++++- > 1 file changed, 14 insertions(+), 1 deletion(-) > > diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c > index b630923c4cef..d9d3cc8dbb5b 100644 > --- a/net/ipv4/tcp_output.c > +++ b/net/ipv4/tcp_output.c > @@ -982,8 +982,21 @@ static int tcp_options_fit_accecn(struct tcp_out_options *opts, int required, > opts->num_accecn_fields--; > size -= TCPOLEN_ACCECN_PERFIELD; > } > - if (opts->num_accecn_fields < required) > + if (opts->num_accecn_fields < required) { > + if (opts->num_sack_blocks > 2) { > + /* Try to fit the option by removing one SACK block */ > + opts->num_sack_blocks--; > + size = tcp_options_fit_accecn(opts, required, > + remaining + > + TCPOLEN_SACK_PERBLOCK, > + max_combine_saving); How deep is the recursion level, worst case? In any case please try to avoid recursion entirely. Possibly a 'goto' statement would help. /P
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index b630923c4cef..d9d3cc8dbb5b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -982,8 +982,21 @@ static int tcp_options_fit_accecn(struct tcp_out_options *opts, int required, opts->num_accecn_fields--; size -= TCPOLEN_ACCECN_PERFIELD; } - if (opts->num_accecn_fields < required) + if (opts->num_accecn_fields < required) { + if (opts->num_sack_blocks > 2) { + /* Try to fit the option by removing one SACK block */ + opts->num_sack_blocks--; + size = tcp_options_fit_accecn(opts, required, + remaining + + TCPOLEN_SACK_PERBLOCK, + max_combine_saving); + if (opts->options & OPTION_ACCECN) + return size - TCPOLEN_SACK_PERBLOCK; + + opts->num_sack_blocks++; + } return 0; + } opts->options |= OPTION_ACCECN; return size;