Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=cf5f9044934658dd3ffc628a60cd37c70f8168b1
Commit:     cf5f9044934658dd3ffc628a60cd37c70f8168b1
Parent:     1b76b31693d4a6088dec104ff6a6ead54081a3c2
Author:     Jay Vosburgh <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 17 17:37:47 2007 -0700
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Tue Oct 23 20:32:00 2007 -0400

    bonding: Convert balance-rr transmit to new locking
    
        Change locking in balance-rr transmit processing to use a free
    running counter to determine which slave to transmit on.  Instead, a
    free-running counter is maintained, and modulo arithmetic used to select
    a slave for transmit.
    
        This removes lock operations from the TX path, and eliminates
    a deadlock introduced by the conversion to work queues.
    
    Signed-off-by: Andy Gospodarek <[EMAIL PROTECTED]>
    Signed-off-by: Jay Vosburgh <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/bonding/bond_main.c |   25 ++++++++++++-------------
 drivers/net/bonding/bonding.h   |    1 +
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ed361d6..862ed8e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4057,8 +4057,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, 
struct net_device *bond_dev
 {
        struct bonding *bond = bond_dev->priv;
        struct slave *slave, *start_at;
-       int i;
-       int res = 1;
+       int i, slave_no, res = 1;
 
        read_lock(&bond->lock);
 
@@ -4066,29 +4065,29 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, 
struct net_device *bond_dev
                goto out;
        }
 
-       read_lock(&bond->curr_slave_lock);
-       slave = start_at = bond->curr_active_slave;
-       read_unlock(&bond->curr_slave_lock);
+       /*
+        * Concurrent TX may collide on rr_tx_counter; we accept that
+        * as being rare enough not to justify using an atomic op here
+        */
+       slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
 
-       if (!slave) {
-               goto out;
+       bond_for_each_slave(bond, slave, i) {
+               slave_no--;
+               if (slave_no < 0) {
+                       break;
+               }
        }
 
+       start_at = slave;
        bond_for_each_slave_from(bond, slave, i, start_at) {
                if (IS_UP(slave->dev) &&
                    (slave->link == BOND_LINK_UP) &&
                    (slave->state == BOND_STATE_ACTIVE)) {
                        res = bond_dev_queue_xmit(bond, skb, slave->dev);
-
-                       write_lock(&bond->curr_slave_lock);
-                       bond->curr_active_slave = slave->next;
-                       write_unlock(&bond->curr_slave_lock);
-
                        break;
                }
        }
 
-
 out:
        if (res) {
                /* no suitable interface, frame not sent */
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index a8f2384..d1ed14b 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -197,6 +197,7 @@ struct bonding {
        int      (*xmit_hash_policy)(struct sk_buff *, struct net_device *, 
int);
        __be32   master_ip;
        u16      flags;
+       u16      rr_tx_counter;
        struct   ad_bond_info ad_info;
        struct   alb_bond_info alb_info;
        struct   bond_params params;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to