@@ -440,15 +440,17 @@ struct fib6_dump_arg {
440440static int fib6_rt_dump (struct fib6_info * rt , struct fib6_dump_arg * arg )
441441{
442442 enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE ;
443+ unsigned int nsiblings ;
443444 int err ;
444445
445446 if (!rt || rt == arg -> net -> ipv6 .fib6_null_entry )
446447 return 0 ;
447448
448- if (rt -> fib6_nsiblings )
449+ nsiblings = READ_ONCE (rt -> fib6_nsiblings );
450+ if (nsiblings )
449451 err = call_fib6_multipath_entry_notifier (arg -> nb , fib_event ,
450452 rt ,
451- rt -> fib6_nsiblings ,
453+ nsiblings ,
452454 arg -> extack );
453455 else
454456 err = call_fib6_entry_notifier (arg -> nb , fib_event , rt ,
@@ -1126,7 +1128,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
11261128
11271129 if (rt6_duplicate_nexthop (iter , rt )) {
11281130 if (rt -> fib6_nsiblings )
1129- rt -> fib6_nsiblings = 0 ;
1131+ WRITE_ONCE ( rt -> fib6_nsiblings , 0 ) ;
11301132 if (!(iter -> fib6_flags & RTF_EXPIRES ))
11311133 return - EEXIST ;
11321134 if (!(rt -> fib6_flags & RTF_EXPIRES )) {
@@ -1155,7 +1157,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
11551157 */
11561158 if (rt_can_ecmp &&
11571159 rt6_qualify_for_ecmp (iter ))
1158- rt -> fib6_nsiblings ++ ;
1160+ WRITE_ONCE (rt -> fib6_nsiblings ,
1161+ rt -> fib6_nsiblings + 1 );
11591162 }
11601163
11611164 if (iter -> fib6_metric > rt -> fib6_metric )
@@ -1205,7 +1208,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
12051208 fib6_nsiblings = 0 ;
12061209 list_for_each_entry_safe (sibling , temp_sibling ,
12071210 & rt -> fib6_siblings , fib6_siblings ) {
1208- sibling -> fib6_nsiblings ++ ;
1211+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1212+ sibling -> fib6_nsiblings + 1 );
12091213 BUG_ON (sibling -> fib6_nsiblings != rt -> fib6_nsiblings );
12101214 fib6_nsiblings ++ ;
12111215 }
@@ -1250,7 +1254,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
12501254 list_for_each_entry_safe (sibling , next_sibling ,
12511255 & rt -> fib6_siblings ,
12521256 fib6_siblings )
1253- sibling -> fib6_nsiblings -- ;
1257+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1258+ sibling -> fib6_nsiblings - 1 );
12541259 WRITE_ONCE (rt -> fib6_nsiblings , 0 );
12551260 list_del_rcu (& rt -> fib6_siblings );
12561261 rt6_multipath_rebalance (next_sibling );
@@ -1968,7 +1973,8 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
19681973 notify_del = true;
19691974 list_for_each_entry_safe (sibling , next_sibling ,
19701975 & rt -> fib6_siblings , fib6_siblings )
1971- sibling -> fib6_nsiblings -- ;
1976+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1977+ sibling -> fib6_nsiblings - 1 );
19721978 WRITE_ONCE (rt -> fib6_nsiblings , 0 );
19731979 list_del_rcu (& rt -> fib6_siblings );
19741980 rt6_multipath_rebalance (next_sibling );
0 commit comments