From: Chia-Yu Chang <[email protected]>

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.

Add a selftest exercising tcp_tso_autosize() from a BPF congestion
control through the tso_segs() callback.

Signed-off-by: Chia-Yu Chang <[email protected]>
---
 net/ipv4/bpf_tcp_ca.c                            | 1 +
 net/ipv4/tcp_output.c                            | 4 ++--
 tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c | 8 ++++++++
 3 files changed, 11 insertions(+), 2 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 7d3e0e715c4b..7914287dd571 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2253,8 +2253,8 @@ static bool tcp_nagle_check(bool partial, const struct 
tcp_sock *tp,
  * 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.
  */
-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)
 {
        unsigned long bytes;
        u32 r;
diff --git a/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c 
b/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c
index 58262e490336..c0f8f20f3052 100644
--- a/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c
+++ b/tools/testing/selftests/bpf/progs/tcp_ca_kfunc.c
@@ -28,6 +28,8 @@ extern void cubictcp_state(struct sock *sk, u8 new_state) 
__ksym;
 extern void cubictcp_cwnd_event_tx_start(struct sock *sk) __ksym;
 extern void cubictcp_acked(struct sock *sk, const struct ack_sample *sample) 
__ksym;
 
+extern u32 tcp_tso_autosize(const struct sock *sk, u32 mss_now, int 
min_tso_segs) __ksym;
+
 SEC("struct_ops")
 void BPF_PROG(init, struct sock *sk)
 {
@@ -109,6 +111,12 @@ void BPF_PROG(pkts_acked, struct sock *sk, const struct 
ack_sample *sample)
        cubictcp_acked(sk, sample);
 }
 
+SEC("struct_ops")
+void BPF_PROG(tso_segs, struct sock *sk, u32 mss_now)
+{
+       return tcp_tso_autosize(sk, mss_now, 1);
+}
+
 SEC(".struct_ops")
 struct tcp_congestion_ops tcp_ca_kfunc = {
        .init           = (void *)init,
-- 
2.34.1


Reply via email to