Skip to content

Commit

Permalink
bonding: fix a div error caused by the slave release path
Browse files Browse the repository at this point in the history
There's a bug in the slave release function which leads the transmit
functions which use the bond->slave_cnt to a div by 0 because we might
just have released our last slave and made slave_cnt == 0 but at the same
time we may have a transmitter after the check for an empty list which will
fetch it and use it in the slave id calculation.
Fix it by moving the slave_cnt after synchronize_rcu so if this was our
last slave any new transmitters will see an empty slave list which is
checked after rcu lock but before calling the mode transmit functions
which rely on bond->slave_cnt.

Fixes: 278b208 ("bonding: initial RCU conversion")

CC: Veaceslav Falico <vfalico@redhat.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: David S. Miller <davem@davemloft.net>

Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Acked-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nikolay Aleksandrov authored and davem330 committed Feb 26, 2014
1 parent e5fe0cd commit ee6154e
Showing 1 changed file with 1 addition and 3 deletions.
4 changes: 1 addition & 3 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1659,9 +1659,6 @@ static int __bond_release_one(struct net_device *bond_dev,
return -EINVAL;
}

/* release the slave from its bond */
bond->slave_cnt--;

bond_sysfs_slave_del(slave);

bond_upper_dev_unlink(bond_dev, slave_dev);
Expand Down Expand Up @@ -1743,6 +1740,7 @@ static int __bond_release_one(struct net_device *bond_dev,

unblock_netpoll_tx();
synchronize_rcu();
bond->slave_cnt--;

if (!bond_has_slaves(bond)) {
call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
Expand Down

0 comments on commit ee6154e

Please sign in to comment.