@@ -445,15 +445,17 @@ struct fib6_dump_arg {
445
445
static int fib6_rt_dump (struct fib6_info * rt , struct fib6_dump_arg * arg )
446
446
{
447
447
enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE ;
448
+ unsigned int nsiblings ;
448
449
int err ;
449
450
450
451
if (!rt || rt == arg -> net -> ipv6 .fib6_null_entry )
451
452
return 0 ;
452
453
453
- if (rt -> fib6_nsiblings )
454
+ nsiblings = READ_ONCE (rt -> fib6_nsiblings );
455
+ if (nsiblings )
454
456
err = call_fib6_multipath_entry_notifier (arg -> nb , fib_event ,
455
457
rt ,
456
- rt -> fib6_nsiblings ,
458
+ nsiblings ,
457
459
arg -> extack );
458
460
else
459
461
err = call_fib6_entry_notifier (arg -> nb , fib_event , rt ,
@@ -1138,7 +1140,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
1138
1140
1139
1141
if (rt6_duplicate_nexthop (iter , rt )) {
1140
1142
if (rt -> fib6_nsiblings )
1141
- rt -> fib6_nsiblings = 0 ;
1143
+ WRITE_ONCE ( rt -> fib6_nsiblings , 0 ) ;
1142
1144
if (!(iter -> fib6_flags & RTF_EXPIRES ))
1143
1145
return - EEXIST ;
1144
1146
if (!(rt -> fib6_flags & RTF_EXPIRES )) {
@@ -1167,7 +1169,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
1167
1169
*/
1168
1170
if (rt_can_ecmp &&
1169
1171
rt6_qualify_for_ecmp (iter ))
1170
- rt -> fib6_nsiblings ++ ;
1172
+ WRITE_ONCE (rt -> fib6_nsiblings ,
1173
+ rt -> fib6_nsiblings + 1 );
1171
1174
}
1172
1175
1173
1176
if (iter -> fib6_metric > rt -> fib6_metric )
@@ -1217,7 +1220,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
1217
1220
fib6_nsiblings = 0 ;
1218
1221
list_for_each_entry_safe (sibling , temp_sibling ,
1219
1222
& rt -> fib6_siblings , fib6_siblings ) {
1220
- sibling -> fib6_nsiblings ++ ;
1223
+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1224
+ sibling -> fib6_nsiblings + 1 );
1221
1225
BUG_ON (sibling -> fib6_nsiblings != rt -> fib6_nsiblings );
1222
1226
fib6_nsiblings ++ ;
1223
1227
}
@@ -1264,7 +1268,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
1264
1268
list_for_each_entry_safe (sibling , next_sibling ,
1265
1269
& rt -> fib6_siblings ,
1266
1270
fib6_siblings )
1267
- sibling -> fib6_nsiblings -- ;
1271
+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1272
+ sibling -> fib6_nsiblings - 1 );
1268
1273
WRITE_ONCE (rt -> fib6_nsiblings , 0 );
1269
1274
list_del_rcu (& rt -> fib6_siblings );
1270
1275
rcu_read_lock ();
@@ -2014,7 +2019,8 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
2014
2019
notify_del = true;
2015
2020
list_for_each_entry_safe (sibling , next_sibling ,
2016
2021
& rt -> fib6_siblings , fib6_siblings )
2017
- sibling -> fib6_nsiblings -- ;
2022
+ WRITE_ONCE (sibling -> fib6_nsiblings ,
2023
+ sibling -> fib6_nsiblings - 1 );
2018
2024
WRITE_ONCE (rt -> fib6_nsiblings , 0 );
2019
2025
list_del_rcu (& rt -> fib6_siblings );
2020
2026
rt6_multipath_rebalance (next_sibling );
0 commit comments