提交 43a03ef8 编写于 作者: K Kuniyuki Iwashima 提交者: Zheng Zengkai

tcp: Fix data-races around sysctl_tcp_no_ssthresh_metrics_save.

stable inclusion
from stable-v5.10.135
commit 2b4b373271e5a39117f520dfa931f2f801f3076f
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5ZWFM

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2b4b373271e5a39117f520dfa931f2f801f3076f

--------------------------------

commit ab1ba21b upstream.

While reading sysctl_tcp_no_ssthresh_metrics_save, it can be changed
concurrently.  Thus, we need to add READ_ONCE() to its readers.

Fixes: 65e6d901 ("net-tcp: Disable TCP ssthresh metrics cache by default")
Signed-off-by: NKuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: NWei Li <liwei391@huawei.com>
上级 405e54b6
...@@ -385,7 +385,7 @@ void tcp_update_metrics(struct sock *sk) ...@@ -385,7 +385,7 @@ void tcp_update_metrics(struct sock *sk)
if (tcp_in_initial_slowstart(tp)) { if (tcp_in_initial_slowstart(tp)) {
/* Slow start still did not finish. */ /* Slow start still did not finish. */
if (!net->ipv4.sysctl_tcp_no_ssthresh_metrics_save && if (!READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) &&
!tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) { !tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) {
val = tcp_metric_get(tm, TCP_METRIC_SSTHRESH); val = tcp_metric_get(tm, TCP_METRIC_SSTHRESH);
if (val && (tp->snd_cwnd >> 1) > val) if (val && (tp->snd_cwnd >> 1) > val)
...@@ -401,7 +401,7 @@ void tcp_update_metrics(struct sock *sk) ...@@ -401,7 +401,7 @@ void tcp_update_metrics(struct sock *sk)
} else if (!tcp_in_slow_start(tp) && } else if (!tcp_in_slow_start(tp) &&
icsk->icsk_ca_state == TCP_CA_Open) { icsk->icsk_ca_state == TCP_CA_Open) {
/* Cong. avoidance phase, cwnd is reliable. */ /* Cong. avoidance phase, cwnd is reliable. */
if (!net->ipv4.sysctl_tcp_no_ssthresh_metrics_save && if (!READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) &&
!tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) !tcp_metric_locked(tm, TCP_METRIC_SSTHRESH))
tcp_metric_set(tm, TCP_METRIC_SSTHRESH, tcp_metric_set(tm, TCP_METRIC_SSTHRESH,
max(tp->snd_cwnd >> 1, tp->snd_ssthresh)); max(tp->snd_cwnd >> 1, tp->snd_ssthresh));
...@@ -418,7 +418,7 @@ void tcp_update_metrics(struct sock *sk) ...@@ -418,7 +418,7 @@ void tcp_update_metrics(struct sock *sk)
tcp_metric_set(tm, TCP_METRIC_CWND, tcp_metric_set(tm, TCP_METRIC_CWND,
(val + tp->snd_ssthresh) >> 1); (val + tp->snd_ssthresh) >> 1);
} }
if (!net->ipv4.sysctl_tcp_no_ssthresh_metrics_save && if (!READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) &&
!tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) { !tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) {
val = tcp_metric_get(tm, TCP_METRIC_SSTHRESH); val = tcp_metric_get(tm, TCP_METRIC_SSTHRESH);
if (val && tp->snd_ssthresh > val) if (val && tp->snd_ssthresh > val)
...@@ -463,7 +463,7 @@ void tcp_init_metrics(struct sock *sk) ...@@ -463,7 +463,7 @@ void tcp_init_metrics(struct sock *sk)
if (tcp_metric_locked(tm, TCP_METRIC_CWND)) if (tcp_metric_locked(tm, TCP_METRIC_CWND))
tp->snd_cwnd_clamp = tcp_metric_get(tm, TCP_METRIC_CWND); tp->snd_cwnd_clamp = tcp_metric_get(tm, TCP_METRIC_CWND);
val = net->ipv4.sysctl_tcp_no_ssthresh_metrics_save ? val = READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) ?
0 : tcp_metric_get(tm, TCP_METRIC_SSTHRESH); 0 : tcp_metric_get(tm, TCP_METRIC_SSTHRESH);
if (val) { if (val) {
tp->snd_ssthresh = val; tp->snd_ssthresh = val;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册