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
