@@ -440,15 +440,17 @@ struct fib6_dump_arg {
440
440
static int fib6_rt_dump (struct fib6_info * rt , struct fib6_dump_arg * arg )
441
441
{
442
442
enum fib_event_type fib_event = FIB_EVENT_ENTRY_REPLACE ;
443
+ unsigned int nsiblings ;
443
444
int err ;
444
445
445
446
if (!rt || rt == arg -> net -> ipv6 .fib6_null_entry )
446
447
return 0 ;
447
448
448
- if (rt -> fib6_nsiblings )
449
+ nsiblings = READ_ONCE (rt -> fib6_nsiblings );
450
+ if (nsiblings )
449
451
err = call_fib6_multipath_entry_notifier (arg -> nb , fib_event ,
450
452
rt ,
451
- rt -> fib6_nsiblings ,
453
+ nsiblings ,
452
454
arg -> extack );
453
455
else
454
456
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,
1126
1128
1127
1129
if (rt6_duplicate_nexthop (iter , rt )) {
1128
1130
if (rt -> fib6_nsiblings )
1129
- rt -> fib6_nsiblings = 0 ;
1131
+ WRITE_ONCE ( rt -> fib6_nsiblings , 0 ) ;
1130
1132
if (!(iter -> fib6_flags & RTF_EXPIRES ))
1131
1133
return - EEXIST ;
1132
1134
if (!(rt -> fib6_flags & RTF_EXPIRES )) {
@@ -1155,7 +1157,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
1155
1157
*/
1156
1158
if (rt_can_ecmp &&
1157
1159
rt6_qualify_for_ecmp (iter ))
1158
- rt -> fib6_nsiblings ++ ;
1160
+ WRITE_ONCE (rt -> fib6_nsiblings ,
1161
+ rt -> fib6_nsiblings + 1 );
1159
1162
}
1160
1163
1161
1164
if (iter -> fib6_metric > rt -> fib6_metric )
@@ -1205,7 +1208,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
1205
1208
fib6_nsiblings = 0 ;
1206
1209
list_for_each_entry_safe (sibling , temp_sibling ,
1207
1210
& rt -> fib6_siblings , fib6_siblings ) {
1208
- sibling -> fib6_nsiblings ++ ;
1211
+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1212
+ sibling -> fib6_nsiblings + 1 );
1209
1213
BUG_ON (sibling -> fib6_nsiblings != rt -> fib6_nsiblings );
1210
1214
fib6_nsiblings ++ ;
1211
1215
}
@@ -1250,7 +1254,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
1250
1254
list_for_each_entry_safe (sibling , next_sibling ,
1251
1255
& rt -> fib6_siblings ,
1252
1256
fib6_siblings )
1253
- sibling -> fib6_nsiblings -- ;
1257
+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1258
+ sibling -> fib6_nsiblings - 1 );
1254
1259
WRITE_ONCE (rt -> fib6_nsiblings , 0 );
1255
1260
list_del_rcu (& rt -> fib6_siblings );
1256
1261
rt6_multipath_rebalance (next_sibling );
@@ -1968,7 +1973,8 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
1968
1973
notify_del = true;
1969
1974
list_for_each_entry_safe (sibling , next_sibling ,
1970
1975
& rt -> fib6_siblings , fib6_siblings )
1971
- sibling -> fib6_nsiblings -- ;
1976
+ WRITE_ONCE (sibling -> fib6_nsiblings ,
1977
+ sibling -> fib6_nsiblings - 1 );
1972
1978
WRITE_ONCE (rt -> fib6_nsiblings , 0 );
1973
1979
list_del_rcu (& rt -> fib6_siblings );
1974
1980
rt6_multipath_rebalance (next_sibling );
0 commit comments