Commit 22555032 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski

tcp: remove dubious FIN exception from tcp_cwnd_test()

tcp_cwnd_test() has a special handing for the last packet in
the write queue if it is smaller than one MSS and has the FIN flag.

This is in violation of TCP RFC, and seems quite dubious.

This packet can be sent only if the current CWND is bigger
than the number of packets in flight.

Making tcp_cwnd_test() result independent of the first skb
in the write queue is needed for the last patch of the series.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20240418214600.1291486-2-edumazet@google.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f62a5e71
...@@ -2073,16 +2073,10 @@ static unsigned int tcp_mss_split_point(const struct sock *sk, ...@@ -2073,16 +2073,10 @@ static unsigned int tcp_mss_split_point(const struct sock *sk,
/* Can at least one segment of SKB be sent right now, according to the /* Can at least one segment of SKB be sent right now, according to the
* congestion window rules? If so, return how many segments are allowed. * congestion window rules? If so, return how many segments are allowed.
*/ */
static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, static u32 tcp_cwnd_test(const struct tcp_sock *tp)
const struct sk_buff *skb)
{ {
u32 in_flight, cwnd, halfcwnd; u32 in_flight, cwnd, halfcwnd;
/* Don't be strict about the congestion window for the final FIN. */
if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) &&
tcp_skb_pcount(skb) == 1)
return 1;
in_flight = tcp_packets_in_flight(tp); in_flight = tcp_packets_in_flight(tp);
cwnd = tcp_snd_cwnd(tp); cwnd = tcp_snd_cwnd(tp);
if (in_flight >= cwnd) if (in_flight >= cwnd)
...@@ -2706,10 +2700,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, ...@@ -2706,10 +2700,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb; struct sk_buff *skb;
unsigned int tso_segs, sent_pkts; unsigned int tso_segs, sent_pkts;
int cwnd_quota; u32 cwnd_quota, max_segs;
int result; int result;
bool is_cwnd_limited = false, is_rwnd_limited = false; bool is_cwnd_limited = false, is_rwnd_limited = false;
u32 max_segs;
sent_pkts = 0; sent_pkts = 0;
...@@ -2743,7 +2736,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, ...@@ -2743,7 +2736,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
tso_segs = tcp_init_tso_segs(skb, mss_now); tso_segs = tcp_init_tso_segs(skb, mss_now);
BUG_ON(!tso_segs); BUG_ON(!tso_segs);
cwnd_quota = tcp_cwnd_test(tp, skb); cwnd_quota = tcp_cwnd_test(tp);
if (!cwnd_quota) { if (!cwnd_quota) {
if (push_one == 2) if (push_one == 2)
/* Force out a loss probe pkt. */ /* Force out a loss probe pkt. */
...@@ -2772,8 +2765,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, ...@@ -2772,8 +2765,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
limit = mss_now; limit = mss_now;
if (tso_segs > 1 && !tcp_urg_mode(tp)) if (tso_segs > 1 && !tcp_urg_mode(tp))
limit = tcp_mss_split_point(sk, skb, mss_now, limit = tcp_mss_split_point(sk, skb, mss_now,
min_t(unsigned int, min(cwnd_quota,
cwnd_quota,
max_segs), max_segs),
nonagle); nonagle);
......
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