Patchwork Possible bug in bonding driver (with VLAN in ALB mode)

login
register
mail settings
Submitter Sven Anders
Date Oct. 27, 2008, 1:38 p.m.
Message ID <4905C44C.8000302@anduras.de>
Download mbox | patch
Permalink /patch/5914/
State Awaiting Upstream
Delegated to: Jeff Garzik
Headers show

Comments

Sven Anders - Oct. 27, 2008, 1:38 p.m.
Jay Vosburgh schrieb:

> 	Can you give this a try?  This patch just checks for VLAN-ness
> and extracts the real device if so, then does the usual "is it bonding"
> stuff to the real device.
> 
> [...]

Ok, this worked as expected. I think you can submit the patch.

So:  Signed-off-by: Sven Anders <anders@anduras.de>

>> What troubles me is, that nobody since the addition of VLAN support
>> to bonding in 2004 had this problem before. Did this (ever) work in
>> one older version of the bonding driver?
> 
> 	I suspect not; I don't recall checking the load balancing
> performance of this kind of configuration (all VLANs over balance-alb).

Ok.
I wrote a patch to show the current status of the load-balancing in ALB mode,
which helped me a lot identifing the problem.
I attached a version of it to this mail.

Moreover I see two additional problem:

1. If I want to use bonding on 10GBit ethernet cards, the counters
   will most likely overflow, because 10 seconds rebalancing interval
   is too long. But reducing it to 3 or 4 seconds may not be a real
   solution. Maybe we should use 64 Bit counters here?!

2. Is this right, that there is no IPv6 support für RLB?
   I'm not really sure, but we only have the following entries
   in the RLB structure:

	struct rlb_client_info {
	        __be32 ip_src;          /* the server IP address */
        	__be32 ip_dst;          /* the client IP address */
		[...]
	}

   And the function "rlb_update_entry_from_arp()" for updating the info
   by the received arp packages, only supports IPv4 (see struct arp_pkt
   too!)

Any comments welcome...

Cheers
 Sven

Patch

Signed-off-by: Sven Anders <anders@anduras.de>

diff -ru linux-2.6.28rc2/drivers/net/bonding/bond_alb.c linux-2.6.28rc2-new/drivers/net/bonding/bond_alb.c
--- linux-2.6.28rc2/drivers/net/bonding/bond_alb.c	2008-10-16 13:05:38.000000000 +0200
+++ linux-2.6.28rc2-new/drivers/net/bonding/bond_alb.c	2008-10-27 14:07:38.000000000 +0100
@@ -26,6 +26,7 @@ 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/pkt_sched.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -1772,3 +1773,88 @@ 
 	}
 }
 
+void bond_alb_info_show(struct seq_file *seq)
+{
+	struct bonding *bond = seq->private;
+	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+	struct rlb_client_info *rclient_info;
+	struct tlb_client_info *tclient_info;
+	struct slave *slave;
+	u32 index;
+	int i;
+	DECLARE_MAC_BUF(mac);
+
+	seq_puts(seq, "\nALB info\n");
+	seq_puts(seq, "\n Receive Load Balancing table:\n");
+	seq_puts(seq, "  Index Slave    Assigned Client-MAC"
+		      "         Server -> Client\n");
+
+	_lock_rx_hashtbl(bond);
+
+	index = bond_info->rx_hashtbl_head;
+	for (; index != RLB_NULL_INDEX; index = rclient_info->next) {
+		rclient_info = &(bond_info->rx_hashtbl[index]);
+		if (rclient_info) {
+			seq_printf(seq,	"%6u: %-8s %6s   %-17s  ",
+				   index,
+				   (rclient_info->slave &&
+				   rclient_info->slave->dev &&
+				   rclient_info->slave->dev->name ?
+				   rclient_info->slave->dev->name : "(none)"),
+				   (rclient_info->assigned ? "yes" : "no"),
+				   print_mac(mac, rclient_info->mac_dst));
+
+			/* Implemented as separate outputs to
+			   support IPv6 in the future (if it's supported) */
+			seq_printf(seq,	NIPQUAD_FMT " -> ",
+				   NIPQUAD(rclient_info->ip_src));
+			seq_printf(seq,	NIPQUAD_FMT "\n",
+				   NIPQUAD(rclient_info->ip_dst));
+		}
+	}
+
+	_unlock_rx_hashtbl(bond);
+
+	seq_puts(seq, "\n Transmit Load Balancing table:\n");
+	seq_printf(seq,	"  Unbalanced load: %u\n"
+			"  Rebalance interval: %u seconds\n\n",
+			bond_info->unbalanced_load,
+			BOND_TLB_REBALANCE_INTERVAL);
+
+	_lock_tx_hashtbl(bond);
+
+	/* Process each slave */
+	bond_for_each_slave(bond, slave, i) {
+
+		if (slave) {
+			seq_puts(seq, "  Slave    Used  Speed    Duplex"
+				      "  Current load\n");
+			seq_printf(seq, "  %-8s %3s   %-8u %4s      %10u\n",
+				   (slave->dev->name ?
+				    slave->dev->name : "none"),
+				   (SLAVE_IS_OK(slave) ? "yes" : "no"),
+				   slave->speed,
+				   (slave->duplex ? "full" : "half"),
+				   SLAVE_TLB_INFO(slave).load);
+
+			seq_puts(seq, "           Index    TX Bytes      "
+				      "Load history\n");
+
+			index = SLAVE_TLB_INFO(slave).head;
+			for (; index != TLB_NULL_INDEX;
+			     index = tclient_info->next) {
+				tclient_info = &(bond_info->tx_hashtbl[index]);
+				if (tclient_info)
+					seq_printf(seq,	"            "
+						   "%3u:  %10u"
+						   "        %10u\n",
+						   index,
+						   tclient_info->tx_bytes,
+						   tclient_info->load_history);
+			}
+			seq_puts(seq, "\n");
+		}
+	}
+
+	_unlock_tx_hashtbl(bond);
+}
diff -ru linux-2.6.28rc2/drivers/net/bonding/bond_alb.h linux-2.6.28rc2-new/drivers/net/bonding/bond_alb.h
--- linux-2.6.28rc2/drivers/net/bonding/bond_alb.h	2008-06-09 11:37:33.000000000 +0200
+++ linux-2.6.28rc2-new/drivers/net/bonding/bond_alb.h	2008-10-27 13:56:00.000000000 +0100
@@ -128,5 +128,6 @@ 
 void bond_alb_monitor(struct work_struct *);
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
 void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
+void bond_alb_info_show(struct seq_file *seq);
 #endif /* __BOND_ALB_H__ */
 
diff -ru linux-2.6.28rc2/drivers/net/bonding/bond_main.c linux-2.6.28rc2-new/drivers/net/bonding/bond_main.c
--- linux-2.6.28rc2/drivers/net/bonding/bond_main.c	2008-10-25 19:13:44.000000000 +0200
+++ linux-2.6.28rc2-new/drivers/net/bonding/bond_main.c	2008-10-27 14:08:25.000000000 +0100
@@ -3308,7 +3308,8 @@ 
 			seq_printf(seq, "\tPartner Mac Address: %s\n",
 				   print_mac(mac, ad_info.partner_system));
 		}
-	}
+	} else if (bond->params.mode == BOND_MODE_ALB)
+		bond_alb_info_show(seq);
 }
 
 static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)