From patchwork Sat May 7 11:48:02 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= X-Patchwork-Id: 94483 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 31A4310081D for ; Sat, 7 May 2011 21:48:14 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755019Ab1EGLsI (ORCPT ); Sat, 7 May 2011 07:48:08 -0400 Received: from rere.qmqm.pl ([89.167.52.164]:55065 "EHLO rere.qmqm.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753756Ab1EGLsF (ORCPT ); Sat, 7 May 2011 07:48:05 -0400 Received: by rere.qmqm.pl (Postfix, from userid 1000) id 9CE7513A6A; Sat, 7 May 2011 13:48:02 +0200 (CEST) From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Subject: [PATCH] net: bonding: factor out rlock(bond->lock) in xmit path MIME-Version: 1.0 To: netdev@vger.kernel.org Cc: Jay Vosburgh , Andy Gospodarek Message-Id: <20110507114802.9CE7513A6A@rere.qmqm.pl> Date: Sat, 7 May 2011 13:48:02 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 --- 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