Thread (6 messages) 6 messages, 3 authors, 2026-09-05

[PATCH net-next v9 2/2] bpf: make tcp_tso_autosize() available to BPF congestion controls

flat view
COLD37d

From: <hidden>
Date: 2026-08-31 16:52:53
Also in: bpf, linux-kselftest
Subsystem: networking [general], networking [tcp], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Neal Cardwell, Linus Torvalds

Revision v9 of 3 in this series.

Revisions (3)
  1. v7 [diff vs current]
  2. v8 [diff vs current]
  3. v9 current
From: Chia-Yu Chang <redacted>

Expose tcp_tso_autosize() as a BPF kfunc and register it in the TCP
congestion-control kfunc set. This allows BPF congestion controls to
reuse the kernel TSO autosizing logic while applying their own
minimum TSO segment policy.

To make the kfunc robust against BPF-provided inputs, min_tso_segs is
sanitized to at least 1 and mss_now == 0 returns the sanitized minimum
value instead of performing autosizing.

Signed-off-by: Chia-Yu Chang <redacted>

--
v8:
- Sanitize min_tso_segs in tcp_tso_autosize()
- Return sanitized min_tso_segs when mss_now == 0
- Update commit messages
---
 net/ipv4/bpf_tcp_ca.c |  1 +
 net/ipv4/tcp_output.c | 14 +++++++++++---
 2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c
index ed4fea98dfde..9deed2244c2d 100644
--- a/net/ipv4/bpf_tcp_ca.c
+++ b/net/ipv4/bpf_tcp_ca.c
@@ -194,6 +194,7 @@ BTF_ID_FLAGS(func, tcp_reno_cong_avoid)
 BTF_ID_FLAGS(func, tcp_reno_undo_cwnd)
 BTF_ID_FLAGS(func, tcp_slow_start)
 BTF_ID_FLAGS(func, tcp_cong_avoid_ai)
+BTF_ID_FLAGS(func, tcp_tso_autosize)
 BTF_KFUNCS_END(bpf_tcp_ca_check_kfunc_ids)
 
 static const struct btf_kfunc_id_set bpf_tcp_ca_kfunc_set = {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index b1b493d46b9c..b7f2ee5e7a6b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2252,13 +2252,21 @@ static bool tcp_nagle_check(bool partial, const struct tcp_sock *tp,
  * in bigger TSO bursts. We we cut the RTT-based allowance in half
  * for every 2^9 usec (aka 512 us) of RTT, so that the RTT-based allowance
  * is below 1500 bytes after 6 * ~500 usec = 3ms.
+ *
+ * The min_tso_segs is floored to 1 to avoid surprising conversion. Also,
+ * BPF callers may pass mss_now == 0. In that case the function returns the
+ * sanitized min_tso_segs value and skips autosizing.
  */
-u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
-		     int min_tso_segs)
+__bpf_kfunc u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
+				 int min_tso_segs)
 {
+	u32 min_tso = max(min_tso_segs, 1);
 	unsigned long bytes;
 	u32 r;
 
+	if (unlikely(!mss_now))
+		return min_tso;
+
 	bytes = READ_ONCE(sk->sk_pacing_rate) >> READ_ONCE(sk->sk_pacing_shift);
 
 	r = tcp_min_rtt(tcp_sk(sk)) >> READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_tso_rtt_log);
@@ -2267,7 +2275,7 @@ u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
 
 	bytes = min_t(unsigned long, bytes, sk->sk_gso_max_size);
 
-	return max_t(u32, bytes / mss_now, min_tso_segs);
+	return max_t(u32, bytes / mss_now, min_tso);
 }
 EXPORT_SYMBOL_GPL(tcp_tso_autosize);
 
-- 
2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help