Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d49ed95 authored by Eric Dumazet's avatar Eric Dumazet Committed by Greg Kroah-Hartman
Browse files

tcp_metrics: annotate data-races around tm->tcpm_net



[ Upstream commit d5d986ce42c71a7562d32c4e21e026b0f87befec ]

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: 849e8a0c ("tcp_metrics: Add a field tcpm_net and verify it matches on lookup")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Link: https://lore.kernel.org/r/20230802131500.1478140-6-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent fc566cf3
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ struct tcp_fastopen_metrics {

struct tcp_metrics_block {
	struct tcp_metrics_block __rcu	*tcpm_next;
	possible_net_t			tcpm_net;
	struct net			*tcpm_net;
	struct inetpeer_addr		tcpm_saddr;
	struct inetpeer_addr		tcpm_daddr;
	unsigned long			tcpm_stamp;
@@ -51,9 +51,10 @@ struct tcp_metrics_block {
	struct rcu_head			rcu_head;
};

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

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,
		if (!tm)
			goto out_unlock;
	}
	write_pnet(&tm->tcpm_net, net);
	/* Paired with the READ_ONCE() in tm_net() */
	WRITE_ONCE(tm->tcpm_net, net);

	tm->tcpm_saddr = *saddr;
	tm->tcpm_daddr = *daddr;