bonding: don't lock when copying/clearing VLAN list on slave

When copying VLAN information to or removing from a slave
during slave addition or removal, the bonding code currently holds
the bond->lock for write to prevent concurrent modification of the
vlan_list / vlgrp.

	This is unnecessary, as all of these operations occur under
RTNL.  Holding the bond->lock also caused might_sleep issues for
some drivers' ndo_vlan_* functions.  This patch removes the extra
locking.

	Problem reported by Michael Chan <mchan@broadcom.com>

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Cc: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jay Vosburgh 2010-07-21 12:14:48 +00:00 committed by David S. Miller
parent f35188faa0
commit 03dc2f4c52

View File

@ -570,10 +570,8 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla
struct vlan_entry *vlan; struct vlan_entry *vlan;
const struct net_device_ops *slave_ops = slave_dev->netdev_ops; const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
write_lock_bh(&bond->lock);
if (!bond->vlgrp) if (!bond->vlgrp)
goto out; return;
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
slave_ops->ndo_vlan_rx_register) slave_ops->ndo_vlan_rx_register)
@ -581,13 +579,10 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
!(slave_ops->ndo_vlan_rx_add_vid)) !(slave_ops->ndo_vlan_rx_add_vid))
goto out; return;
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) list_for_each_entry(vlan, &bond->vlan_list, vlan_list)
slave_ops->ndo_vlan_rx_add_vid(slave_dev, vlan->vlan_id); slave_ops->ndo_vlan_rx_add_vid(slave_dev, vlan->vlan_id);
out:
write_unlock_bh(&bond->lock);
} }
static void bond_del_vlans_from_slave(struct bonding *bond, static void bond_del_vlans_from_slave(struct bonding *bond,
@ -597,10 +592,8 @@ static void bond_del_vlans_from_slave(struct bonding *bond,
struct vlan_entry *vlan; struct vlan_entry *vlan;
struct net_device *vlan_dev; struct net_device *vlan_dev;
write_lock_bh(&bond->lock);
if (!bond->vlgrp) if (!bond->vlgrp)
goto out; return;
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
!(slave_ops->ndo_vlan_rx_kill_vid)) !(slave_ops->ndo_vlan_rx_kill_vid))
@ -621,9 +614,6 @@ unreg:
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) && if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
slave_ops->ndo_vlan_rx_register) slave_ops->ndo_vlan_rx_register)
slave_ops->ndo_vlan_rx_register(slave_dev, NULL); slave_ops->ndo_vlan_rx_register(slave_dev, NULL);
out:
write_unlock_bh(&bond->lock);
} }
/*------------------------------- Link status -------------------------------*/ /*------------------------------- Link status -------------------------------*/