diff options
| author | Eric Dumazet <edumazet@google.com> | 2026-06-02 12:51:38 +0000 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-03 19:04:40 -0700 |
| commit | a02a765bd5c2ae7705144829b2911c96c29db6ba (patch) | |
| tree | ac4c71c963ab9ba548dc710512bb5e639a89dc87 | |
| parent | 3070d0294e12311d304610703b3e691b70217549 (diff) | |
| download | linux-a02a765bd5c2ae7705144829b2911c96c29db6ba.tar.gz linux-a02a765bd5c2ae7705144829b2911c96c29db6ba.zip | |
mptcp: change mptcp_established_options() to return opt_size
Instead of passing opt_size address to mptcp_established_options(),
change this function to return it by value.
This removes the need for an expensive stack canary in
tcp_established_options() when CONFIG_STACKPROTECTOR_STRONG=y.
$ scripts/bloat-o-meter -t vmlinux.old vmlinux.new
add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-92 (-92)
Function old new delta
tcp_options_write.isra 1423 1407 -16
mptcp_established_options 2746 2720 -26
tcp_established_options 553 503 -50
Total: Before=22110750, After=22110658, chg -0.00%
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260602125138.2317015-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | include/net/mptcp.h | 17 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 7 | ||||
| -rw-r--r-- | net/mptcp/options.c | 31 |
3 files changed, 28 insertions, 27 deletions
diff --git a/include/net/mptcp.h b/include/net/mptcp.h index f7263fe2a2e4..27225c68a388 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -149,9 +149,9 @@ bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, unsigned int *size, struct mptcp_out_options *opts); bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, struct mptcp_out_options *opts); -bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, - unsigned int *size, unsigned int remaining, - struct mptcp_out_options *opts); +int mptcp_established_options(struct sock *sk, struct sk_buff *skb, + unsigned int remaining, + struct mptcp_out_options *opts); bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb); void mptcp_write_options(struct tcphdr *th, __be32 *ptr, struct tcp_sock *tp, @@ -266,13 +266,12 @@ static inline bool mptcp_synack_options(const struct request_sock *req, return false; } -static inline bool mptcp_established_options(struct sock *sk, - struct sk_buff *skb, - unsigned int *size, - unsigned int remaining, - struct mptcp_out_options *opts) +static inline int mptcp_established_options(struct sock *sk, + struct sk_buff *skb, + unsigned int remaining, + struct mptcp_out_options *opts) { - return false; + return -1; } static inline bool mptcp_incoming_options(struct sock *sk, diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 1b0a066bb6a3..d3b8e61d3c5e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1183,10 +1183,11 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb */ if (sk_is_mptcp(sk)) { unsigned int remaining = MAX_TCP_OPTION_SPACE - size; - unsigned int opt_size = 0; + int opt_size; - if (mptcp_established_options(sk, skb, &opt_size, remaining, - &opts->mptcp)) { + opt_size = mptcp_established_options(sk, skb, remaining, + &opts->mptcp); + if (opt_size >= 0) { opts->options |= OPTION_MPTCP; size += opt_size; } diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 8a1c5698983c..53528301394d 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -836,13 +836,14 @@ static bool mptcp_established_options_mp_fail(struct sock *sk, return true; } -bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, - unsigned int *size, unsigned int remaining, - struct mptcp_out_options *opts) +int mptcp_established_options(struct sock *sk, struct sk_buff *skb, + unsigned int remaining, + struct mptcp_out_options *opts) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); struct mptcp_sock *msk = mptcp_sk(subflow->conn); unsigned int opt_size = 0; + int total_size = 0; bool snd_data_fin; bool ret = false; @@ -852,20 +853,20 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, * option space. */ if (unlikely(__mptcp_check_fallback(msk) && !mptcp_check_infinite_map(skb))) - return true; + return 0; if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) { if (mptcp_established_options_fastclose(sk, &opt_size, remaining, opts) || mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) { - *size += opt_size; + total_size += opt_size; remaining -= opt_size; } /* MP_RST can be used with MP_FASTCLOSE and MP_FAIL if there is room */ if (mptcp_established_options_rst(sk, skb, &opt_size, remaining, opts)) { - *size += opt_size; + total_size += opt_size; remaining -= opt_size; } - return true; + return total_size; } snd_data_fin = mptcp_data_fin_enabled(msk); @@ -877,9 +878,9 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, ret = true; if (mptcp_established_options_mp_fail(sk, &mp_fail_size, remaining - opt_size, opts)) { - *size += opt_size + mp_fail_size; + total_size += opt_size + mp_fail_size; remaining -= opt_size - mp_fail_size; - return true; + return total_size; } } @@ -887,27 +888,27 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, * TCP option space would be fatal */ if (WARN_ON_ONCE(opt_size > remaining)) - return false; + return -1; - *size += opt_size; + total_size += opt_size; remaining -= opt_size; if (mptcp_established_options_add_addr(sk, skb, &opt_size, remaining, opts)) { - *size += opt_size; + total_size += opt_size; remaining -= opt_size; ret = true; } else if (mptcp_established_options_rm_addr(sk, &opt_size, remaining, opts)) { - *size += opt_size; + total_size += opt_size; remaining -= opt_size; ret = true; } if (mptcp_established_options_mp_prio(sk, &opt_size, remaining, opts)) { - *size += opt_size; + total_size += opt_size; remaining -= opt_size; ret = true; } - return ret; + return ret ? total_size : -1; } bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, |
