[PATCH v2 bpf-next 04/11] tcp: Split out __tcp_set_rcvlowat().
From: Kuniyuki Iwashima <kuniyu@google.com>
Date: 2026-05-22 07:46:09
Also in:
bpf
Subsystem:
networking [general], networking [tcp], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Neal Cardwell, Linus Torvalds
We will add a kfunc for BPF_SOCK_OPS_RCVQ_CB hooks to adjust sk->sk_rcvlowat. These hooks will be triggered when: 1. TCP stack enqueues skb to sk->sk_receive_queue 2. TCP recvmsg() completes In the enqueue path, tcp_data_ready() is always called after the hooks in tcp_queue_rcv() and tcp_ofo_queue(). If tcp_set_rcvlowat() were used as is, tcp_data_ready() could be called twice for the same skb, which is redundant and also confusing. Let's split out __tcp_set_rcvlowat() and add a flag to control wakeup behaviour. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> --- include/net/tcp.h | 1 + net/ipv4/tcp.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ecbadcb3a744..c6a6853909c4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h@@ -515,6 +515,7 @@ void tcp_set_keepalive(struct sock *sk, int val); void tcp_syn_ack_timeout(const struct request_sock *req); int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags); +int __tcp_set_rcvlowat(struct sock *sk, int val, bool wakeup); int tcp_set_rcvlowat(struct sock *sk, int val); void tcp_set_rcvbuf(struct sock *sk, int val); int tcp_set_window_clamp(struct sock *sk, int val);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 432fa28e47d4..3afeb69a547a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c@@ -1829,8 +1829,7 @@ int tcp_peek_len(struct socket *sock) return tcp_inq(sock->sk); } -/* Make sure sk_rcvbuf is big enough to satisfy SO_RCVLOWAT hint */ -int tcp_set_rcvlowat(struct sock *sk, int val) +int __tcp_set_rcvlowat(struct sock *sk, int val, bool wakeup) { struct tcp_sock *tp = tcp_sk(sk); int space, cap;
@@ -1843,7 +1842,8 @@ int tcp_set_rcvlowat(struct sock *sk, int val) WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); /* Check if we need to signal EPOLLIN right now */ - tcp_data_ready(sk); + if (wakeup) + tcp_data_ready(sk); if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) return 0;
@@ -1858,6 +1858,12 @@ int tcp_set_rcvlowat(struct sock *sk, int val) return 0; } +/* Make sure sk_rcvbuf is big enough to satisfy SO_RCVLOWAT hint */ +int tcp_set_rcvlowat(struct sock *sk, int val) +{ + return __tcp_set_rcvlowat(sk, val, true); +} + void tcp_set_rcvbuf(struct sock *sk, int val) { tcp_set_window_clamp(sk, tcp_win_from_space(sk, val));
--
2.54.0.746.g67dd491aae-goog