[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20110507114802.9CE7513A6A@rere.qmqm.pl>
Date: Sat, 7 May 2011 13:48:02 +0200 (CEST)
From: Michał Mirosław <mirq-linux@...e.qmqm.pl>
To: netdev@...r.kernel.org
Cc: Jay Vosburgh <fubar@...ibm.com>,
Andy Gospodarek <andy@...yhouse.net>
Subject: [PATCH] net: bonding: factor out rlock(bond->lock) in xmit path
Pull read_lock(&bond->lock) and BOND_IS_OK() to bond_start_xmit() from
mode-dependent xmit functions.
netif_running() is always true in hard_start_xmit.
Signed-off-by: Michał Mirosław <mirq-linux@...e.qmqm.pl>
---
drivers/net/bonding/bond_3ad.c | 10 +-----
drivers/net/bonding/bond_alb.c | 11 +-----
drivers/net/bonding/bond_main.c | 74 +++++++++++++++++----------------------
3 files changed, 35 insertions(+), 60 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index d4160f8..c7537abc 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2403,14 +2403,6 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
struct ad_info ad_info;
int res = 1;
- /* make sure that the slaves list will
- * not change during tx
- */
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
-
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n",
dev->name);
@@ -2464,7 +2456,7 @@ out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 3b7b040..8f2d2e7 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1225,16 +1225,10 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
skb_reset_mac_header(skb);
eth_data = eth_hdr(skb);
- /* make sure that the curr_active_slave and the slaves list do
- * not change during tx
+ /* make sure that the curr_active_slave do not change during tx
*/
- read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
-
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
const struct iphdr *iph = ip_hdr(skb);
@@ -1334,13 +1328,12 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
}
}
-out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
read_unlock(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 04a2205..1f8902e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3975,10 +3975,6 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
int i, slave_no, res = 1;
struct iphdr *iph = ip_hdr(skb);
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
/*
* Start with the curr_active_slave that joined the bond as the
* default for sending IGMP traffic. For failover purposes one
@@ -4025,7 +4021,7 @@ out:
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
@@ -4039,24 +4035,18 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
struct bonding *bond = netdev_priv(bond_dev);
int res = 1;
- read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (!BOND_IS_OK(bond))
- goto out;
+ if (bond->curr_active_slave)
+ res = bond_dev_queue_xmit(bond, skb,
+ bond->curr_active_slave->dev);
- if (!bond->curr_active_slave)
- goto out;
-
- res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
-
-out:
if (res)
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
read_unlock(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
@@ -4073,11 +4063,6 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
int i;
int res = 1;
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
-
slave_no = bond->xmit_hash_policy(skb, bond->slave_cnt);
bond_for_each_slave(bond, slave, i) {
@@ -4097,12 +4082,11 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
}
}
-out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
- read_unlock(&bond->lock);
+
return NETDEV_TX_OK;
}
@@ -4117,11 +4101,6 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
int i;
int res = 1;
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond))
- goto out;
-
read_lock(&bond->curr_slave_lock);
start_at = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
@@ -4160,7 +4139,6 @@ out:
dev_kfree_skb(skb);
/* frame sent to all suitable interfaces */
- read_unlock(&bond->lock);
return NETDEV_TX_OK;
}
@@ -4192,10 +4170,8 @@ static inline int bond_slave_override(struct bonding *bond,
struct slave *slave = NULL;
struct slave *check_slave;
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond) || !skb->queue_mapping)
- goto out;
+ if (!skb->queue_mapping)
+ return 1;
/* Find out if any slaves have the same mapping as this skb. */
bond_for_each_slave(bond, check_slave, i) {
@@ -4211,8 +4187,6 @@ static inline int bond_slave_override(struct bonding *bond,
res = bond_dev_queue_xmit(bond, skb, slave->dev);
}
-out:
- read_unlock(&bond->lock);
return res;
}
@@ -4234,17 +4208,10 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
return txq;
}
-static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bonding *bond = netdev_priv(dev);
- /*
- * If we risk deadlock from transmitting this in the
- * netpoll path, tell netpoll to queue the frame for later tx
- */
- if (is_netpoll_tx_blocked(dev))
- return NETDEV_TX_BUSY;
-
if (TX_QUEUE_OVERRIDE(bond->params.mode)) {
if (!bond_slave_override(bond, skb))
return NETDEV_TX_OK;
@@ -4274,6 +4241,29 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
+static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bonding *bond = netdev_priv(dev);
+ netdev_tx_t ret = NETDEV_TX_OK;
+
+ /*
+ * If we risk deadlock from transmitting this in the
+ * netpoll path, tell netpoll to queue the frame for later tx
+ */
+ if (is_netpoll_tx_blocked(dev))
+ return NETDEV_TX_BUSY;
+
+ read_lock(&bond->lock);
+
+ if (bond->slave_cnt)
+ ret = __bond_start_xmit(skb, dev);
+ else
+ dev_kfree_skb(skb);
+
+ read_unlock(&bond->lock);
+
+ return ret;
+}
/*
* set bond mode specific net device operations
--
1.7.2.5
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists