Skip to content

Commit d5d986c

Browse files
edumazetkuba-moo
authored andcommitted
tcp_metrics: annotate data-races around tm->tcpm_net
tm->tcpm_net can be read or written locklessly. Instead of changing write_pnet() and read_pnet() and potentially hurt performance, add the needed READ_ONCE()/WRITE_ONCE() in tm_net() and tcpm_new(). Fixes: 849e8a0 ("tcp_metrics: Add a field tcpm_net and verify it matches on lookup") 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-6-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 8c4d04f commit d5d986c

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

net/ipv4/tcp_metrics.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct tcp_fastopen_metrics {
4040

4141
struct tcp_metrics_block {
4242
struct tcp_metrics_block __rcu *tcpm_next;
43-
possible_net_t tcpm_net;
43+
struct net *tcpm_net;
4444
struct inetpeer_addr tcpm_saddr;
4545
struct inetpeer_addr tcpm_daddr;
4646
unsigned long tcpm_stamp;
@@ -51,9 +51,10 @@ struct tcp_metrics_block {
5151
struct rcu_head rcu_head;
5252
};
5353

54-
static inline struct net *tm_net(struct tcp_metrics_block *tm)
54+
static inline struct net *tm_net(const struct tcp_metrics_block *tm)
5555
{
56-
return read_pnet(&tm->tcpm_net);
56+
/* Paired with the WRITE_ONCE() in tcpm_new() */
57+
return READ_ONCE(tm->tcpm_net);
5758
}
5859

5960
static bool tcp_metric_locked(struct tcp_metrics_block *tm,
@@ -197,7 +198,9 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
197198
if (!tm)
198199
goto out_unlock;
199200
}
200-
write_pnet(&tm->tcpm_net, net);
201+
/* Paired with the READ_ONCE() in tm_net() */
202+
WRITE_ONCE(tm->tcpm_net, net);
203+
201204
tm->tcpm_saddr = *saddr;
202205
tm->tcpm_daddr = *daddr;
203206

0 commit comments

Comments
 (0)