@@ -3526,18 +3526,65 @@ static void bond_fold_stats(struct rtnl_link_stats64 *_res,
3526
3526
}
3527
3527
}
3528
3528
3529
+ #ifdef CONFIG_LOCKDEP
3530
+ static int bond_get_lowest_level_rcu (struct net_device * dev )
3531
+ {
3532
+ struct net_device * ldev , * next , * now , * dev_stack [MAX_NEST_DEV + 1 ];
3533
+ struct list_head * niter , * iter , * iter_stack [MAX_NEST_DEV + 1 ];
3534
+ int cur = 0 , max = 0 ;
3535
+
3536
+ now = dev ;
3537
+ iter = & dev -> adj_list .lower ;
3538
+
3539
+ while (1 ) {
3540
+ next = NULL ;
3541
+ while (1 ) {
3542
+ ldev = netdev_next_lower_dev_rcu (now , & iter );
3543
+ if (!ldev )
3544
+ break ;
3545
+
3546
+ next = ldev ;
3547
+ niter = & ldev -> adj_list .lower ;
3548
+ dev_stack [cur ] = now ;
3549
+ iter_stack [cur ++ ] = iter ;
3550
+ if (max <= cur )
3551
+ max = cur ;
3552
+ break ;
3553
+ }
3554
+
3555
+ if (!next ) {
3556
+ if (!cur )
3557
+ return max ;
3558
+ next = dev_stack [-- cur ];
3559
+ niter = iter_stack [cur ];
3560
+ }
3561
+
3562
+ now = next ;
3563
+ iter = niter ;
3564
+ }
3565
+
3566
+ return max ;
3567
+ }
3568
+ #endif
3569
+
3529
3570
static void bond_get_stats (struct net_device * bond_dev ,
3530
3571
struct rtnl_link_stats64 * stats )
3531
3572
{
3532
3573
struct bonding * bond = netdev_priv (bond_dev );
3533
3574
struct rtnl_link_stats64 temp ;
3534
3575
struct list_head * iter ;
3535
3576
struct slave * slave ;
3577
+ int nest_level = 0 ;
3536
3578
3537
- spin_lock (& bond -> stats_lock );
3538
- memcpy (stats , & bond -> bond_stats , sizeof (* stats ));
3539
3579
3540
3580
rcu_read_lock ();
3581
+ #ifdef CONFIG_LOCKDEP
3582
+ nest_level = bond_get_lowest_level_rcu (bond_dev );
3583
+ #endif
3584
+
3585
+ spin_lock_nested (& bond -> stats_lock , nest_level );
3586
+ memcpy (stats , & bond -> bond_stats , sizeof (* stats ));
3587
+
3541
3588
bond_for_each_slave_rcu (bond , slave , iter ) {
3542
3589
const struct rtnl_link_stats64 * new =
3543
3590
dev_get_stats (slave -> dev , & temp );
@@ -3547,10 +3594,10 @@ static void bond_get_stats(struct net_device *bond_dev,
3547
3594
/* save off the slave stats for the next run */
3548
3595
memcpy (& slave -> slave_stats , new , sizeof (* new ));
3549
3596
}
3550
- rcu_read_unlock ();
3551
3597
3552
3598
memcpy (& bond -> bond_stats , stats , sizeof (* stats ));
3553
3599
spin_unlock (& bond -> stats_lock );
3600
+ rcu_read_unlock ();
3554
3601
}
3555
3602
3556
3603
static int bond_do_ioctl (struct net_device * bond_dev , struct ifreq * ifr , int cmd )
0 commit comments