bonding: simplify bond_3ad_update_lacp_rate and use RTNL for sync
authornikolay@redhat.com <nikolay@redhat.com>
Mon, 2 Sep 2013 11:51:40 +0000 (13:51 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Sep 2013 04:27:24 +0000 (00:27 -0400)
We can drop the use of bond->lock for mutual exclusion in
bond_3ad_update_lacp_rate and use RTNL in the sysfs store function
instead. This way we'll prevent races with mode change and interface
up/down as well as simplify update_lacp_rate by removing the check for
port->slave because it'll always be initialized (done while enslaving
with RTNL). This change will also help in the future removal of reader
bond->lock from bond_enslave.

Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_sysfs.c

index 90102652c82a9651a09a49741453fd76dbeb47a4..0d8f427ade938c75052d804138cd377b02c34f99 100644 (file)
@@ -2514,17 +2514,13 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
  */
 void bond_3ad_update_lacp_rate(struct bonding *bond)
 {
-       struct slave *slave;
        struct port *port = NULL;
+       struct slave *slave;
        int lacp_fast;
 
-       write_lock_bh(&bond->lock);
        lacp_fast = bond->params.lacp_fast;
-
        bond_for_each_slave(bond, slave) {
                port = &(SLAVE_AD_INFO(slave).port);
-               if (port->slave == NULL)
-                       continue;
                __get_state_machine_lock(port);
                if (lacp_fast)
                        port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
@@ -2532,6 +2528,4 @@ void bond_3ad_update_lacp_rate(struct bonding *bond)
                        port->actor_oper_port_state &= ~AD_STATE_LACP_TIMEOUT;
                __release_state_machine_lock(port);
        }
-
-       write_unlock_bh(&bond->lock);
 }
index 0f539de640dcb6f471378a5d44e47c0946a01d0c..ce4677668e2c1a025813bc2da681ea049a74064c 100644 (file)
@@ -852,8 +852,11 @@ static ssize_t bonding_store_lacp(struct device *d,
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
 {
-       int new_value, ret = count;
        struct bonding *bond = to_bond(d);
+       int new_value, ret = count;
+
+       if (!rtnl_trylock())
+               return restart_syscall();
 
        if (bond->dev->flags & IFF_UP) {
                pr_err("%s: Unable to update LACP rate because interface is up.\n",
@@ -883,6 +886,8 @@ static ssize_t bonding_store_lacp(struct device *d,
                ret = -EINVAL;
        }
 out:
+       rtnl_unlock();
+
        return ret;
 }
 static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,