]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/bonding/bond_main.c
Merge tag 'platform-drivers-x86-v4.12-2' of git://git.infradead.org/linux-platform...
[karo-tx-linux.git] / drivers / net / bonding / bond_main.c
index 73313318399c7b06b116b12e37b0b1b0277c4345..8ab6bdbe16820dd3e56ec517838903bedda515de 100644 (file)
@@ -2612,11 +2612,13 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
        bond_for_each_slave_rcu(bond, slave, iter) {
                unsigned long trans_start = dev_trans_start(slave->dev);
 
+               slave->new_link = BOND_LINK_NOCHANGE;
+
                if (slave->link != BOND_LINK_UP) {
                        if (bond_time_in_interval(bond, trans_start, 1) &&
                            bond_time_in_interval(bond, slave->last_rx, 1)) {
 
-                               slave->link  = BOND_LINK_UP;
+                               slave->new_link = BOND_LINK_UP;
                                slave_state_changed = 1;
 
                                /* primary_slave has no meaning in round-robin
@@ -2643,7 +2645,7 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
                        if (!bond_time_in_interval(bond, trans_start, 2) ||
                            !bond_time_in_interval(bond, slave->last_rx, 2)) {
 
-                               slave->link  = BOND_LINK_DOWN;
+                               slave->new_link = BOND_LINK_DOWN;
                                slave_state_changed = 1;
 
                                if (slave->link_failure_count < UINT_MAX)
@@ -2674,6 +2676,11 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
                if (!rtnl_trylock())
                        goto re_arm;
 
+               bond_for_each_slave(bond, slave, iter) {
+                       if (slave->new_link != BOND_LINK_NOCHANGE)
+                               slave->link = slave->new_link;
+               }
+
                if (slave_state_changed) {
                        bond_slave_state_change(bond);
                        if (BOND_MODE(bond) == BOND_MODE_XOR)
@@ -4185,7 +4192,6 @@ static void bond_destructor(struct net_device *bond_dev)
        struct bonding *bond = netdev_priv(bond_dev);
        if (bond->wq)
                destroy_workqueue(bond->wq);
-       free_netdev(bond_dev);
 }
 
 void bond_setup(struct net_device *bond_dev)
@@ -4205,7 +4211,8 @@ void bond_setup(struct net_device *bond_dev)
        bond_dev->netdev_ops = &bond_netdev_ops;
        bond_dev->ethtool_ops = &bond_ethtool_ops;
 
-       bond_dev->destructor = bond_destructor;
+       bond_dev->needs_free_netdev = true;
+       bond_dev->priv_destructor = bond_destructor;
 
        SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
 
@@ -4729,7 +4736,7 @@ int bond_create(struct net *net, const char *name)
 
        rtnl_unlock();
        if (res < 0)
-               bond_destructor(bond_dev);
+               free_netdev(bond_dev);
        return res;
 }