bonding: add proper __rcu annotation for current_arp_slave
authorEric Dumazet <edumazet@google.com>
Tue, 15 Jul 2014 13:56:56 +0000 (06:56 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Jul 2014 00:49:42 +0000 (17:49 -0700)
Using __rcu annotation actually helps to spot all accesses to
bond->current_arp_slave are correctly protected, with LOCKDEP support.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Nikolay Aleksandrov <nikolay@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h

index 27ce838d45d6dd29d982e744265eec0958c0c945..6d3b8db882a1066d5525861c141decef8d664fdd 100644 (file)
@@ -1711,7 +1711,7 @@ static int __bond_release_one(struct net_device *bond_dev,
 
        oldcurrent = rcu_access_pointer(bond->curr_active_slave);
 
-       bond->current_arp_slave = NULL;
+       RCU_INIT_POINTER(bond->current_arp_slave, NULL);
 
        if (!all && (!bond->params.fail_over_mac ||
                     BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)) {
@@ -2569,7 +2569,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
                 * before being taken out
                 */
                if (!bond_is_active_slave(slave) &&
-                   !bond->current_arp_slave &&
+                   !rcu_access_pointer(bond->current_arp_slave) &&
                    !bond_time_in_interval(bond, last_rx, 3)) {
                        slave->new_link = BOND_LINK_DOWN;
                        commit++;
@@ -2615,12 +2615,15 @@ static void bond_ab_arp_commit(struct bonding *bond)
                        if (rtnl_dereference(bond->curr_active_slave) != slave ||
                            (!rtnl_dereference(bond->curr_active_slave) &&
                             bond_time_in_interval(bond, trans_start, 1))) {
+                               struct slave *current_arp_slave;
+
+                               current_arp_slave = rtnl_dereference(bond->current_arp_slave);
                                slave->link = BOND_LINK_UP;
-                               if (bond->current_arp_slave) {
+                               if (current_arp_slave) {
                                        bond_set_slave_inactive_flags(
-                                               bond->current_arp_slave,
+                                               current_arp_slave,
                                                BOND_SLAVE_NOTIFY_NOW);
-                                       bond->current_arp_slave = NULL;
+                                       RCU_INIT_POINTER(bond->current_arp_slave, NULL);
                                }
 
                                pr_info("%s: link status definitely up for interface %s\n",
@@ -2646,7 +2649,7 @@ static void bond_ab_arp_commit(struct bonding *bond)
                                bond->dev->name, slave->dev->name);
 
                        if (slave == rtnl_dereference(bond->curr_active_slave)) {
-                               bond->current_arp_slave = NULL;
+                               RCU_INIT_POINTER(bond->current_arp_slave, NULL);
                                goto do_failover;
                        }
 
index d03d2ae4d3af4c763bad374d80c32e246a206aa8..b2e548e9d7382d96455b1f3db4108f878e557bc5 100644 (file)
@@ -195,7 +195,7 @@ struct slave {
 struct bonding {
        struct   net_device *dev; /* first - useful for panic debug */
        struct   slave __rcu *curr_active_slave;
-       struct   slave *current_arp_slave;
+       struct   slave __rcu *current_arp_slave;
        struct   slave *primary_slave;
        bool     force_primary;
        s32      slave_cnt; /* never change this value outside the attach/detach wrappers */