From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 882B61DFD8B for ; Mon, 20 Oct 2025 15:44:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760975056; cv=none; b=aZxM6epDxHkDhQb7YiGDVXNZyGkpncq84ritHhEaHlsoFuUvD34NEqEod/1Q7UEoarWD7BPxVa2wtlroTb97zbpRl8TwvorPzWxQS+erKIAof0ILMw8BzB2kmm9aJfsmNG55Z/EPe3TjgHZH7Qv3PdJNKoDzcQry4bDJ5F2fesY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760975056; c=relaxed/simple; bh=HJvDb+K2y6oZ6+jTA/nBo8H+1wqdZamiBZq0HJu+Ryw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YsnHaCw+hQ+rBgR5rDtYkxP6ixoG+dXJUfr0ldqQfDIcK8K6H1+GER1nyimnSERkefHuW/a1WUQOGdhb09aFz3EVIdhxCdkxVqBOaHTtSyoTvxKH8zjH6raUYWTgwyLVpkQ+zvM8n/5ut+GfB0ooPH7WAw4HGaqhKi84ky6EZmI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Kbfbqmo0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Kbfbqmo0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 70A7EC4CEF9; Mon, 20 Oct 2025 15:44:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760975056; bh=HJvDb+K2y6oZ6+jTA/nBo8H+1wqdZamiBZq0HJu+Ryw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kbfbqmo0BMn+8X7nyxz6ZP3uFDuIPnhUxh84jaAoIGAertREY/mHu7ILV2E7tVerd S/gbQcCmxswN4r8PXr7Q5L3HfJl7u2lTC5HOMBrM78ZayD3AohpnA6loO4R2vruxCi zy1YipFNqWGhIKswQOZ+uO6VrQ63pmJpjMLiL/lDliC40wNZCSaU8nl208INGWihB3 UwfhNEYgKGmtPlerXY/M+IvfXenpQQivodw++HiqKBn2tCrtjkzU4OPqb1LFlfYJBM WnjU0yr4nRkOat/mNY3G2Qq9at4dtUZOJtMpUrPt7x35h4F79kBR3JpQnasB4UsZPH v8rdMUAkMyvVA== From: Sasha Levin To: stable@vger.kernel.org Cc: Eric Dumazet , Kuniyuki Iwashima , Jakub Kicinski , Sasha Levin Subject: [PATCH 6.12.y 3/8] net: dst: add four helpers to annotate data-races around dst->dev Date: Mon, 20 Oct 2025 11:44:04 -0400 Message-ID: <20251020154409.1823664-3-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251020154409.1823664-1-sashal@kernel.org> References: <2025101604-chamber-playhouse-5278@gregkh> <20251020154409.1823664-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Eric Dumazet [ Upstream commit 88fe14253e181878c2ddb51a298ae8c468a63010 ] dst->dev is read locklessly in many contexts, and written in dst_dev_put(). Fixing all the races is going to need many changes. We probably will have to add full RCU protection. Add three helpers to ease this painful process. static inline struct net_device *dst_dev(const struct dst_entry *dst) { return READ_ONCE(dst->dev); } static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) { return dst_dev(skb_dst(skb)); } static inline struct net *skb_dst_dev_net(const struct sk_buff *skb) { return dev_net(skb_dst_dev(skb)); } static inline struct net *skb_dst_dev_net_rcu(const struct sk_buff *skb) { return dev_net_rcu(skb_dst_dev(skb)); } Fixes: 4a6ce2b6f2ec ("net: introduce a new function dst_dev_put()") Signed-off-by: Eric Dumazet Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250630121934.3399505-7-edumazet@google.com Signed-off-by: Jakub Kicinski Stable-dep-of: 833d4313bc1e ("mptcp: reset blackhole on success with non-loopback ifaces") Signed-off-by: Sasha Levin --- include/net/dst.h | 20 ++++++++++++++++++++ net/core/dst.c | 4 ++-- net/core/sock.c | 8 ++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index e18826cd05595..23ee8139a7563 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -561,6 +561,26 @@ static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu) dst->ops->update_pmtu(dst, NULL, skb, mtu, false); } +static inline struct net_device *dst_dev(const struct dst_entry *dst) +{ + return READ_ONCE(dst->dev); +} + +static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) +{ + return dst_dev(skb_dst(skb)); +} + +static inline struct net *skb_dst_dev_net(const struct sk_buff *skb) +{ + return dev_net(skb_dst_dev(skb)); +} + +static inline struct net *skb_dst_dev_net_rcu(const struct sk_buff *skb) +{ + return dev_net_rcu(skb_dst_dev(skb)); +} + struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu, bool confirm_neigh); diff --git a/net/core/dst.c b/net/core/dst.c index cc990706b6451..9a0ddef8bee43 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -150,7 +150,7 @@ void dst_dev_put(struct dst_entry *dst) dst->ops->ifdown(dst, dev); WRITE_ONCE(dst->input, dst_discard); WRITE_ONCE(dst->output, dst_discard_out); - dst->dev = blackhole_netdev; + WRITE_ONCE(dst->dev, blackhole_netdev); netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker, GFP_ATOMIC); } @@ -263,7 +263,7 @@ unsigned int dst_blackhole_mtu(const struct dst_entry *dst) { unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); - return mtu ? : dst->dev->mtu; + return mtu ? : dst_dev(dst)->mtu; } EXPORT_SYMBOL_GPL(dst_blackhole_mtu); diff --git a/net/core/sock.c b/net/core/sock.c index b5723adab4ebf..a5f248a914042 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2534,8 +2534,8 @@ static u32 sk_dst_gso_max_size(struct sock *sk, struct dst_entry *dst) !ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)); #endif /* pairs with the WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */ - max_size = is_ipv6 ? READ_ONCE(dst->dev->gso_max_size) : - READ_ONCE(dst->dev->gso_ipv4_max_size); + max_size = is_ipv6 ? READ_ONCE(dst_dev(dst)->gso_max_size) : + READ_ONCE(dst_dev(dst)->gso_ipv4_max_size); if (max_size > GSO_LEGACY_MAX_SIZE && !sk_is_tcp(sk)) max_size = GSO_LEGACY_MAX_SIZE; @@ -2546,7 +2546,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) { u32 max_segs = 1; - sk->sk_route_caps = dst->dev->features; + sk->sk_route_caps = dst_dev(dst)->features; if (sk_is_tcp(sk)) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -2564,7 +2564,7 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst) sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM; sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dst); /* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */ - max_segs = max_t(u32, READ_ONCE(dst->dev->gso_max_segs), 1); + max_segs = max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1); } } sk->sk_gso_max_segs = max_segs; -- 2.51.0