Skip to content

Commit

Permalink
bonding: don't call slave_xxx_netpoll under spinlocks
Browse files Browse the repository at this point in the history
The slave_xxx_netpoll will call synchronize_rcu_bh(),
so the function may schedule and sleep, it should't be
called under spinlocks.

bond_netpoll_setup() and bond_netpoll_cleanup() are always
protected by rtnl lock, it is no need to take the read lock,
as the slave list couldn't be changed outside rtnl lock.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Cc: Jay Vosburgh <fubar@us.ibm.com>
Cc: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
dingtianhong authored and David S. Miller committed Jul 25, 2013
1 parent f13bbc2 commit c4cdef9
Showing 1 changed file with 3 additions and 12 deletions.
15 changes: 3 additions & 12 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,39 +1219,30 @@ static void bond_poll_controller(struct net_device *bond_dev)
{
}

static void __bond_netpoll_cleanup(struct bonding *bond)
static void bond_netpoll_cleanup(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave;
int i;

bond_for_each_slave(bond, slave, i)
if (IS_UP(slave->dev))
slave_disable_netpoll(slave);
}
static void bond_netpoll_cleanup(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);

read_lock(&bond->lock);
__bond_netpoll_cleanup(bond);
read_unlock(&bond->lock);
}

static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, gfp_t gfp)
{
struct bonding *bond = netdev_priv(dev);
struct slave *slave;
int i, err = 0;

read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i) {
err = slave_enable_netpoll(slave);
if (err) {
__bond_netpoll_cleanup(bond);
bond_netpoll_cleanup(dev);
break;
}
}
read_unlock(&bond->lock);
return err;
}

Expand Down

0 comments on commit c4cdef9

Please sign in to comment.