netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] bonding: miscellaneous fixes
@ 2008-01-30  2:07 Jay Vosburgh
  2008-01-30  2:07 ` [PATCH 1/7] bonding: fix parameter parsing Jay Vosburgh
  0 siblings, 1 reply; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik

	Following are 7 bonding related patches:

	patch 1: Revamp parameter parsing again to handle all cases (missed
an edge case last time).

	patch 2: fix set_multicast_list locking issues

	patch 3: Fix possible NULL pointer deref at module init time

	patch 4: Fix race that causes invalid statistics

	patch 5: Don't acquire rtnl in ARP monitor; it's not needed

	patch 6: update version

	patch 7: update MAINTAINERS

	Patches are against the current netdev-2.6#upstream branch.

	Please apply.

	-J

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] bonding: fix parameter parsing
  2008-01-30  2:07 [PATCH 0/7] bonding: miscellaneous fixes Jay Vosburgh
@ 2008-01-30  2:07 ` Jay Vosburgh
  2008-01-30  2:07   ` [PATCH 2/7] bonding: fix set_multicast_list locking Jay Vosburgh
  2008-01-30  8:38   ` [PATCH 1/7] bonding: fix parameter parsing Jeff Garzik
  0 siblings, 2 replies; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, Jay Vosburgh

	My last fix (commit ece95f7fefe3afae19e641e1b3f5e64b00d5b948)
didn't handle one case correctly.  This resolves that, and it will now
correctly parse parameters with arbitrary white space, and either text
names or mode values.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 49a1982..f3b1e02 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4549,14 +4549,19 @@ static void bond_free_all(void)
 int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
 {
 	int mode = -1, i, rv;
-	char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
+	char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
 
-	rv = sscanf(buf, "%d", &mode);
-	if (!rv) {
+	for (p = (char *)buf; *p; p++)
+		if (!(isdigit(*p) || isspace(*p)))
+			break;
+
+	if (*p)
 		rv = sscanf(buf, "%20s", modestr);
-		if (!rv)
-			return -1;
-	}
+	else
+		rv = sscanf(buf, "%d", &mode);
+
+	if (!rv)
+		return -1;
 
 	for (i = 0; tbl[i].modename; i++) {
 		if (mode == tbl[i].mode)
-- 
1.5.3.4.206.g58ba4-dirty


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/7] bonding: fix set_multicast_list locking
  2008-01-30  2:07 ` [PATCH 1/7] bonding: fix parameter parsing Jay Vosburgh
@ 2008-01-30  2:07   ` Jay Vosburgh
  2008-01-30  2:07     ` [PATCH 3/7] bonding: fix NULL pointer deref in startup processing Jay Vosburgh
  2008-01-30  8:38   ` [PATCH 1/7] bonding: fix parameter parsing Jeff Garzik
  1 sibling, 1 reply; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, Jay Vosburgh

	This patch eliminates a problem (reported by lockdep) in the
bond_set_multicast_list function.  It first reduces the locking on
bond->lock to a simple read_lock, and second, adds netif_tx locking
around the bonding mc_list manipulations that occur outside of the
set_multicast_list function.

	The original problem was related to IPv6 addrconf activity.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f3b1e02..591b8b4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1464,10 +1464,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 			dev_set_allmulti(slave_dev, 1);
 		}
 
+		netif_tx_lock_bh(bond_dev);
 		/* upload master's mc_list to new slave */
 		for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
 			dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
 		}
+		netif_tx_unlock_bh(bond_dev);
 	}
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
@@ -1821,7 +1823,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 		}
 
 		/* flush master's mc_list from slave */
+		netif_tx_lock_bh(bond_dev);
 		bond_mc_list_flush(bond_dev, slave_dev);
+		netif_tx_unlock_bh(bond_dev);
 	}
 
 	netdev_set_master(slave_dev, NULL);
@@ -1942,7 +1946,9 @@ static int bond_release_all(struct net_device *bond_dev)
 			}
 
 			/* flush master's mc_list from slave */
+			netif_tx_lock_bh(bond_dev);
 			bond_mc_list_flush(bond_dev, slave_dev);
+			netif_tx_unlock_bh(bond_dev);
 		}
 
 		netdev_set_master(slave_dev, NULL);
@@ -3937,8 +3943,6 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
 	struct bonding *bond = bond_dev->priv;
 	struct dev_mc_list *dmi;
 
-	write_lock_bh(&bond->lock);
-
 	/*
 	 * Do promisc before checking multicast_mode
 	 */
@@ -3959,6 +3963,8 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
 		bond_set_allmulti(bond, -1);
 	}
 
+	read_lock(&bond->lock);
+
 	bond->flags = bond_dev->flags;
 
 	/* looking for addresses to add to slaves' mc list */
@@ -3979,7 +3985,7 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
 	bond_mc_list_destroy(bond);
 	bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC);
 
-	write_unlock_bh(&bond->lock);
+	read_unlock(&bond->lock);
 }
 
 /*
@@ -4526,7 +4532,9 @@ static void bond_free_all(void)
 		struct net_device *bond_dev = bond->dev;
 
 		bond_work_cancel_all(bond);
+		netif_tx_lock_bh(bond_dev);
 		bond_mc_list_destroy(bond);
+		netif_tx_unlock_bh(bond_dev);
 		/* Release the bonded slaves */
 		bond_release_all(bond_dev);
 		bond_deinit(bond_dev);
-- 
1.5.3.4.206.g58ba4-dirty


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/7] bonding: fix NULL pointer deref in startup processing
  2008-01-30  2:07   ` [PATCH 2/7] bonding: fix set_multicast_list locking Jay Vosburgh
@ 2008-01-30  2:07     ` Jay Vosburgh
  2008-01-30  2:07       ` [PATCH 4/7] bonding: fix race that causes invalid statistics Jay Vosburgh
  0 siblings, 1 reply; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, Jay Vosburgh

	Fix the "are we creating a duplicate" check to not compare
the name if the name is NULL (meaning that the system should select
a name).  Bug reported by Benny Amorsen <benny+usenet@amorsen.dk>.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 591b8b4..63866da 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4896,14 +4896,16 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
 	down_write(&bonding_rwsem);
 
 	/* Check to see if the bond already exists. */
-	list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
-		if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
-			printk(KERN_ERR DRV_NAME
+	if (name) {
+		list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+			if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
+				printk(KERN_ERR DRV_NAME
 			       ": cannot add bond %s; it already exists\n",
-			       name);
-			res = -EPERM;
-			goto out_rtnl;
-		}
+				       name);
+				res = -EPERM;
+				goto out_rtnl;
+			}
+	}
 
 	bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
 				ether_setup);
-- 
1.5.3.4.206.g58ba4-dirty


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/7] bonding: fix race that causes invalid statistics
  2008-01-30  2:07     ` [PATCH 3/7] bonding: fix NULL pointer deref in startup processing Jay Vosburgh
@ 2008-01-30  2:07       ` Jay Vosburgh
  2008-01-30  2:07         ` [PATCH 5/7] bonding: do not acquire rtnl in ARP monitor Jay Vosburgh
  0 siblings, 1 reply; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, Andy Gospodarek, Chris Snook

From: Andy Gospodarek <andy@greyhouse.net>

I've seen reports of invalid stats in /proc/net/dev for bonding
interfaces, and found it's a pretty easy problem to reproduce.  Since
the current code zeros the bonding stats when a read is requested and a
pointer to that data is returned to the caller we cannot guarantee that
the caller has completely accessed the data before a successive call to
request the stats zeroes the stats again.

This patch creates a new stack variable to keep track of the updated
stats and copies the data from that variable into the bonding stats
structure.  This ensures that the value for any of the bonding stats
should not incorrectly return zero for any of the bonding statistics.
This does use more stack space and require an extra memcpy, but it seems
like a fair trade-off for consistently correct bonding statistics.

Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Chris Snook <csnook@redhat.com>
Acked-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |   57 ++++++++++++++++++++------------------
 1 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 63866da..0cc853e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3775,41 +3775,44 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct net_device_stats *stats = &(bond->stats), *sstats;
+	struct net_device_stats local_stats;
 	struct slave *slave;
 	int i;
 
-	memset(stats, 0, sizeof(struct net_device_stats));
+	memset(&local_stats, 0, sizeof(struct net_device_stats));
 
 	read_lock_bh(&bond->lock);
 
 	bond_for_each_slave(bond, slave, i) {
 		sstats = slave->dev->get_stats(slave->dev);
-		stats->rx_packets += sstats->rx_packets;
-		stats->rx_bytes += sstats->rx_bytes;
-		stats->rx_errors += sstats->rx_errors;
-		stats->rx_dropped += sstats->rx_dropped;
-
-		stats->tx_packets += sstats->tx_packets;
-		stats->tx_bytes += sstats->tx_bytes;
-		stats->tx_errors += sstats->tx_errors;
-		stats->tx_dropped += sstats->tx_dropped;
-
-		stats->multicast += sstats->multicast;
-		stats->collisions += sstats->collisions;
-
-		stats->rx_length_errors += sstats->rx_length_errors;
-		stats->rx_over_errors += sstats->rx_over_errors;
-		stats->rx_crc_errors += sstats->rx_crc_errors;
-		stats->rx_frame_errors += sstats->rx_frame_errors;
-		stats->rx_fifo_errors += sstats->rx_fifo_errors;
-		stats->rx_missed_errors += sstats->rx_missed_errors;
-
-		stats->tx_aborted_errors += sstats->tx_aborted_errors;
-		stats->tx_carrier_errors += sstats->tx_carrier_errors;
-		stats->tx_fifo_errors += sstats->tx_fifo_errors;
-		stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
-		stats->tx_window_errors += sstats->tx_window_errors;
-	}
+		local_stats.rx_packets += sstats->rx_packets;
+		local_stats.rx_bytes += sstats->rx_bytes;
+		local_stats.rx_errors += sstats->rx_errors;
+		local_stats.rx_dropped += sstats->rx_dropped;
+
+		local_stats.tx_packets += sstats->tx_packets;
+		local_stats.tx_bytes += sstats->tx_bytes;
+		local_stats.tx_errors += sstats->tx_errors;
+		local_stats.tx_dropped += sstats->tx_dropped;
+
+		local_stats.multicast += sstats->multicast;
+		local_stats.collisions += sstats->collisions;
+
+		local_stats.rx_length_errors += sstats->rx_length_errors;
+		local_stats.rx_over_errors += sstats->rx_over_errors;
+		local_stats.rx_crc_errors += sstats->rx_crc_errors;
+		local_stats.rx_frame_errors += sstats->rx_frame_errors;
+		local_stats.rx_fifo_errors += sstats->rx_fifo_errors;
+		local_stats.rx_missed_errors += sstats->rx_missed_errors;
+
+		local_stats.tx_aborted_errors += sstats->tx_aborted_errors;
+		local_stats.tx_carrier_errors += sstats->tx_carrier_errors;
+		local_stats.tx_fifo_errors += sstats->tx_fifo_errors;
+		local_stats.tx_heartbeat_errors += sstats->tx_heartbeat_errors;
+		local_stats.tx_window_errors += sstats->tx_window_errors;
+	}
+
+	memcpy(stats, &local_stats, sizeof(struct net_device_stats));
 
 	read_unlock_bh(&bond->lock);
 
-- 
1.5.3.4.206.g58ba4-dirty


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/7] bonding: do not acquire rtnl in ARP monitor
  2008-01-30  2:07       ` [PATCH 4/7] bonding: fix race that causes invalid statistics Jay Vosburgh
@ 2008-01-30  2:07         ` Jay Vosburgh
  2008-01-30  2:07           ` [PATCH 6/7] bonding: update version Jay Vosburgh
  0 siblings, 1 reply; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, Jay Vosburgh

	The ARP monitor functions currently acquire RTNL when performing
failover operations, but do so incorrectly (out of order).  This causes
various warnings from might_sleep.

	The ARP monitor isn't supported for any of the bonding modes
that actually require RTNL, so it is safe to not hold RTNL when
failing over in the ARP monitor.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bond_main.c |   12 ------------
 1 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 0cc853e..b532125 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2801,14 +2801,11 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
 	}
 
 	if (do_failover) {
-		rtnl_lock();
 		write_lock_bh(&bond->curr_slave_lock);
 
 		bond_select_active_slave(bond);
 
 		write_unlock_bh(&bond->curr_slave_lock);
-		rtnl_unlock();
-
 	}
 
 re_arm:
@@ -2865,8 +2862,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
 
 				slave->link = BOND_LINK_UP;
 
-				rtnl_lock();
-
 				write_lock_bh(&bond->curr_slave_lock);
 
 				if ((!bond->curr_active_slave) &&
@@ -2902,7 +2897,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
 				}
 
 				write_unlock_bh(&bond->curr_slave_lock);
-				rtnl_unlock();
 			}
 		} else {
 			read_lock(&bond->curr_slave_lock);
@@ -2972,7 +2966,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
 			       bond->dev->name,
 			       slave->dev->name);
 
-			rtnl_lock();
 			write_lock_bh(&bond->curr_slave_lock);
 
 			bond_select_active_slave(bond);
@@ -2980,8 +2973,6 @@ void bond_activebackup_arp_mon(struct work_struct *work)
 
 			write_unlock_bh(&bond->curr_slave_lock);
 
-			rtnl_unlock();
-
 			bond->current_arp_slave = slave;
 
 			if (slave) {
@@ -2999,13 +2990,10 @@ void bond_activebackup_arp_mon(struct work_struct *work)
 			       bond->primary_slave->dev->name);
 
 			/* primary is up so switch to it */
-			rtnl_lock();
 			write_lock_bh(&bond->curr_slave_lock);
 			bond_change_active_slave(bond, bond->primary_slave);
 			write_unlock_bh(&bond->curr_slave_lock);
 
-			rtnl_unlock();
-
 			slave = bond->primary_slave;
 			slave->jiffies = jiffies;
 		} else {
-- 
1.5.3.4.206.g58ba4-dirty


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/7] bonding: update version
  2008-01-30  2:07         ` [PATCH 5/7] bonding: do not acquire rtnl in ARP monitor Jay Vosburgh
@ 2008-01-30  2:07           ` Jay Vosburgh
  2008-01-30  2:07             ` [PATCH 7/7] bonding: update MAINTAINERS Jay Vosburgh
  0 siblings, 1 reply; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, Jay Vosburgh

	Update bonding to version 3.2.4.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 drivers/net/bonding/bonding.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 6d83be4..67ccad6 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"3.2.3"
-#define DRV_RELDATE	"December 6, 2007"
+#define DRV_VERSION	"3.2.4"
+#define DRV_RELDATE	"January 28, 2008"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
-- 
1.5.3.4.206.g58ba4-dirty


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/7] bonding: update MAINTAINERS
  2008-01-30  2:07           ` [PATCH 6/7] bonding: update version Jay Vosburgh
@ 2008-01-30  2:07             ` Jay Vosburgh
  0 siblings, 0 replies; 9+ messages in thread
From: Jay Vosburgh @ 2008-01-30  2:07 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik, Jay Vosburgh

	Remove Chad Tindel; he hasn't been involved for a number
of years.

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
---
 MAINTAINERS |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2340cfb..4b7fa32 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -930,8 +930,6 @@ M:	maxk@qualcomm.com
 S:	Maintained
 
 BONDING DRIVER
-P:	Chad Tindel
-M:	ctindel@users.sourceforge.net
 P:	Jay Vosburgh
 M:	fubar@us.ibm.com
 L:	bonding-devel@lists.sourceforge.net
-- 
1.5.3.4.206.g58ba4-dirty


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/7] bonding: fix parameter parsing
  2008-01-30  2:07 ` [PATCH 1/7] bonding: fix parameter parsing Jay Vosburgh
  2008-01-30  2:07   ` [PATCH 2/7] bonding: fix set_multicast_list locking Jay Vosburgh
@ 2008-01-30  8:38   ` Jeff Garzik
  1 sibling, 0 replies; 9+ messages in thread
From: Jeff Garzik @ 2008-01-30  8:38 UTC (permalink / raw)
  To: Jay Vosburgh; +Cc: netdev

Jay Vosburgh wrote:
> 	My last fix (commit ece95f7fefe3afae19e641e1b3f5e64b00d5b948)
> didn't handle one case correctly.  This resolves that, and it will now
> correctly parse parameters with arbitrary white space, and either text
> names or mode values.
> 
> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
> ---
>  drivers/net/bonding/bond_main.c |   17 +++++++++++------
>  1 files changed, 11 insertions(+), 6 deletions(-)

applied 1-7



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-01-30  8:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-30  2:07 [PATCH 0/7] bonding: miscellaneous fixes Jay Vosburgh
2008-01-30  2:07 ` [PATCH 1/7] bonding: fix parameter parsing Jay Vosburgh
2008-01-30  2:07   ` [PATCH 2/7] bonding: fix set_multicast_list locking Jay Vosburgh
2008-01-30  2:07     ` [PATCH 3/7] bonding: fix NULL pointer deref in startup processing Jay Vosburgh
2008-01-30  2:07       ` [PATCH 4/7] bonding: fix race that causes invalid statistics Jay Vosburgh
2008-01-30  2:07         ` [PATCH 5/7] bonding: do not acquire rtnl in ARP monitor Jay Vosburgh
2008-01-30  2:07           ` [PATCH 6/7] bonding: update version Jay Vosburgh
2008-01-30  2:07             ` [PATCH 7/7] bonding: update MAINTAINERS Jay Vosburgh
2008-01-30  8:38   ` [PATCH 1/7] bonding: fix parameter parsing Jeff Garzik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).