]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
tcp_metrics: annotate data-races around tm->tcpm_lock
authorEric Dumazet <edumazet@google.com>
Wed, 2 Aug 2023 13:14:57 +0000 (13:14 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Aug 2023 09:33:55 +0000 (11:33 +0200)
[ Upstream commit 285ce119a3c6c4502585936650143e54c8692788 ]

tm->tcpm_lock can be read or written locklessly.

Add needed READ_ONCE()/WRITE_ONCE() to document this.

Fixes: 51c5d0c4b169 ("tcp: Maintain dynamic metrics in local cache.")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://lore.kernel.org/r/20230802131500.1478140-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/ipv4/tcp_metrics.c

index a283b0710a7e21faba30f30432339920c193bbfd..2f0e7c38e634c167b42bd71f5a6f64e1bdb4efec 100644 (file)
@@ -61,7 +61,8 @@ static inline struct net *tm_net(struct tcp_metrics_block *tm)
 static bool tcp_metric_locked(struct tcp_metrics_block *tm,
                              enum tcp_metric_index idx)
 {
-       return tm->tcpm_lock & (1 << idx);
+       /* Paired with WRITE_ONCE() in tcpm_suck_dst() */
+       return READ_ONCE(tm->tcpm_lock) & (1 << idx);
 }
 
 static u32 tcp_metric_get(struct tcp_metrics_block *tm,
@@ -112,7 +113,8 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm,
                val |= 1 << TCP_METRIC_CWND;
        if (dst_metric_locked(dst, RTAX_REORDERING))
                val |= 1 << TCP_METRIC_REORDERING;
-       tm->tcpm_lock = val;
+       /* Paired with READ_ONCE() in tcp_metric_locked() */
+       WRITE_ONCE(tm->tcpm_lock, val);
 
        msval = dst_metric_raw(dst, RTAX_RTT);
        tm->tcpm_vals[TCP_METRIC_RTT] = msval * USEC_PER_MSEC;