[PATCH mptcp-next v6 6/7] mptcp: track app-limited state in mptcp_sendmsg
Geliang Tang <[email protected]>
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <d9f714b2c6013166635975261ba96b16cfbf5083.1787446274.git.tanggeliang@kylinos.cn> |
From: Geliang Tang <[email protected]> The application-limited accounting in TCP is updated by tcp_rate_check_app_limited(), which currently takes a struct sock * and internally calls tcp_sk(). MPTCP needs to apply the same accounting to each subflow individually - every subflow is an independent TCP socket with its own tp->app_limited / delivered state - so wrapping the call as a struct sock * -> tcp_sk() helper is awkward at the call site. Split the existing function: keep the logic as tcp_sock_rate_check_app_limited(struct tcp_sock *tp), and turn tcp_rate_check_app_limited(struct sock *) into a thin wrapper so the exported API is unchanged for other TCP users. Then add mptcp_sock_rate_check_app_limited() that walks every subflow of the mptcp_sock and runs tcp_sock_rate_check_app_limited() under each subflow's socket lock. Invoke it from mptcp_sendmsg() right after the send-side setup, so the delivery-rate app_limited state stays in sync with what the application actually has to send across each subflow. With this in place, TCP_INFO.tcpi_delivery_rate_app_limited is reported correctly for MPTCP connections instead of being left at 0. Signed-off-by: Geliang Tang <[email protected]> --- include/net/tcp.h | 1 + net/ipv4/tcp.c | 9 +++++++-- net/mptcp/protocol.c | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 2c5b889530b5..9d436816411b 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -849,6 +849,7 @@ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize) /* tcp.c */ void tcp_get_info(struct sock *, struct tcp_info *); +void tcp_sock_rate_check_app_limited(struct tcp_sock *tp); void tcp_rate_check_app_limited(struct sock *sk); /* Read 'sendfile()'-style from a TCP socket */ diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 1452c40e22d4..f0f843fd1897 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1096,9 +1096,9 @@ int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *copied, } /* If a gap is detected between sends, mark the socket application-limited. */ -void tcp_rate_check_app_limited(struct sock *sk) +void tcp_sock_rate_check_app_limited(struct tcp_sock *tp) { - struct tcp_sock *tp = tcp_sk(sk); + struct sock *sk = (struct sock *)tp; if (/* We have less than one packet to send. */ tp->write_seq - tp->snd_nxt < tp->mss_cache && @@ -1111,6 +1111,11 @@ void tcp_rate_check_app_limited(struct sock *sk) tp->app_limited = (tp->delivered + tcp_packets_in_flight(tp)) ? : 1; } + +void tcp_rate_check_app_limited(struct sock *sk) +{ + tcp_sock_rate_check_app_limited(tcp_sk(sk)); +} EXPORT_SYMBOL_GPL(tcp_rate_check_app_limited); int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 3e3461e5804e..f39c62f956c4 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2048,6 +2048,21 @@ static void mptcp_rps_record_subflows(const struct mptcp_sock *msk) } } +static void mptcp_sock_rate_check_app_limited(struct sock *sk) +{ + struct mptcp_sock *msk = mptcp_sk(sk); + struct mptcp_subflow_context *subflow; + + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + bool slow; + + slow = lock_sock_fast_nested(ssk); + tcp_sock_rate_check_app_limited(tcp_sk(ssk)); + unlock_sock_fast(ssk, slow); + } +} + static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) { struct mptcp_sock *msk = mptcp_sk(sk); @@ -2078,6 +2093,9 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); + /* is sending application-limited? */ + mptcp_sock_rate_check_app_limited(sk); + if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) { ret = sk_stream_wait_connect(sk, &timeo); if (ret) -- 2.53.0