bonding, net: Move last_rx update into bonding recv logic
authorJay Vosburgh <fubar@us.ibm.com>
Tue, 4 Nov 2008 02:16:50 +0000 (18:16 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 4 Nov 2008 02:16:50 +0000 (18:16 -0800)
The only user of the net_device->last_rx field is bonding.
This patch adds a conditional update of last_rx to the bonding special
logic in skb_bond_should_drop, causing last_rx to only be updated when
the ARP monitor is running.

This frees network device drivers from the necessity of
updating last_rx, which can have cache line thrash issues.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
include/linux/if.h
include/linux/netdevice.h

index 56c823c175fed16bb846f63ef5cec56370e0df54..39575d7649743750621c64afe130e28d07c6ecfc 100644 (file)
@@ -4564,6 +4564,8 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
        bond_dev->tx_queue_len = 0;
        bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
        bond_dev->priv_flags |= IFF_BONDING;
+       if (bond->params.arp_interval)
+               bond_dev->priv_flags |= IFF_MASTER_ARPMON;
 
        /* At first, we block adding VLANs. That's the only way to
         * prevent problems that occur when adding VLANs over an
index 296a865b75d29291a02ef169bab0a9229613aa1a..e400d7dfdfc860464da51e68832fc4b869e7dfe4 100644 (file)
@@ -620,6 +620,8 @@ static ssize_t bonding_store_arp_interval(struct device *d,
               ": %s: Setting ARP monitoring interval to %d.\n",
               bond->dev->name, new_value);
        bond->params.arp_interval = new_value;
+       if (bond->params.arp_interval)
+               bond->dev->priv_flags |= IFF_MASTER_ARPMON;
        if (bond->params.miimon) {
                printk(KERN_INFO DRV_NAME
                       ": %s: ARP monitoring cannot be used with MII monitoring. "
@@ -1039,6 +1041,7 @@ static ssize_t bonding_store_miimon(struct device *d,
                               "ARP monitoring. Disabling ARP monitoring...\n",
                               bond->dev->name);
                        bond->params.arp_interval = 0;
+                       bond->dev->priv_flags &= ~IFF_MASTER_ARPMON;
                        if (bond->params.arp_validate) {
                                bond_unregister_arp(bond);
                                bond->params.arp_validate =
index 65246846c844089e5eef7fce7054789f26ffe817..2a6e29620a963bcbfbd9195859fbab7c07f84266 100644 (file)
@@ -65,6 +65,7 @@
 #define IFF_BONDING    0x20            /* bonding master or slave      */
 #define IFF_SLAVE_NEEDARP 0x40         /* need ARPs for validation     */
 #define IFF_ISATAP     0x80            /* ISATAP interface (RFC4214)   */
+#define IFF_MASTER_ARPMON 0x100                /* bonding master, ARP mon in use */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
index 9d77b1d7dca806e540838d27bbc632961a340f0e..f1b0dbe584648a839eb6ae13228d529d10e752f1 100644 (file)
@@ -1742,22 +1742,26 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
        struct net_device *dev = skb->dev;
        struct net_device *master = dev->master;
 
-       if (master &&
-           (dev->priv_flags & IFF_SLAVE_INACTIVE)) {
-               if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
-                   skb->protocol == __constant_htons(ETH_P_ARP))
-                       return 0;
-
-               if (master->priv_flags & IFF_MASTER_ALB) {
-                       if (skb->pkt_type != PACKET_BROADCAST &&
-                           skb->pkt_type != PACKET_MULTICAST)
+       if (master) {
+               if (master->priv_flags & IFF_MASTER_ARPMON)
+                       dev->last_rx = jiffies;
+
+               if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
+                       if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
+                           skb->protocol == __constant_htons(ETH_P_ARP))
                                return 0;
-               }
-               if (master->priv_flags & IFF_MASTER_8023AD &&
-                   skb->protocol == __constant_htons(ETH_P_SLOW))
-                       return 0;
 
-               return 1;
+                       if (master->priv_flags & IFF_MASTER_ALB) {
+                               if (skb->pkt_type != PACKET_BROADCAST &&
+                                   skb->pkt_type != PACKET_MULTICAST)
+                                       return 0;
+                       }
+                       if (master->priv_flags & IFF_MASTER_8023AD &&
+                           skb->protocol == __constant_htons(ETH_P_SLOW))
+                               return 0;
+
+                       return 1;
+               }
        }
        return 0;
 }