:p
atchew
Login
From: Geliang Tang <tanggeliang@kylinos.cn> This series optimizes MPTCP's ADD_ADDR retransmission timeout: 1. Renames sysctl to add_addr_timeout_max for clearer semantics 2. Makes timeout adaptive to subflow RTT 3. Updates selftests for the rename The adaptive timeout improves subflow establishment responsiveness while maintaining reliability through the max timeout cap. The rename provides better configuration clarity. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/576 Geliang Tang (3): mptcp: rename add_addr_timeout to add_addr_timeout_max mptcp: make ADD_ADDR timeout adaptive to subflow RTT selftests: mptcp: update for add_addr_timeout_max rename Documentation/networking/mptcp-sysctl.rst | 6 ++--- net/mptcp/ctrl.c | 12 ++++----- net/mptcp/pm.c | 27 ++++++++++++++++--- net/mptcp/protocol.h | 2 +- .../testing/selftests/net/mptcp/mptcp_join.sh | 8 +++--- 5 files changed, 38 insertions(+), 17 deletions(-) -- 2.48.1
From: Geliang Tang <tanggeliang@kylinos.cn> This renames the MPTCP sysctl variable to better reflect its purpose as the maximum ADD_ADDR retransmission timeout. The patch includes updates to: - Documentation/networking/mptcp-sysctl.rst - net/mptcp/ctrl.c - net/mptcp/pm.c - net/mptcp/protocol.h All references to the old variable name have been updated to use the new naming convention. The functionality remains unchanged. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- Documentation/networking/mptcp-sysctl.rst | 6 +++--- net/mptcp/ctrl.c | 12 ++++++------ net/mptcp/pm.c | 6 +++--- net/mptcp/protocol.h | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index XXXXXXX..XXXXXXX 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -XXX,XX +XXX,XX @@ MPTCP Sysfs variables /proc/sys/net/mptcp/* Variables =============================== -add_addr_timeout - INTEGER (seconds) - Set the timeout after which an ADD_ADDR control message will be - resent to an MPTCP peer that has not acknowledged a previous +add_addr_timeout_max - INTEGER (seconds) + Set the maximum value of timeout after which an ADD_ADDR control message + will be resent to an MPTCP peer that has not acknowledged a previous ADD_ADDR message. The default value matches TCP_RTO_MAX. This is a per-namespace diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/ctrl.c +++ b/net/mptcp/ctrl.c @@ -XXX,XX +XXX,XX @@ struct mptcp_pernet { struct ctl_table_header *ctl_table_hdr; #endif - unsigned int add_addr_timeout; + unsigned int add_addr_timeout_max; unsigned int blackhole_timeout; unsigned int close_timeout; unsigned int stale_loss_cnt; @@ -XXX,XX +XXX,XX @@ int mptcp_is_enabled(const struct net *net) return mptcp_get_pernet(net)->mptcp_enabled; } -unsigned int mptcp_get_add_addr_timeout(const struct net *net) +unsigned int mptcp_get_add_addr_timeout_max(const struct net *net) { - return mptcp_get_pernet(net)->add_addr_timeout; + return mptcp_get_pernet(net)->add_addr_timeout_max; } int mptcp_is_checksum_enabled(const struct net *net) @@ -XXX,XX +XXX,XX @@ const char *mptcp_get_scheduler(const struct net *net) static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet) { pernet->mptcp_enabled = 1; - pernet->add_addr_timeout = TCP_RTO_MAX; + pernet->add_addr_timeout_max = TCP_RTO_MAX; pernet->blackhole_timeout = 3600; pernet->syn_retrans_before_tcp_fallback = 2; atomic_set(&pernet->active_disable_times, 0); @@ -XXX,XX +XXX,XX @@ static struct ctl_table mptcp_sysctl_table[] = { .extra2 = SYSCTL_ONE }, { - .procname = "add_addr_timeout", + .procname = "add_addr_timeout_max", .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_jiffies, @@ -XXX,XX +XXX,XX @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet) } table[0].data = &pernet->mptcp_enabled; - table[1].data = &pernet->add_addr_timeout; + table[1].data = &pernet->add_addr_timeout_max; table[2].data = &pernet->checksum_enabled; table[3].data = &pernet->allow_join_initial_addr_port; table[4].data = &pernet->stale_loss_cnt; diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_add_timer(struct timer_list *timer) if (entry->retrans_times < ADD_ADDR_RETRANS_MAX) sk_reset_timer(sk, timer, - jiffies + mptcp_get_add_addr_timeout(sock_net(sk))); + jiffies + mptcp_get_add_addr_timeout_max(sock_net(sk))); spin_unlock_bh(&msk->pm.lock); @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, return false; sk_reset_timer(sk, &add_entry->add_timer, - jiffies + mptcp_get_add_addr_timeout(net)); + jiffies + mptcp_get_add_addr_timeout_max(net)); return true; } @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0); sk_reset_timer(sk, &add_entry->add_timer, - jiffies + mptcp_get_add_addr_timeout(net)); + jiffies + mptcp_get_add_addr_timeout_max(net)); return true; } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -XXX,XX +XXX,XX @@ mptcp_subflow_delegated_next(struct mptcp_delegated_action *delegated) } int mptcp_is_enabled(const struct net *net); -unsigned int mptcp_get_add_addr_timeout(const struct net *net); +unsigned int mptcp_get_add_addr_timeout_max(const struct net *net); int mptcp_is_checksum_enabled(const struct net *net); int mptcp_allow_join_id0(const struct net *net); unsigned int mptcp_stale_loss_cnt(const struct net *net); -- 2.48.1
From: Geliang Tang <tanggeliang@kylinos.cn> This patch makes the ADD_ADDR retransmission timeout adaptive by using the maximum subflow RTT, while still capping it at the configured max value (add_addr_timeout_max). This improves responsiveness when establishing new subflows. The change: - Adds mptcp_get_add_addr_timeout() helper - Uses subflow RTT when available - Falls back to max timeout otherwise Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- net/mptcp/pm.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk, return -EINVAL; } +static unsigned int mptcp_get_add_addr_timeout(struct mptcp_sock *msk, + const struct net *net) +{ + unsigned int timeout = mptcp_get_add_addr_timeout_max(net); + struct mptcp_subflow_context *subflow; + unsigned int srtt_us = 0; + + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + struct tcp_sock *tp = tcp_sk(ssk); + + if (srtt_us < tp->srtt_us) + srtt_us = tp->srtt_us; + } + + if (srtt_us && srtt_us < timeout) + timeout = srtt_us; + + return timeout; +} + static void mptcp_pm_add_timer(struct timer_list *timer) { struct mptcp_pm_add_entry *entry = timer_container_of(entry, timer, @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_add_timer(struct timer_list *timer) if (entry->retrans_times < ADD_ADDR_RETRANS_MAX) sk_reset_timer(sk, timer, - jiffies + mptcp_get_add_addr_timeout_max(sock_net(sk))); + jiffies + mptcp_get_add_addr_timeout(msk, sock_net(sk))); spin_unlock_bh(&msk->pm.lock); @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, return false; sk_reset_timer(sk, &add_entry->add_timer, - jiffies + mptcp_get_add_addr_timeout_max(net)); + jiffies + mptcp_get_add_addr_timeout(msk, net)); return true; } @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0); sk_reset_timer(sk, &add_entry->add_timer, - jiffies + mptcp_get_add_addr_timeout_max(net)); + jiffies + mptcp_get_add_addr_timeout(msk, net)); return true; } -- 2.48.1
From: Geliang Tang <tanggeliang@kylinos.cn> Update MPTCP selftests to use the renamed sysctl variable add_addr_timeout_max. This aligns tests with the kernel change. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- tools/testing/selftests/net/mptcp/mptcp_join.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -XXX,XX +XXX,XX @@ reset_with_add_addr_timeout() tables="${ip6tables}" fi - ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1 + ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout_max=1 if ! ip netns exec $ns2 $tables -A OUTPUT -p tcp \ -m tcp --tcp-option 30 \ @@ -XXX,XX +XXX,XX @@ chk_add_nr() rx=" server" fi - timeout=$(ip netns exec ${ns_tx} sysctl -n net.mptcp.add_addr_timeout) + timeout=$(ip netns exec ${ns_tx} sysctl -n net.mptcp.add_addr_timeout_max) print_check "add addr rx${rx}" count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtAddAddr") @@ -XXX,XX +XXX,XX @@ chk_add_tx_nr() local timeout local count - timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout) + timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout_max) print_check "add addr tx" count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtAddAddrTx") @@ -XXX,XX +XXX,XX @@ signal_address_tests() pm_nl_add_endpoint $ns2 10.0.4.2 flags signal # the peer could possibly miss some addr notification, allow retransmission - ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1 + ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout_max=1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 -- 2.48.1
From: Geliang Tang <tanggeliang@kylinos.cn> v4: - rollback to v2, just use icsk->icsk_rto. Depends on: - mptcp: disable add_addr retrans, v2 Based-on: <cover.1754534416.git.tanggeliang@kylinos.cn> v3: - a new patch, remove duplicate sk_reset_timer call - use __tcp_set_rto() * 2 instead of icsk->icsk_rto - update selftests. - https://patchwork.kernel.org/project/mptcp/cover/cover.1754449947.git.tanggeliang@kylinos.cn/ v2: - do not rename add_addr_timeout - use icsk->icsk_rto instead of tp->srtt_us - increase the time after each retransmission - https://patchwork.kernel.org/project/mptcp/patch/40706ad511220729207ccd7cf48e320e4d0d7dea.1754028199.git.tanggeliang@kylinos.cn/ v1: - https://patchwork.kernel.org/project/mptcp/cover/cover.1753777199.git.tanggeliang@kylinos.cn/ Geliang Tang (2): mptcp: make ADD_ADDR retransmission timeout adaptive selftests: mptcp: remove add_addr_timeout settings Documentation/networking/mptcp-sysctl.rst | 4 +-- net/mptcp/pm.c | 28 ++++++++++++++++--- .../testing/selftests/net/mptcp/mptcp_join.sh | 3 -- 3 files changed, 26 insertions(+), 9 deletions(-) -- 2.48.1
From: Geliang Tang <tanggeliang@kylinos.cn> Currently the ADD_ADDR option is retransmitted with a fixed timeout. This patch makes the retransmission timeout adaptive by using the maximum RTO among all the subflows, while still capping it at the configured maximum value (add_addr_timeout_max). This improves responsiveness when establishing new subflows. Specifically: 1. Adds mptcp_adjust_add_addr_timeout() helper to compute the adaptive timeout. 2. Uses maximum subflow RTO (icsk_rto) when available. 3. Applies exponential backoff based on retransmission count. 4. Maintains fallback to configured max timeout when no RTO data exists. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/576 Reviewed-by: Christoph Paasch <cpaasch@openai.com> Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- Documentation/networking/mptcp-sysctl.rst | 4 ++-- net/mptcp/pm.c | 28 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Documentation/networking/mptcp-sysctl.rst b/Documentation/networking/mptcp-sysctl.rst index XXXXXXX..XXXXXXX 100644 --- a/Documentation/networking/mptcp-sysctl.rst +++ b/Documentation/networking/mptcp-sysctl.rst @@ -XXX,XX +XXX,XX @@ MPTCP Sysfs variables =============================== add_addr_timeout - INTEGER (seconds) - Set the timeout after which an ADD_ADDR control message will be - resent to an MPTCP peer that has not acknowledged a previous + Set the maximum value of timeout after which an ADD_ADDR control message + will be resent to an MPTCP peer that has not acknowledged a previous ADD_ADDR message. Do not retransmit if set to 0. diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index XXXXXXX..XXXXXXX 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -XXX,XX +XXX,XX @@ int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk, return -EINVAL; } +static unsigned int mptcp_adjust_add_addr_timeout(struct mptcp_sock *msk) +{ + const struct net *net = sock_net((struct sock *)msk); + unsigned int rto = mptcp_get_add_addr_timeout(net); + struct mptcp_subflow_context *subflow; + unsigned int max = 0; + + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + struct inet_connection_sock *icsk = inet_csk(ssk); + + if (icsk->icsk_rto > max) + max = icsk->icsk_rto; + } + + if (max && max < rto) + rto = max; + + return rto; +} + static void mptcp_pm_add_timer(struct timer_list *timer) { struct mptcp_pm_add_entry *entry = timer_container_of(entry, timer, @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_add_timer(struct timer_list *timer) goto out; } - timeout = mptcp_get_add_addr_timeout(sock_net(sk)); + timeout = mptcp_adjust_add_addr_timeout(msk); if (!timeout) goto out; @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_add_timer(struct timer_list *timer) if (entry->retrans_times < ADD_ADDR_RETRANS_MAX) sk_reset_timer(sk, timer, - jiffies + timeout); + jiffies + (timeout << entry->retrans_times)); spin_unlock_bh(&msk->pm.lock); @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, { struct mptcp_pm_add_entry *add_entry = NULL; struct sock *sk = (struct sock *)msk; - struct net *net = sock_net(sk); unsigned int timeout; lockdep_assert_held(&msk->pm.lock); @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0); reset_timer: - timeout = mptcp_get_add_addr_timeout(net); + timeout = mptcp_adjust_add_addr_timeout(msk); if (timeout) sk_reset_timer(sk, &add_entry->add_timer, jiffies + timeout); -- 2.48.1
From: Geliang Tang <tanggeliang@kylinos.cn> Now that add_addr_timeout can be dynamically adjusted, there is no need to set specific timeout values in the mptcp_join.sh tests. This patch removes the explicit sysctl settings for net.mptcp.add_addr_timeout from the test scripts. The change simplifies the test setup and ensures the tests work with the default or dynamically adjusted timeout values. Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> --- tools/testing/selftests/net/mptcp/mptcp_join.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index XXXXXXX..XXXXXXX 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -XXX,XX +XXX,XX @@ reset_with_add_addr_timeout() tables="${ip6tables}" fi - ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1 - if ! ip netns exec $ns2 $tables -A OUTPUT -p tcp \ -m tcp --tcp-option 30 \ -m bpf --bytecode \ @@ -XXX,XX +XXX,XX @@ signal_address_tests() pm_nl_add_endpoint $ns2 10.0.4.2 flags signal # the peer could possibly miss some addr notification, allow retransmission - ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=1 speed=slow \ run_tests $ns1 $ns2 10.0.1.1 -- 2.48.1