Skip to content

Commit 90c47a1

Browse files
edumazetgregkh
authored andcommitted
net: dst: introduce dst->dev_rcu
[ Upstream commit caedcc5 ] Followup of commit 88fe142 ("net: dst: add four helpers to annotate data-races around dst->dev"). We want to gradually add explicit RCU protection to dst->dev, including lockdep support. Add an union to alias dst->dev_rcu and dst->dev. Add dst_dev_net_rcu() helper. Fixes: 4a6ce2b ("net: introduce a new function dst_dev_put()") Cc: stable@vger.kernel.org Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20250828195823.3958522-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: 50c127a ("Replace three dst_dev() with a lockdep enabled helper.") Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8401fe8 commit 90c47a1

3 files changed

Lines changed: 14 additions & 8 deletions

File tree

include/net/dst.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
struct sk_buff;
2525

2626
struct dst_entry {
27-
struct net_device *dev;
27+
union {
28+
struct net_device *dev;
29+
struct net_device __rcu *dev_rcu;
30+
};
2831
struct dst_ops *ops;
2932
unsigned long _metrics;
3033
unsigned long expires;
@@ -568,9 +571,12 @@ static inline struct net_device *dst_dev(const struct dst_entry *dst)
568571

569572
static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst)
570573
{
571-
/* In the future, use rcu_dereference(dst->dev) */
572-
WARN_ON_ONCE(!rcu_read_lock_held());
573-
return READ_ONCE(dst->dev);
574+
return rcu_dereference(dst->dev_rcu);
575+
}
576+
577+
static inline struct net *dst_dev_net_rcu(const struct dst_entry *dst)
578+
{
579+
return dev_net_rcu(dst_dev_rcu(dst));
574580
}
575581

576582
static inline struct net_device *skb_dst_dev(const struct sk_buff *skb)
@@ -590,7 +596,7 @@ static inline struct net *skb_dst_dev_net(const struct sk_buff *skb)
590596

591597
static inline struct net *skb_dst_dev_net_rcu(const struct sk_buff *skb)
592598
{
593-
return dev_net_rcu(skb_dst_dev(skb));
599+
return dev_net_rcu(skb_dst_dev_rcu(skb));
594600
}
595601

596602
struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie);

net/core/dst.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ void dst_dev_put(struct dst_entry *dst)
150150
dst->ops->ifdown(dst, dev);
151151
WRITE_ONCE(dst->input, dst_discard);
152152
WRITE_ONCE(dst->output, dst_discard_out);
153-
WRITE_ONCE(dst->dev, blackhole_netdev);
153+
rcu_assign_pointer(dst->dev_rcu, blackhole_netdev);
154154
netdev_ref_replace(dev, blackhole_netdev, &dst->dev_tracker,
155155
GFP_ATOMIC);
156156
}

net/ipv4/route.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
10301030
return;
10311031

10321032
rcu_read_lock();
1033-
net = dev_net_rcu(dst_dev(dst));
1033+
net = dst_dev_net_rcu(dst);
10341034
if (mtu < net->ipv4.ip_rt_min_pmtu) {
10351035
lock = true;
10361036
mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu);
@@ -1328,7 +1328,7 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst)
13281328
struct net *net;
13291329

13301330
rcu_read_lock();
1331-
net = dev_net_rcu(dst_dev(dst));
1331+
net = dst_dev_net_rcu(dst);
13321332
advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size,
13331333
net->ipv4.ip_rt_min_advmss);
13341334
rcu_read_unlock();

0 commit comments

Comments
 (0)