Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: dst: annotate data-races around dst->expires

(dst_entry)->expires is read and written locklessly,
add corresponding annotations.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250630121934.3399505-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
36229b2c 8a402bbe

+16 -14
+5 -3
include/net/dst.h
··· 431 431 432 432 static inline void dst_set_expires(struct dst_entry *dst, int timeout) 433 433 { 434 - unsigned long expires = jiffies + timeout; 434 + unsigned long old, expires = jiffies + timeout; 435 435 436 436 if (expires == 0) 437 437 expires = 1; 438 438 439 - if (dst->expires == 0 || time_before(expires, dst->expires)) 440 - dst->expires = expires; 439 + old = READ_ONCE(dst->expires); 440 + 441 + if (!old || time_before(expires, old)) 442 + WRITE_ONCE(dst->expires, expires); 441 443 } 442 444 443 445 static inline unsigned int dst_dev_overhead(struct dst_entry *dst,
+1 -1
include/net/ip.h
··· 477 477 ip_mtu_locked(dst) || 478 478 !forwarding) { 479 479 mtu = rt->rt_pmtu; 480 - if (mtu && time_before(jiffies, rt->dst.expires)) 480 + if (mtu && time_before(jiffies, READ_ONCE(rt->dst.expires))) 481 481 goto out; 482 482 } 483 483
+4 -3
net/ipv4/route.c
··· 844 844 845 845 if ((READ_ONCE(dst->obsolete) > 0) || 846 846 (rt->rt_flags & RTCF_REDIRECTED) || 847 - rt->dst.expires) 847 + READ_ONCE(rt->dst.expires)) 848 848 sk_dst_reset(sk); 849 849 } 850 850 ··· 1033 1033 } 1034 1034 1035 1035 if (rt->rt_pmtu == mtu && !lock && 1036 - time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2)) 1036 + time_before(jiffies, READ_ONCE(dst->expires) - 1037 + net->ipv4.ip_rt_mtu_expires / 2)) 1037 1038 goto out; 1038 1039 1039 1040 if (fib_lookup(net, fl4, &res, 0) == 0) { ··· 3011 3010 } 3012 3011 } 3013 3012 3014 - expires = rt->dst.expires; 3013 + expires = READ_ONCE(rt->dst.expires); 3015 3014 if (expires) { 3016 3015 unsigned long now = jiffies; 3017 3016
+6 -7
net/ipv6/route.c
··· 391 391 static bool __rt6_check_expired(const struct rt6_info *rt) 392 392 { 393 393 if (rt->rt6i_flags & RTF_EXPIRES) 394 - return time_after(jiffies, rt->dst.expires); 395 - else 396 - return false; 394 + return time_after(jiffies, READ_ONCE(rt->dst.expires)); 395 + return false; 397 396 } 398 397 399 398 static bool rt6_check_expired(const struct rt6_info *rt) ··· 402 403 from = rcu_dereference(rt->from); 403 404 404 405 if (rt->rt6i_flags & RTF_EXPIRES) { 405 - if (time_after(jiffies, rt->dst.expires)) 406 + if (time_after(jiffies, READ_ONCE(rt->dst.expires))) 406 407 return true; 407 408 } else if (from) { 408 409 return READ_ONCE(rt->dst.obsolete) != DST_OBSOLETE_FORCE_CHK || ··· 2138 2139 rt6_remove_exception(bucket, rt6_ex); 2139 2140 return; 2140 2141 } 2141 - } else if (time_after(jiffies, rt->dst.expires)) { 2142 + } else if (time_after(jiffies, READ_ONCE(rt->dst.expires))) { 2142 2143 pr_debug("purging expired route %p\n", rt); 2143 2144 rt6_remove_exception(bucket, rt6_ex); 2144 2145 return; ··· 2869 2870 rcu_read_lock(); 2870 2871 from = rcu_dereference(rt0->from); 2871 2872 if (from) 2872 - rt0->dst.expires = from->expires; 2873 + WRITE_ONCE(rt0->dst.expires, from->expires); 2873 2874 rcu_read_unlock(); 2874 2875 } 2875 2876 ··· 5902 5903 } 5903 5904 5904 5905 if (rt6_flags & RTF_EXPIRES) { 5905 - expires = dst ? dst->expires : rt->expires; 5906 + expires = dst ? READ_ONCE(dst->expires) : rt->expires; 5906 5907 expires -= jiffies; 5907 5908 } 5908 5909