I believe so. The lock is held here nominally to mutex
bonding's vlan_list. The bond_add_vlans_on_slave function actually does
the lock and call to ndo_vlan_rx_register (plus one add_vid call per
configured VLAN); I think the call frame in the above stack has been
optimized out.
For the specific cases of bond_add_vlans_on_slave and
bond_del_vlans_from_slave, we should be able to get away without holding
the bond->lock because we also hold RTNL, and it looks like all changes
to the vlan_list are implicitly mutexed by RTNL because all VLAN add /
remove for device or vid end up being done under RTNL.
The cases within bonding that change the vlan_list will still
have to hold bond->lock, because other call sites within bonding check
the vlan_list without RTNL (and it would be impractical to have them do
so).
The patch is as follows; I'm compiling this now to test. If it
pans out, I'll post a formal submission in a bit.
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8228088..decddf5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -565,10 +565,8 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla
struct vlan_entry *vlan;
const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
- write_lock_bh(&bond->lock);
-
if (list_empty(&bond->vlan_list))
- goto out;
+ return;
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
slave_ops->ndo_vlan_rx_register)
@@ -576,13 +574,10 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
!(slave_ops->ndo_vlan_rx_add_vid))
- goto out;
+ return;
list_for_each_entry(vlan, &bond->vlan_list, vlan_list)
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,
@@ -592,10 +587,8 @@ static void bond_del_vlans_from_slave(struct bonding *bond,
struct vlan_entry *vlan;
struct net_device *vlan_dev;
- write_lock_bh(&bond->lock);
-
if (list_empty(&bond->vlan_list))
- goto out;
+ return;
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
!(slave_ops->ndo_vlan_rx_kill_vid))
@@ -614,9 +607,6 @@ unreg:
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
slave_ops->ndo_vlan_rx_register)
slave_ops->ndo_vlan_rx_register(slave_dev, NULL);
-
-out:
- write_unlock_bh(&bond->lock);
}
/*------------------------------- Link status -------------------------------*/
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html