@@ -438,15 +438,17 @@ struct fib6_dump_arg {
438438static int fib6_rt_dump (struct fib6_info * rt , struct fib6_dump_arg * arg )
439439{
440440 enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE ;
441+ unsigned int nsiblings ;
441442 int err ;
442443
443444 if (!rt || rt == arg -> net -> ipv6 .fib6_null_entry )
444445 return 0 ;
445446
446- if (rt -> fib6_nsiblings )
447+ nsiblings = READ_ONCE (rt -> fib6_nsiblings );
448+ if (nsiblings )
447449 err = call_fib6_multipath_entry_notifier (arg -> nb , fib_event ,
448450 rt ,
449- rt -> fib6_nsiblings ,
451+ nsiblings ,
450452 arg -> extack );
451453 else
452454 err = call_fib6_entry_notifier (arg -> nb , fib_event , rt ,
@@ -1122,7 +1124,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
11221124
11231125 if (rt6_duplicate_nexthop (iter , rt )) {
11241126 if (rt -> fib6_nsiblings )
1125- rt -> fib6_nsiblings = 0 ;
1127+ WRITE_ONCE ( rt -> fib6_nsiblings , 0 ) ;
11261128 if (!(iter -> fib6_flags & RTF_EXPIRES ))
11271129 return - EEXIST ;
11281130 if (!(rt -> fib6_flags & RTF_EXPIRES ))
@@ -1148,7 +1150,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
11481150 */
11491151 if (rt_can_ecmp &&
11501152 rt6_qualify_for_ecmp (iter ))
1151- rt -> fib6_nsiblings ++ ;
1153+ WRITE_ONCE (rt -> fib6_nsiblings ,
1154+ rt -> fib6_nsiblings + 1 );
11521155 }
11531156
11541157 if (iter -> fib6_metric > rt -> fib6_metric )
@@ -1198,7 +1201,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
11981201 fib6_nsiblings = 0 ;
11991202 list_for_each_entry_safe (sibling , temp_sibling ,
12001203 & rt -> fib6_siblings , fib6_siblings ) {
1201- sibling -> fib6_nsiblings ++ ;
1204+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1205+ sibling -> fib6_nsiblings + 1 );
12021206 BUG_ON (sibling -> fib6_nsiblings != rt -> fib6_nsiblings );
12031207 fib6_nsiblings ++ ;
12041208 }
@@ -1243,8 +1247,9 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
12431247 list_for_each_entry_safe (sibling , next_sibling ,
12441248 & rt -> fib6_siblings ,
12451249 fib6_siblings )
1246- sibling -> fib6_nsiblings -- ;
1247- rt -> fib6_nsiblings = 0 ;
1250+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1251+ sibling -> fib6_nsiblings - 1 );
1252+ WRITE_ONCE (rt -> fib6_nsiblings , 0 );
12481253 list_del_rcu (& rt -> fib6_siblings );
12491254 rt6_multipath_rebalance (next_sibling );
12501255 return err ;
@@ -1957,8 +1962,9 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
19571962 notify_del = true;
19581963 list_for_each_entry_safe (sibling , next_sibling ,
19591964 & rt -> fib6_siblings , fib6_siblings )
1960- sibling -> fib6_nsiblings -- ;
1961- rt -> fib6_nsiblings = 0 ;
1965+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1966+ sibling -> fib6_nsiblings - 1 );
1967+ WRITE_ONCE (rt -> fib6_nsiblings , 0 );
19621968 list_del_rcu (& rt -> fib6_siblings );
19631969 rt6_multipath_rebalance (next_sibling );
19641970 }
0 commit comments