Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 net-next 15/27] bonding: remove unused bond_for_each_slave_from()
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

It has no users, so we can remove it.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    New patch.

 drivers/net/bonding/bonding.h | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 4d725a5..e484c38 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -94,19 +94,6 @@
 					  bond_to_slave((pos)->list.prev))
 
 /**
- * bond_for_each_slave_from - iterate the slaves list from a starting point
- * @bond:	the bond holding this list.
- * @pos:	current slave.
- * @cnt:	counter for max number of moves
- * @start:	starting point.
- *
- * Caller must hold bond->lock
- */
-#define bond_for_each_slave_from(bond, pos, cnt, start) \
-	for (cnt = 0, pos = start; pos && cnt < (bond)->slave_cnt; \
-	     cnt++, pos = bond_next_slave(bond, pos))
-
-/**
  * bond_for_each_slave - iterate over all slaves
  * @bond:	the bond holding this list
  * @pos:	current slave
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 13/27] bonding: rework bond_find_best_slave() to use bond_for_each_slave()
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

bond_find_best_slave() does not have to be balanced - i.e. return the slave
that is *after* some other slave, but rather return the best slave that
suits, except of bond->primary_slave - in which case we just return it if
it's suitable.

After that we just look through all the slaves and return either first up
slave or the slave whose link came back earliest.

We also don't care about curr_active_slave lock cause we use it in
bond_should_change_active() only and there we take it right away - i.e. it
won't go away.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    New patch.

 drivers/net/bonding/bond_main.c | 43 ++++++++++++-----------------------------
 1 file changed, 12 insertions(+), 31 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2075321..b5497e7 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -785,43 +785,24 @@ static bool bond_should_change_active(struct bonding *bond)
 /**
  * find_best_interface - select the best available slave to be the active one
  * @bond: our bonding struct
- *
- * Warning: Caller must hold curr_slave_lock for writing.
  */
 static struct slave *bond_find_best_slave(struct bonding *bond)
 {
-	struct slave *new_active, *old_active;
-	struct slave *bestslave = NULL;
+	struct slave *slave, *bestslave = NULL;
+	struct list_head *iter;
 	int mintime = bond->params.updelay;
-	int i;
 
-	new_active = bond->curr_active_slave;
-
-	if (!new_active) { /* there were no active slaves left */
-		new_active = bond_first_slave(bond);
-		if (!new_active)
-			return NULL; /* still no slave, return NULL */
-	}
+	if (bond->primary_slave && bond->primary_slave->link == BOND_LINK_UP &&
+	    bond_should_change_active(bond))
+		return bond->primary_slave;
 
-	if ((bond->primary_slave) &&
-	    bond->primary_slave->link == BOND_LINK_UP &&
-	    bond_should_change_active(bond)) {
-		new_active = bond->primary_slave;
-	}
-
-	/* remember where to stop iterating over the slaves */
-	old_active = new_active;
-
-	bond_for_each_slave_from(bond, new_active, i, old_active) {
-		if (new_active->link == BOND_LINK_UP) {
-			return new_active;
-		} else if (new_active->link == BOND_LINK_BACK &&
-			   IS_UP(new_active->dev)) {
-			/* link up, but waiting for stabilization */
-			if (new_active->delay < mintime) {
-				mintime = new_active->delay;
-				bestslave = new_active;
-			}
+	bond_for_each_slave(bond, slave, iter) {
+		if (slave->link == BOND_LINK_UP)
+			return slave;
+		if (slave->link == BOND_LINK_BACK && IS_UP(slave->dev) &&
+		    slave->delay < mintime) {
+			mintime = slave->delay;
+			bestslave = slave;
 		}
 	}
 
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 12/27] bonding: rework rlb_next_rx_slave() to use bond_for_each_slave()
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

Currently, we're using bond_for_each_slave_from(), which is really hard to
implement under RCU and/or neighbour list.

Remove it and use bond_for_each_slave() instead, taking care of the last
used slave.

Also, rename next_rx_slave to rx_slave and store the current (last)
rx_slave.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    New patch.

 drivers/net/bonding/bond_alb.c | 41 +++++++++++++++++++++--------------------
 drivers/net/bonding/bond_alb.h |  4 +---
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index caa437d..1172474 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -383,30 +383,31 @@ out:
 static struct slave *rlb_next_rx_slave(struct bonding *bond)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-	struct slave *rx_slave, *slave, *start_at;
-	int i = 0;
-
-	if (bond_info->next_rx_slave)
-		start_at = bond_info->next_rx_slave;
-	else
-		start_at = bond_first_slave(bond);
-
-	rx_slave = NULL;
+	struct slave *before = NULL, *rx_slave = NULL, *slave;
+	struct list_head *iter;
+	bool found = false;
 
-	bond_for_each_slave_from(bond, slave, i, start_at) {
-		if (SLAVE_IS_OK(slave)) {
-			if (!rx_slave) {
-				rx_slave = slave;
-			} else if (slave->speed > rx_slave->speed) {
+	bond_for_each_slave(bond, slave, iter) {
+		if (!SLAVE_IS_OK(slave))
+			continue;
+		if (!found) {
+			if (!before || before->speed < slave->speed)
+				before = slave;
+		} else {
+			if (!rx_slave || rx_slave->speed < slave->speed)
 				rx_slave = slave;
-			}
 		}
+		if (slave == bond_info->rx_slave)
+			found = true;
 	}
+	/* we didn't find anything after the current or we have something
+	 * better before and up to the current slave
+	 */
+	if (!rx_slave || (before && rx_slave->speed < before->speed))
+		rx_slave = before;
 
-	if (rx_slave) {
-		slave = bond_next_slave(bond, rx_slave);
-		bond_info->next_rx_slave = slave;
-	}
+	if (rx_slave)
+		bond_info->rx_slave = rx_slave;
 
 	return rx_slave;
 }
@@ -1611,7 +1612,7 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
 	tlb_clear_slave(bond, slave, 0);
 
 	if (bond->alb_info.rlb_enabled) {
-		bond->alb_info.next_rx_slave = NULL;
+		bond->alb_info.rx_slave = NULL;
 		rlb_clear_slave(bond, slave);
 	}
 }
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 28d8e4c..7736ce2 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -153,9 +153,7 @@ struct alb_bond_info {
 	u8			rx_ntt;	/* flag - need to transmit
 					 * to all rx clients
 					 */
-	struct slave		*next_rx_slave;/* next slave to be assigned
-						* to a new rx client for
-						*/
+	struct slave		*rx_slave;/* last slave to xmit from */
 	u8			primary_is_promisc;	   /* boolean */
 	u32			rlb_promisc_timeout_counter;/* counts primary
 							     * promiscuity time
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 11/27] bonding: rework bond_3ad_xmit_xor() to use bond_for_each_slave() only
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

Currently, there are two loops - first we find the first slave in an
aggregator after the xmit_hash_policy() returned number, and after that we
loop from that slave, over bonding head, and till that slave to find any
suitable slave to send the packet through.

Replace it by just one bond_for_each_slave() loop, which first loops
through the requested number of slaves, saving the first suitable one, and
after that we've hit the requested number of slaves to skip - search for
any up slave to send the packet through. If we don't find such kind of
slave - then just send the packet through the first suitable slave found.

Logic remains unchainged, and we skip two loops. Also, refactor it a bit
for readability.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    New patch.

 drivers/net/bonding/bond_3ad.c | 46 ++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 3847aee..c861ee7 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2417,15 +2417,15 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
 
 int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 {
-	struct slave *slave, *start_at;
 	struct bonding *bond = netdev_priv(dev);
+	struct slave *slave, *first_ok_slave;
+	struct aggregator *agg;
+	struct ad_info ad_info;
 	struct list_head *iter;
-	int slave_agg_no;
 	int slaves_in_agg;
-	int agg_id;
-	int i;
-	struct ad_info ad_info;
+	int slave_agg_no;
 	int res = 1;
+	int agg_id;
 
 	read_lock(&bond->lock);
 	if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
@@ -2438,20 +2438,28 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 	agg_id = ad_info.aggregator_id;
 
 	if (slaves_in_agg == 0) {
-		/*the aggregator is empty*/
 		pr_debug("%s: Error: active aggregator is empty\n", dev->name);
 		goto out;
 	}
 
 	slave_agg_no = bond->xmit_hash_policy(skb, slaves_in_agg);
+	first_ok_slave = NULL;
 
 	bond_for_each_slave(bond, slave, iter) {
-		struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
+		agg = SLAVE_AD_INFO(slave).port.aggregator;
+		if (!agg || agg->aggregator_identifier != agg_id)
+			continue;
 
-		if (agg && (agg->aggregator_identifier == agg_id)) {
+		if (slave_agg_no >= 0) {
+			if (!first_ok_slave && SLAVE_IS_OK(slave))
+				first_ok_slave = slave;
 			slave_agg_no--;
-			if (slave_agg_no < 0)
-				break;
+			continue;
+		}
+
+		if (SLAVE_IS_OK(slave)) {
+			res = bond_dev_queue_xmit(bond, skb, slave->dev);
+			goto out;
 		}
 	}
 
@@ -2461,20 +2469,10 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 		goto out;
 	}
 
-	start_at = slave;
-
-	bond_for_each_slave_from(bond, slave, i, start_at) {
-		int slave_agg_id = 0;
-		struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
-
-		if (agg)
-			slave_agg_id = agg->aggregator_identifier;
-
-		if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) {
-			res = bond_dev_queue_xmit(bond, skb, slave->dev);
-			break;
-		}
-	}
+	/* we couldn't find any suitable slave after the agg_no, so use the
+	 * first suitable found, if found. */
+	if (first_ok_slave)
+		res = bond_dev_queue_xmit(bond, skb, first_ok_slave->dev);
 
 out:
 	read_unlock(&bond->lock);
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 10/27] bonding: use bond_for_each_slave() in bond_uninit()
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

We're safe agains removal there, cause we use neighbours primitives.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    Move the patch rigth after we start using neighbour lists for
    bond_for_each_slave().

 drivers/net/bonding/bond_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index cdd5c5f..2075321 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4090,12 +4090,13 @@ static void bond_setup(struct net_device *bond_dev)
 static void bond_uninit(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
-	struct slave *slave, *tmp_slave;
+	struct list_head *iter;
+	struct slave *slave;
 
 	bond_netpoll_cleanup(bond_dev);
 
 	/* Release the bonded slaves */
-	list_for_each_entry_safe(slave, tmp_slave, &bond->slave_list, list)
+	bond_for_each_slave(bond, slave, iter)
 		__bond_release_one(bond_dev, slave->dev, true);
 	pr_info("%s: released all slaves\n", bond_dev->name);
 
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 08/27] bonding: remove bond_for_each_slave_reverse()
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

We only use it in rollback scenarios and can easily use the standart
bond_for_each_dev() instead.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    Move the patch right before we change bond_for_each_slave() conversion,
    so that we don't have to convert bond_for_each_slave_reverse() too.

 drivers/net/bonding/bond_alb.c  | 14 ++++++++------
 drivers/net/bonding/bond_main.c | 34 ++++++++++++++++++++++------------
 drivers/net/bonding/bonding.h   | 10 ----------
 3 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index c3dcc6b..46f6b40 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1246,9 +1246,9 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
  */
 static int alb_set_mac_address(struct bonding *bond, void *addr)
 {
-	char tmp_addr[ETH_ALEN];
-	struct slave *slave;
+	struct slave *slave, *rollback_slave;
 	struct sockaddr sa;
+	char tmp_addr[ETH_ALEN];
 	int res;
 
 	if (bond->alb_info.rlb_enabled)
@@ -1274,10 +1274,12 @@ unwind:
 	sa.sa_family = bond->dev->type;
 
 	/* unwind from head to the slave that failed */
-	bond_for_each_slave_continue_reverse(bond, slave) {
-		memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
-		dev_set_mac_address(slave->dev, &sa);
-		memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
+	bond_for_each_slave(bond, rollback_slave) {
+		if (rollback_slave == slave)
+			break;
+		memcpy(tmp_addr, rollback_slave->dev->dev_addr, ETH_ALEN);
+		dev_set_mac_address(rollback_slave->dev, &sa);
+		memcpy(rollback_slave->dev->dev_addr, tmp_addr, ETH_ALEN);
 	}
 
 	return res;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f862dc8..3956478 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -332,7 +332,7 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev,
 				__be16 proto, u16 vid)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
-	struct slave *slave;
+	struct slave *slave, *rollback_slave;
 	int res;
 
 	bond_for_each_slave(bond, slave) {
@@ -344,9 +344,13 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev,
 	return 0;
 
 unwind:
-	/* unwind from the slave that failed */
-	bond_for_each_slave_continue_reverse(bond, slave)
-		vlan_vid_del(slave->dev, proto, vid);
+	/* unwind to the slave that failed */
+	bond_for_each_slave(bond, rollback_slave) {
+		if (rollback_slave == slave)
+			break;
+
+		vlan_vid_del(rollback_slave->dev, proto, vid);
+	}
 
 	return res;
 }
@@ -3468,7 +3472,7 @@ static int bond_neigh_setup(struct net_device *dev,
 static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
-	struct slave *slave;
+	struct slave *slave, *rollback_slave;
 	int res = 0;
 
 	pr_debug("bond=%p, name=%s, new_mtu=%d\n", bond,
@@ -3517,13 +3521,16 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
 
 unwind:
 	/* unwind from head to the slave that failed */
-	bond_for_each_slave_continue_reverse(bond, slave) {
+	bond_for_each_slave(bond, rollback_slave) {
 		int tmp_res;
 
-		tmp_res = dev_set_mtu(slave->dev, bond_dev->mtu);
+		if (rollback_slave == slave);
+			break;
+
+		tmp_res = dev_set_mtu(rollback_slave->dev, bond_dev->mtu);
 		if (tmp_res) {
 			pr_debug("unwind err %d dev %s\n",
-				 tmp_res, slave->dev->name);
+				 tmp_res, rollback_slave->dev->name);
 		}
 	}
 
@@ -3540,8 +3547,8 @@ unwind:
 static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
+	struct slave *slave, *rollback_slave;
 	struct sockaddr *sa = addr, tmp_sa;
-	struct slave *slave;
 	int res = 0;
 
 	if (bond->params.mode == BOND_MODE_ALB)
@@ -3607,13 +3614,16 @@ unwind:
 	tmp_sa.sa_family = bond_dev->type;
 
 	/* unwind from head to the slave that failed */
-	bond_for_each_slave_continue_reverse(bond, slave) {
+	bond_for_each_slave(bond, rollback_slave) {
 		int tmp_res;
 
-		tmp_res = dev_set_mac_address(slave->dev, &tmp_sa);
+		if (rollback_slave == slave)
+			break;
+
+		tmp_res = dev_set_mac_address(rollback_slave->dev, &tmp_sa);
 		if (tmp_res) {
 			pr_debug("unwind err %d dev %s\n",
-				 tmp_res, slave->dev->name);
+				 tmp_res, rollback_slave->dev->name);
 		}
 	}
 
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 6d1a893..141ddc3 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -120,16 +120,6 @@
 #define bond_for_each_slave_rcu(bond, pos) \
 	list_for_each_entry_rcu(pos, &(bond)->slave_list, list)
 
-/**
- * bond_for_each_slave_reverse - iterate in reverse from a given position
- * @bond:	the bond holding this list
- * @pos:	slave to continue from
- *
- * Caller must hold bond->lock
- */
-#define bond_for_each_slave_continue_reverse(bond, pos) \
-	list_for_each_entry_continue_reverse(pos, &(bond)->slave_list, list)
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 extern atomic_t netpoll_block_tx;
 
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 07/27] net: add for_each iterators through neighbour lower link's private
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev
  Cc: jiri, Veaceslav Falico, David S. Miller, Eric Dumazet,
	Alexander Duyck
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

Add a possibility to iterate through netdev_adjacent's private, currently
only for lower neighbours.

Add both RCU and RTNL/other locking variants of iterators.

CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    rename neighbour_dev_list/all_dev_list to adj_list/all_adj_list and rework
    the naming of functions - to make the use the pattern
    netdev_(all_)(lower|upper)_* . Also reword the commit message - I had to
    read it three times to understand :-/, and move it closer to the beginning
    of the patchset.

 include/linux/netdevice.h | 17 ++++++++++++
 net/core/dev.c            | 66 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index eab8e36..48431f0 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2833,6 +2833,23 @@ extern struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *d
 	     updev; \
 	     updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)))
 
+extern void *netdev_lower_get_next_private(struct net_device *dev,
+					   struct list_head **iter);
+extern void *netdev_lower_get_next_private_rcu(struct net_device *dev,
+					       struct list_head **iter);
+
+#define netdev_for_each_lower_private(dev, priv, iter) \
+	for (iter = &(dev)->adj_list.lower, \
+	     priv = netdev_lower_get_next_private(dev, &(iter)); \
+	     priv; \
+	     priv = netdev_lower_get_next_private(dev, &(iter)))
+
+#define netdev_for_each_lower_private_rcu(dev, priv, iter) \
+	for (iter = &(dev)->adj_list.lower, \
+	     priv = netdev_lower_get_next_private_rcu(dev, &(iter)); \
+	     priv; \
+	     priv = netdev_lower_get_next_private_rcu(dev, &(iter)))
+
 extern struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
 extern struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev);
 extern int netdev_upper_dev_link(struct net_device *dev,
diff --git a/net/core/dev.c b/net/core/dev.c
index 6b2b12f..11284c8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4537,6 +4537,72 @@ struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
 }
 EXPORT_SYMBOL(netdev_all_upper_get_next_dev_rcu);
 
+/* netdev_lower_get_next_private - Get the next ->private from the
+ *				   lower neighbour list
+ * @dev: device
+ * @iter: list_head ** of the current position
+ *
+ * Gets the next netdev_adjacent->private from the dev's lower neighbour
+ * list, starting from iter position. The caller must hold either hold the
+ * RTNL lock or its own locking that guarantees that the neighbour lower
+ * list will remain unchainged. If iter is NULL - return the first private.
+ */
+void *netdev_lower_get_next_private(struct net_device *dev,
+				    struct list_head **iter)
+{
+	struct netdev_adjacent *lower;
+
+	if (iter)
+		lower = list_entry((*iter)->next, struct netdev_adjacent,
+				   list);
+	else
+		lower = list_entry(dev->adj_list.lower.next,
+				   struct netdev_adjacent, list);
+
+	if (&lower->list == &dev->adj_list.lower)
+		return NULL;
+
+	if (iter)
+		*iter = &lower->list;
+
+	return lower->private;
+}
+EXPORT_SYMBOL(netdev_lower_get_next_private);
+
+/* netdev_lower_get_next_private_rcu - Get the next ->private from the
+ *				       lower neighbour list, RCU
+ *				       variant
+ * @dev: device
+ * @iter: list_head ** of the current position
+ *
+ * Gets the next netdev_adjacent->private from the dev's lower neighbour
+ * list, starting from iter position. The caller must hold RCU read lock.
+ * If iter is NULL - returns the first private.
+ */
+void *netdev_lower_get_next_private_rcu(struct net_device *dev,
+					struct list_head **iter)
+{
+	struct netdev_adjacent *lower;
+
+	WARN_ON_ONCE(!rcu_read_lock_held());
+
+	if (iter)
+		lower = list_entry_rcu((*iter)->next, struct netdev_adjacent,
+				       list);
+	else
+		lower = list_entry_rcu(dev->adj_list.lower.next,
+				       struct netdev_adjacent, list);
+
+	if (&lower->list == &dev->adj_list.lower)
+		return NULL;
+
+	if (iter)
+		*iter = &lower->list;
+
+	return lower->private;
+}
+EXPORT_SYMBOL(netdev_lower_get_next_private_rcu);
+
 /**
  * netdev_master_upper_dev_get_rcu - Get master upper device
  * @dev: device
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 06/27] bonding: modify bond_get_slave_by_dev() to use neighbours
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

It should be used under rtnl/bonding lock, so use the non-RCU version.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    Move the patch right after we've populated ->private with bonding.

 drivers/net/bonding/bonding.h | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index f7ab161..6d1a893 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -275,13 +275,8 @@ struct bonding {
 static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,
 						  struct net_device *slave_dev)
 {
-	struct slave *slave = NULL;
-
-	bond_for_each_slave(bond, slave)
-		if (slave->dev == slave_dev)
-			return slave;
-
-	return NULL;
+	return (struct slave *)netdev_lower_dev_get_private(bond->dev,
+							    slave_dev);
 }
 
 static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 00/27] bonding: use neighbours instead of own lists
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev
  Cc: jiri, Jay Vosburgh, Andy Gospodarek, Dimitris Michailidis,
	David S. Miller, Patrick McHardy, Eric Dumazet, Alexander Duyck,
	Veaceslav Falico

(David, feel free to drop the whole patchset - I know that the window is
closed and I'm quite sure that it's not the last version, and even if it is
- I'll easily re-submit it. Sorry for the mess, again :) )

Hi,

v1  -> v2:
Fix a bug when we could remove try to remove a neighbour twice - it was
possible if we've had this neighbour already and added another devices
which had this neighbour in its lists. Fix it by following the rule - there
can be only one neighbour link, so add also _remove_neighbour() functions
to the generic _remove()s to handle the neighbour only removing, and fix
its refcounting while adding (all in patch 01).
Also, fix a vlan bug when it called unregister netdevice before unlinking -
it could possibly lead to a subte race condition - cause it was
unregistered but still in global-accessible list.
Rearrange sysfs/vlan patches so that first we fix vlan and only after we
add sysfs stuff.

RFC -> v1:
I've added proper, consistent naming for all variables/functions, uninlined
some helpers to get better backtraces, just in case (overhead is minimal,
no hot paths), rearranged patches for better review, dropped bondings
->prev and bond_for_each_slave_continue() functionality - to be able to
RCUify it easier, and renamed slave_* sysfs links to lower_* sysfs links to
maintain upper/lower naming. I've also dropped, thanks to bonding cleanup,
some heavy and ugly/intrusive patches.

I'm sending it as early as possible, because it's quite a big patchset and
some of the approaches I've chosen are not really easy/straightforward.
It's, however, quite heavily tested already and works fine.

I'm sending it to gather any feedback possible.

This patchset introduces all the needed infrastructure, on top of current
adjacent lists, to be able to remove bond's slave_list/slave->list. The
overhead in memory/CPU is minimal, and after the patchset bonding can rely
on its slave-related functions, given the proper locking. I've done some
netperf benchmarks on a vm, and the delta was about 0.1gbps for 35gbps as a
whole, so no speed fluctuations.

It also automatically creates lower/upper and master symlinks in dev's
sysfs directory.

The current version works ok, as first tests have shown. I'm testing it
further, if anything comes up - I'll update.

The per-patch description has moved from here to per-patch notes.

Thanks in advance.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: Dimitris Michailidis <dm@chelsio.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Patrick McHardy <kaber@trash.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>

---
 drivers/net/bonding/bond_3ad.c                  |  54 +--
 drivers/net/bonding/bond_alb.c                  |  81 ++--
 drivers/net/bonding/bond_alb.h                  |   4 +-
 drivers/net/bonding/bond_main.c                 | 296 ++++++++-------
 drivers/net/bonding/bond_procfs.c               |   5 +-
 drivers/net/bonding/bond_sysfs.c                |  62 +--
 drivers/net/bonding/bonding.h                   |  74 ++--
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   3 +-
 include/linux/netdevice.h                       |  57 ++-
 net/8021q/vlan.c                                |  18 +-
 net/core/dev.c                                  | 482 +++++++++++++++++++-----
 11 files changed, 724 insertions(+), 412 deletions(-)

^ permalink raw reply

* [PATCH v2 net-next 05/27] bonding: populate neighbour's private on enslave
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

Use the new provided function when attaching the lower slave to populate
its ->private with struct slave *new_slave. Also, move it to the end to
be able to 'find' it only after it was completely initialized, and
deinitialize in the first place on release.

CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    Move the patch right after the introduction of ->private, to immediately
    use it - easier for review and more logical.

 drivers/net/bonding/bond_main.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 72bdb8b..f862dc8 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1233,11 +1233,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
 }
 
 static int bond_master_upper_dev_link(struct net_device *bond_dev,
-				      struct net_device *slave_dev)
+				      struct net_device *slave_dev,
+				      struct slave *slave)
 {
 	int err;
 
-	err = netdev_master_upper_dev_link(slave_dev, bond_dev);
+	err = netdev_master_upper_dev_link_private(slave_dev, bond_dev, slave);
 	if (err)
 		return err;
 	slave_dev->flags |= IFF_SLAVE;
@@ -1413,17 +1414,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 		}
 	}
 
-	res = bond_master_upper_dev_link(bond_dev, slave_dev);
-	if (res) {
-		pr_debug("Error %d calling bond_master_upper_dev_link\n", res);
-		goto err_restore_mac;
-	}
-
 	/* open the slave since the application closed it */
 	res = dev_open(slave_dev);
 	if (res) {
 		pr_debug("Opening slave %s failed\n", slave_dev->name);
-		goto err_unset_master;
+		goto err_restore_mac;
 	}
 
 	new_slave->bond = bond;
@@ -1637,6 +1632,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 		goto err_dest_symlinks;
 	}
 
+	res = bond_master_upper_dev_link(bond_dev, slave_dev, new_slave);
+	if (res) {
+		pr_debug("Error %d calling bond_master_upper_dev_link\n", res);
+		goto err_unregister;
+	}
+
+
 	pr_info("%s: enslaving %s as a%s interface with a%s link.\n",
 		bond_dev->name, slave_dev->name,
 		bond_is_active_slave(new_slave) ? "n active" : " backup",
@@ -1646,6 +1648,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	return 0;
 
 /* Undo stages on error */
+err_unregister:
+	netdev_rx_handler_unregister(slave_dev);
+
 err_dest_symlinks:
 	bond_destroy_slave_symlinks(bond_dev, slave_dev);
 
@@ -1675,9 +1680,6 @@ err_close:
 	slave_dev->priv_flags &= ~IFF_BONDING;
 	dev_close(slave_dev);
 
-err_unset_master:
-	bond_upper_dev_unlink(bond_dev, slave_dev);
-
 err_restore_mac:
 	if (!bond->params.fail_over_mac) {
 		/* XXX TODO - fom follow mode needs to change master's
@@ -1748,6 +1750,8 @@ static int __bond_release_one(struct net_device *bond_dev,
 	}
 
 	write_unlock_bh(&bond->lock);
+
+	bond_upper_dev_unlink(bond_dev, slave_dev);
 	/* unregister rx_handler early so bond_handle_frame wouldn't be called
 	 * for this slave anymore.
 	 */
@@ -1866,8 +1870,6 @@ static int __bond_release_one(struct net_device *bond_dev,
 		bond_hw_addr_flush(bond_dev, slave_dev);
 	}
 
-	bond_upper_dev_unlink(bond_dev, slave_dev);
-
 	slave_disable_netpoll(slave);
 
 	/* close slave before restoring its mac address */
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 03/27] net: uninline netdev neighbour functions
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev
  Cc: jiri, Veaceslav Falico, David S. Miller, Eric Dumazet,
	Alexander Duyck
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

They don't give almost any speed/size advantage, however it's really
useful to have them in the backtrace.

CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    New patch.

 net/core/dev.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 75eabef..d277081 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4684,25 +4684,25 @@ void __netdev_adjacent_dev_remove(struct net_device *dev,
 	kfree_rcu(adj, rcu);
 }
 
-static inline void __netdev_upper_dev_remove(struct net_device *dev,
-					     struct net_device *udev)
+static void __netdev_upper_dev_remove(struct net_device *dev,
+				      struct net_device *udev)
 {
 	return __netdev_adjacent_dev_remove(dev, udev, true, false);
 }
 
-static inline void __netdev_upper_dev_remove_neighbour(struct net_device *dev,
+static void __netdev_upper_dev_remove_neighbour(struct net_device *dev,
 						struct net_device *udev)
 {
 	return __netdev_adjacent_dev_remove(dev, udev, true, true);
 }
 
-static inline void __netdev_lower_dev_remove(struct net_device *dev,
-					     struct net_device *ldev)
+static void __netdev_lower_dev_remove(struct net_device *dev,
+				      struct net_device *ldev)
 {
 	return __netdev_adjacent_dev_remove(dev, ldev, false, false);
 }
 
-static inline void __netdev_lower_dev_remove_neighbour(struct net_device *dev,
+static void __netdev_lower_dev_remove_neighbour(struct net_device *dev,
 						struct net_device *ldev)
 {
 	return __netdev_adjacent_dev_remove(dev, ldev, false, true);
@@ -4727,15 +4727,15 @@ int __netdev_adjacent_dev_insert_link(struct net_device *dev,
 	return 0;
 }
 
-static inline int __netdev_adjacent_dev_link(struct net_device *dev,
-					     struct net_device *udev)
+static int __netdev_adjacent_dev_link(struct net_device *dev,
+				      struct net_device *udev)
 {
 	return __netdev_adjacent_dev_insert_link(dev, udev, false, false);
 }
 
-static inline int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
-						       struct net_device *udev,
-						       bool master)
+static int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
+						struct net_device *udev,
+						bool master)
 {
 	return __netdev_adjacent_dev_insert_link(dev, udev, master, true);
 }
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 04/27] net: add netdev_adjacent->private and allow to use it
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev
  Cc: jiri, Veaceslav Falico, David S. Miller, Eric Dumazet,
	Alexander Duyck
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

Currently, even though we can access any linked device, we can't attach
anything to it, which is vital to properly manage them.

To fix this, add a new void *private to netdev_adjacent and functions
setting/getting it (per link), so that we can save, per example, bonding's
slave structures there, per slave device.

netdev_master_upper_dev_link_private(dev, upper_dev, private) links dev to
upper dev and populates the neighbour link only with private.

netdev_lower_dev_get_private{,_rcu}() returns the private, if found.

CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    rename neighbour_dev_list/all_dev_list to adj_list/all_adj_list and rework
    the naming of functions - to make the use the pattern
    netdev_(all_)(lower|upper)_* .

 include/linux/netdevice.h |  7 ++++
 net/core/dev.c            | 83 ++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 2a944e5..eab8e36 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2839,8 +2839,15 @@ extern int netdev_upper_dev_link(struct net_device *dev,
 				 struct net_device *upper_dev);
 extern int netdev_master_upper_dev_link(struct net_device *dev,
 					struct net_device *upper_dev);
+extern int netdev_master_upper_dev_link_private(struct net_device *dev,
+						struct net_device *upper_dev,
+						void *private);
 extern void netdev_upper_dev_unlink(struct net_device *dev,
 				    struct net_device *upper_dev);
+extern void *netdev_lower_dev_get_private_rcu(struct net_device *dev,
+					      struct net_device *lower_dev);
+extern void *netdev_lower_dev_get_private(struct net_device *dev,
+					  struct net_device *lower_dev);
 extern int skb_checksum_help(struct sk_buff *skb);
 extern struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
 	netdev_features_t features, bool tx_path);
diff --git a/net/core/dev.c b/net/core/dev.c
index d277081..6b2b12f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4376,6 +4376,9 @@ struct netdev_adjacent {
 	/* counter for the number of times this device was added to us */
 	u16 ref_nr;
 
+	/* private field for the users */
+	void *private;
+
 	struct list_head list;
 	struct rcu_head rcu;
 };
@@ -4556,7 +4559,7 @@ EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);
 static int __netdev_adjacent_dev_insert(struct net_device *dev,
 					struct net_device *adj_dev,
 					bool neighbour, bool master,
-					bool upper)
+					bool upper, void *private)
 {
 	struct netdev_adjacent *adj, *neigh = NULL;
 
@@ -4599,9 +4602,15 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
 			 adj_dev->name);
 
 	if (!upper) {
-		if (neigh)
+		if (neigh) {
+			/* we're backlinging the master device to its
+			 * slave, so save the private in this link.
+			 */
+			if (master)
+				neigh->private = private;
 			list_add_tail_rcu(&neigh->list,
 					  &dev->adj_list.lower);
+		}
 		list_add_tail_rcu(&adj->list, &dev->all_adj_list.lower);
 		return 0;
 	}
@@ -4627,15 +4636,16 @@ static int __netdev_upper_dev_insert(struct net_device *dev,
 				     bool master, bool neighbour)
 {
 	return __netdev_adjacent_dev_insert(dev, udev, neighbour, master,
-					    true);
+					    true, NULL);
 }
 
 static int __netdev_lower_dev_insert(struct net_device *dev,
 				     struct net_device *ldev,
-				     bool neighbour)
+				     bool master, bool neighbour,
+				     void *private)
 {
-	return __netdev_adjacent_dev_insert(dev, ldev, neighbour, false,
-					    false);
+	return __netdev_adjacent_dev_insert(dev, ldev, neighbour, master,
+					    false, private);
 }
 
 void __netdev_adjacent_dev_remove(struct net_device *dev,
@@ -4710,7 +4720,8 @@ static void __netdev_lower_dev_remove_neighbour(struct net_device *dev,
 
 int __netdev_adjacent_dev_insert_link(struct net_device *dev,
 				      struct net_device *upper_dev,
-				      bool master, bool neighbour)
+				      bool master, bool neighbour,
+				      void *private)
 {
 	int ret;
 
@@ -4718,7 +4729,8 @@ int __netdev_adjacent_dev_insert_link(struct net_device *dev,
 	if (ret)
 		return ret;
 
-	ret = __netdev_lower_dev_insert(upper_dev, dev, neighbour);
+	ret = __netdev_lower_dev_insert(upper_dev, dev, master, neighbour,
+					private);
 	if (ret) {
 		__netdev_upper_dev_remove(dev, upper_dev);
 		return ret;
@@ -4730,14 +4742,15 @@ int __netdev_adjacent_dev_insert_link(struct net_device *dev,
 static int __netdev_adjacent_dev_link(struct net_device *dev,
 				      struct net_device *udev)
 {
-	return __netdev_adjacent_dev_insert_link(dev, udev, false, false);
+	return __netdev_adjacent_dev_insert_link(dev, udev, false, false, NULL);
 }
 
 static int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
 						struct net_device *udev,
-						bool master)
+						bool master, void *priv)
 {
-	return __netdev_adjacent_dev_insert_link(dev, udev, master, true);
+	return __netdev_adjacent_dev_insert_link(dev, udev, master, true,
+						 priv);
 }
 
 void __netdev_adjacent_dev_unlink(struct net_device *dev,
@@ -4756,7 +4769,8 @@ void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
 
 
 static int __netdev_upper_dev_link(struct net_device *dev,
-				   struct net_device *upper_dev, bool master)
+				   struct net_device *upper_dev, bool master,
+				   void *private)
 {
 	struct netdev_adjacent *i, *j, *to_i, *to_j;
 	int ret = 0;
@@ -4776,7 +4790,8 @@ static int __netdev_upper_dev_link(struct net_device *dev,
 	if (master && netdev_master_upper_dev_get(dev))
 		return -EBUSY;
 
-	ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, master);
+	ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, master,
+						   private);
 	if (ret)
 		return ret;
 
@@ -4867,7 +4882,7 @@ rollback_mesh:
 int netdev_upper_dev_link(struct net_device *dev,
 			  struct net_device *upper_dev)
 {
-	return __netdev_upper_dev_link(dev, upper_dev, false);
+	return __netdev_upper_dev_link(dev, upper_dev, false, NULL);
 }
 EXPORT_SYMBOL(netdev_upper_dev_link);
 
@@ -4885,10 +4900,18 @@ EXPORT_SYMBOL(netdev_upper_dev_link);
 int netdev_master_upper_dev_link(struct net_device *dev,
 				 struct net_device *upper_dev)
 {
-	return __netdev_upper_dev_link(dev, upper_dev, true);
+	return __netdev_upper_dev_link(dev, upper_dev, true, NULL);
 }
 EXPORT_SYMBOL(netdev_master_upper_dev_link);
 
+int netdev_master_upper_dev_link_private(struct net_device *dev,
+					 struct net_device *upper_dev,
+					 void *private)
+{
+	return __netdev_upper_dev_link(dev, upper_dev, true, private);
+}
+EXPORT_SYMBOL(netdev_master_upper_dev_link_private);
+
 /**
  * netdev_upper_dev_unlink - Removes a link to upper device
  * @dev: device
@@ -4926,6 +4949,36 @@ void netdev_upper_dev_unlink(struct net_device *dev,
 }
 EXPORT_SYMBOL(netdev_upper_dev_unlink);
 
+void *netdev_lower_dev_get_private_rcu(struct net_device *dev,
+				       struct net_device *lower_dev)
+{
+	struct netdev_adjacent *lower;
+
+	if (!lower_dev)
+		return NULL;
+	lower = __netdev_lower_find_rcu(dev, lower_dev);
+	if (!lower)
+		return NULL;
+
+	return lower->private;
+}
+EXPORT_SYMBOL(netdev_lower_dev_get_private_rcu);
+
+void *netdev_lower_dev_get_private(struct net_device *dev,
+				   struct net_device *lower_dev)
+{
+	struct netdev_adjacent *lower;
+
+	if (!lower_dev)
+		return NULL;
+	lower = __netdev_lower_find(dev, lower_dev);
+	if (!lower)
+		return NULL;
+
+	return lower->private;
+}
+EXPORT_SYMBOL(netdev_lower_dev_get_private);
+
 static void dev_change_rx_flags(struct net_device *dev, int flags)
 {
 	const struct net_device_ops *ops = dev->netdev_ops;
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 02/27] net: add RCU variant to search for netdev_adjacent link
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev
  Cc: jiri, Veaceslav Falico, David S. Miller, Eric Dumazet,
	Alexander Duyck, Cong Wang
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

Currently we have only the RTNL flavour, however we can traverse it while
holding only RCU, so add the RCU search. Add only one function that will be
used further, other functions can be added easily afterwards, if anyone
would need them.

CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
CC: Cong Wang <amwang@redhat.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    No changes.
    
    RFC -> v1:
    rename neighbour_dev_list/all_dev_list to adj_list/all_adj_list and rework
    the naming of functions - to make the use the pattern
    netdev_(all_)(lower|upper)_* . Uninline functions to get better stack
    traces - inline doesn't give much speed improvement, but this way the stack
    traces are meaningful. Remove the unused (through the whole patchset)
    functions - they can easily be added afterwards.

 net/core/dev.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index f69a8ab..75eabef 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4380,6 +4380,33 @@ struct netdev_adjacent {
 	struct rcu_head rcu;
 };
 
+static struct netdev_adjacent *__netdev_find_adj_rcu(struct net_device *dev,
+						     struct net_device *adj_dev,
+						     bool upper, bool neighbour)
+{
+	struct netdev_adjacent *adj;
+	struct list_head *adj_list;
+
+	if (neighbour)
+		adj_list = upper ? &dev->adj_list.upper :
+				   &dev->adj_list.lower;
+	else
+		adj_list = upper ? &dev->all_adj_list.upper :
+				   &dev->all_adj_list.lower;
+
+	list_for_each_entry_rcu(adj, adj_list, list) {
+		if (adj->dev == adj_dev)
+			return adj;
+	}
+	return NULL;
+}
+
+static struct netdev_adjacent *__netdev_lower_find_rcu(struct net_device *dev,
+							struct net_device *ldev)
+{
+	return __netdev_find_adj_rcu(dev, ldev, false, true);
+}
+
 static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev,
 						 struct net_device *adj_dev,
 						 bool upper, bool neighbour)
-- 
1.8.4

^ permalink raw reply related

* [PATCH v2 net-next 01/27] net: add adj_list to save only neighbours
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
  To: netdev
  Cc: jiri, Veaceslav Falico, David S. Miller, Eric Dumazet,
	Alexander Duyck, Cong Wang
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>

Currently, we distinguish neighbours (first-level linked devices) from
non-neighbours by the neighbour bool in the netdev_adjacent. This could be
quite time-consuming in case we would like to traverse *only* through
neighbours - cause we'd have to traverse through all devices and check for
this flag, and in a (quite common) scenario where we have lots of vlans on
top of bridge, which is on top of a bond - the bonding would have to go
through all those vlans to get its upper neighbour linked devices.

This situation is really unpleasant, cause there are already a lot of cases
when a device with slaves needs to go through them in hot path.

To fix this, introduce a new upper/lower device lists structure -
adj_list, which contains only the neighbours. It works always in
pair with the all_adj_list structure (renamed from upper/lower_dev_list),
i.e. both of them contain the same links, only that all_adj_list contains
also non-neighbour device links. It's really a small change visible,
currently, only for __netdev_adjacent_dev_insert/remove(), and doesn't
change the main linked logic at all.

Also, add some comments a fix a name collision in
netdev_for_each_upper_dev_rcu() and rework the naming by the following
rules:

netdev_(all_)(upper|lower)_*

If "all_" is present, then we work with the whole list of upper/lower
devices, otherwise - only with direct neighbours. Uninline functions - to
get better stack traces.

CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
CC: Cong Wang <amwang@redhat.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---

Notes:
    v1  -> v2:
    Fix a bug when we've tried to add a non-neighbour dev1 to dev2, while dev2
    already had dev1 as a neighbour - we shouldn't care about neighbour's
    ref_nr at all cause we can only add one - so just add/remove it via
    different functions. And it became more readable.
    
    RFC -> v1:
    rename neighbour_dev_list/all_dev_list to adj_list/all_adj_list and rework
    the naming of functions - to make the use the pattern
    netdev_(all_)(lower|upper)_* . Uninline functions to get better stack
    traces - inline doesn't give much speed improvement, but this way the stack
    traces are meaningful.

 drivers/net/bonding/bond_alb.c  |   2 +-
 drivers/net/bonding/bond_main.c |  10 +-
 include/linux/netdevice.h       |  28 +++--
 net/core/dev.c                  | 219 ++++++++++++++++++++++++++++------------
 4 files changed, 179 insertions(+), 80 deletions(-)

diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 91f179d..c3dcc6b 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1019,7 +1019,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
 
 	/* loop through vlans and send one packet for each */
 	rcu_read_lock();
-	netdev_for_each_upper_dev_rcu(bond->dev, upper, iter) {
+	netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
 		if (upper->priv_flags & IFF_802_1Q_VLAN)
 			alb_send_lp_vid(slave, mac_addr,
 					vlan_dev_vlan_id(upper));
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 39e5b1c..72bdb8b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2267,7 +2267,7 @@ static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
 		return true;
 
 	rcu_read_lock();
-	netdev_for_each_upper_dev_rcu(bond->dev, upper, iter) {
+	netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
 		if (ip == bond_confirm_addr(upper, 0, ip)) {
 			ret = true;
 			break;
@@ -2342,10 +2342,12 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 		 *
 		 * TODO: QinQ?
 		 */
-		netdev_for_each_upper_dev_rcu(bond->dev, vlan_upper, vlan_iter) {
+		netdev_for_each_all_upper_dev_rcu(bond->dev, vlan_upper,
+						  vlan_iter) {
 			if (!is_vlan_dev(vlan_upper))
 				continue;
-			netdev_for_each_upper_dev_rcu(vlan_upper, upper, iter) {
+			netdev_for_each_all_upper_dev_rcu(vlan_upper, upper,
+							  iter) {
 				if (upper == rt->dst.dev) {
 					vlan_id = vlan_dev_vlan_id(vlan_upper);
 					rcu_read_unlock();
@@ -2358,7 +2360,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 		 * our upper vlans, then just search for any dev that
 		 * matches, and in case it's a vlan - save the id
 		 */
-		netdev_for_each_upper_dev_rcu(bond->dev, upper, iter) {
+		netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
 			if (upper == rt->dst.dev) {
 				/* if it's a vlan - get its VID */
 				if (is_vlan_dev(upper))
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 041b42a..2a944e5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1143,8 +1143,18 @@ struct net_device {
 	struct list_head	dev_list;
 	struct list_head	napi_list;
 	struct list_head	unreg_list;
-	struct list_head	upper_dev_list; /* List of upper devices */
-	struct list_head	lower_dev_list;
+
+	/* directly linked devices, like slaves for bonding */
+	struct {
+		struct list_head upper;
+		struct list_head lower;
+	} adj_list;
+
+	/* all linked devices, *including* neighbours */
+	struct {
+		struct list_head upper;
+		struct list_head lower;
+	} all_adj_list;
 
 
 	/* currently active device features */
@@ -2813,15 +2823,15 @@ extern int		bpf_jit_enable;
 extern bool netdev_has_upper_dev(struct net_device *dev,
 				 struct net_device *upper_dev);
 extern bool netdev_has_any_upper_dev(struct net_device *dev);
-extern struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
-							struct list_head **iter);
+extern struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
+							    struct list_head **iter);
 
 /* iterate through upper list, must be called under RCU read lock */
-#define netdev_for_each_upper_dev_rcu(dev, upper, iter) \
-	for (iter = &(dev)->upper_dev_list, \
-	     upper = netdev_upper_get_next_dev_rcu(dev, &(iter)); \
-	     upper; \
-	     upper = netdev_upper_get_next_dev_rcu(dev, &(iter)))
+#define netdev_for_each_all_upper_dev_rcu(dev, updev, iter) \
+	for (iter = &(dev)->all_adj_list.upper, \
+	     updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)); \
+	     updev; \
+	     updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)))
 
 extern struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
 extern struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev);
diff --git a/net/core/dev.c b/net/core/dev.c
index 5c713f2..f69a8ab 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4373,9 +4373,6 @@ struct netdev_adjacent {
 	/* upper master flag, there can only be one master device per list */
 	bool master;
 
-	/* indicates that this dev is our first-level lower/upper device */
-	bool neighbour;
-
 	/* counter for the number of times this device was added to us */
 	u16 ref_nr;
 
@@ -4385,30 +4382,47 @@ struct netdev_adjacent {
 
 static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev,
 						 struct net_device *adj_dev,
-						 bool upper)
+						 bool upper, bool neighbour)
 {
 	struct netdev_adjacent *adj;
-	struct list_head *dev_list;
+	struct list_head *adj_list;
 
-	dev_list = upper ? &dev->upper_dev_list : &dev->lower_dev_list;
+	if (neighbour)
+		adj_list = upper ? &dev->adj_list.upper :
+				   &dev->adj_list.lower;
+	else
+		adj_list = upper ? &dev->all_adj_list.upper :
+				   &dev->all_adj_list.lower;
 
-	list_for_each_entry(adj, dev_list, list) {
+	list_for_each_entry(adj, adj_list, list) {
 		if (adj->dev == adj_dev)
 			return adj;
 	}
 	return NULL;
 }
 
-static inline struct netdev_adjacent *__netdev_find_upper(struct net_device *dev,
-							  struct net_device *udev)
+static struct netdev_adjacent *__netdev_all_upper_find(struct net_device *dev,
+						       struct net_device *udev)
+{
+	return __netdev_find_adj(dev, udev, true, false);
+}
+
+static struct netdev_adjacent *__netdev_all_lower_find(struct net_device *dev,
+						       struct net_device *ldev)
 {
-	return __netdev_find_adj(dev, udev, true);
+	return __netdev_find_adj(dev, ldev, false, false);
 }
 
-static inline struct netdev_adjacent *__netdev_find_lower(struct net_device *dev,
-							  struct net_device *ldev)
+static struct netdev_adjacent *__netdev_upper_find(struct net_device *dev,
+						   struct net_device *udev)
 {
-	return __netdev_find_adj(dev, ldev, false);
+	return __netdev_find_adj(dev, udev, true, true);
+}
+
+static struct netdev_adjacent *__netdev_lower_find(struct net_device *dev,
+						   struct net_device *ldev)
+{
+	return __netdev_find_adj(dev, ldev, false, true);
 }
 
 /**
@@ -4425,7 +4439,7 @@ bool netdev_has_upper_dev(struct net_device *dev,
 {
 	ASSERT_RTNL();
 
-	return __netdev_find_upper(dev, upper_dev);
+	return __netdev_all_upper_find(dev, upper_dev);
 }
 EXPORT_SYMBOL(netdev_has_upper_dev);
 
@@ -4440,7 +4454,7 @@ bool netdev_has_any_upper_dev(struct net_device *dev)
 {
 	ASSERT_RTNL();
 
-	return !list_empty(&dev->upper_dev_list);
+	return !list_empty(&dev->all_adj_list.upper);
 }
 EXPORT_SYMBOL(netdev_has_any_upper_dev);
 
@@ -4457,10 +4471,10 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
 
 	ASSERT_RTNL();
 
-	if (list_empty(&dev->upper_dev_list))
+	if (list_empty(&dev->adj_list.upper))
 		return NULL;
 
-	upper = list_first_entry(&dev->upper_dev_list,
+	upper = list_first_entry(&dev->adj_list.upper,
 				 struct netdev_adjacent, list);
 	if (likely(upper->master))
 		return upper->dev;
@@ -4468,15 +4482,15 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
 }
 EXPORT_SYMBOL(netdev_master_upper_dev_get);
 
-/* netdev_upper_get_next_dev_rcu - Get the next dev from upper list
+/* netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list
  * @dev: device
  * @iter: list_head ** of the current position
  *
  * Gets the next device from the dev's upper list, starting from iter
  * position. The caller must hold RCU read lock.
  */
-struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
-						 struct list_head **iter)
+struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
+						     struct list_head **iter)
 {
 	struct netdev_adjacent *upper;
 
@@ -4484,14 +4498,14 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
 
 	upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);
 
-	if (&upper->list == &dev->upper_dev_list)
+	if (&upper->list == &dev->all_adj_list.upper)
 		return NULL;
 
 	*iter = &upper->list;
 
 	return upper->dev;
 }
-EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu);
+EXPORT_SYMBOL(netdev_all_upper_get_next_dev_rcu);
 
 /**
  * netdev_master_upper_dev_get_rcu - Get master upper device
@@ -4504,7 +4518,7 @@ struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev)
 {
 	struct netdev_adjacent *upper;
 
-	upper = list_first_or_null_rcu(&dev->upper_dev_list,
+	upper = list_first_or_null_rcu(&dev->adj_list.upper,
 				       struct netdev_adjacent, list);
 	if (upper && likely(upper->master))
 		return upper->dev;
@@ -4517,11 +4531,12 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
 					bool neighbour, bool master,
 					bool upper)
 {
-	struct netdev_adjacent *adj;
+	struct netdev_adjacent *adj, *neigh = NULL;
 
-	adj = __netdev_find_adj(dev, adj_dev, upper);
+	adj = __netdev_find_adj(dev, adj_dev, upper, false);
 
 	if (adj) {
+		/* we cannot insert a neighbour device twice */
 		BUG_ON(neighbour);
 		adj->ref_nr++;
 		return 0;
@@ -4533,58 +4548,103 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
 
 	adj->dev = adj_dev;
 	adj->master = master;
-	adj->neighbour = neighbour;
 	adj->ref_nr = 1;
-
 	dev_hold(adj_dev);
+
+	if (neighbour) {
+		neigh = kmalloc(sizeof(*neigh), GFP_KERNEL);
+		if (!neigh) {
+			kfree(adj);
+			return -ENOMEM;
+		}
+		neigh->dev = adj_dev;
+		neigh->master = master;
+		neigh->ref_nr = 1;
+		dev_hold(adj_dev);
+	}
+
 	pr_debug("dev_hold for %s, because of %s link added from %s to %s\n",
 		 adj_dev->name, upper ? "upper" : "lower", dev->name,
 		 adj_dev->name);
+	if (neigh)
+		pr_debug("dev_hold for %s, because of %s link added from %s to %s (neighbour)\n",
+			 adj_dev->name, upper ? "upper" : "lower", dev->name,
+			 adj_dev->name);
 
 	if (!upper) {
-		list_add_tail_rcu(&adj->list, &dev->lower_dev_list);
+		if (neigh)
+			list_add_tail_rcu(&neigh->list,
+					  &dev->adj_list.lower);
+		list_add_tail_rcu(&adj->list, &dev->all_adj_list.lower);
 		return 0;
 	}
 
 	/* Ensure that master upper link is always the first item in list. */
-	if (master)
-		list_add_rcu(&adj->list, &dev->upper_dev_list);
-	else
-		list_add_tail_rcu(&adj->list, &dev->upper_dev_list);
+	if (master) {
+		if (neigh)
+			list_add_rcu(&neigh->list,
+				     &dev->adj_list.upper);
+		list_add_rcu(&adj->list, &dev->all_adj_list.upper);
+	} else {
+		if (neigh)
+			list_add_tail_rcu(&neigh->list,
+					  &dev->adj_list.upper);
+		list_add_tail_rcu(&adj->list, &dev->all_adj_list.upper);
+	}
 
 	return 0;
 }
 
-static inline int __netdev_upper_dev_insert(struct net_device *dev,
-					    struct net_device *udev,
-					    bool master, bool neighbour)
+static int __netdev_upper_dev_insert(struct net_device *dev,
+				     struct net_device *udev,
+				     bool master, bool neighbour)
 {
 	return __netdev_adjacent_dev_insert(dev, udev, neighbour, master,
 					    true);
 }
 
-static inline int __netdev_lower_dev_insert(struct net_device *dev,
-					    struct net_device *ldev,
-					    bool neighbour)
+static int __netdev_lower_dev_insert(struct net_device *dev,
+				     struct net_device *ldev,
+				     bool neighbour)
 {
 	return __netdev_adjacent_dev_insert(dev, ldev, neighbour, false,
 					    false);
 }
 
 void __netdev_adjacent_dev_remove(struct net_device *dev,
-				  struct net_device *adj_dev, bool upper)
+				  struct net_device *adj_dev, bool upper,
+				  bool is_neigh)
 {
-	struct netdev_adjacent *adj;
+	struct netdev_adjacent *adj, *neighbour;
 
-	if (upper)
-		adj = __netdev_find_upper(dev, adj_dev);
-	else
-		adj = __netdev_find_lower(dev, adj_dev);
+	if (upper) {
+		adj = __netdev_all_upper_find(dev, adj_dev);
+		neighbour = __netdev_upper_find(dev, adj_dev);
+	} else {
+		adj = __netdev_all_lower_find(dev, adj_dev);
+		neighbour = __netdev_lower_find(dev, adj_dev);
+	}
 
-	if (!adj)
+	if (!adj) {
+		pr_err("tried to remove %s device %s from %s\n",
+		       upper ? "upper" : "lower", dev->name, adj_dev->name);
 		BUG();
+	}
+
+	if (is_neigh) {
+		BUG_ON(!neighbour || neighbour->ref_nr > 1);
+		pr_debug("dev_put for %s, because of %s link removed from %s to %s (neighbour)\n",
+			 adj_dev->name, upper ? "upper" : "lower", dev->name,
+			 adj_dev->name);
+		list_del_rcu(&neighbour->list);
+		dev_put(adj_dev);
+		kfree_rcu(neighbour, rcu);
+	}
 
 	if (adj->ref_nr > 1) {
+		pr_debug("rec_cnt-- for link to %s, because of %s link removed from %s to %s, remains %d\n",
+			 adj_dev->name, upper ? "upper" : "lower", dev->name,
+			 adj_dev->name, adj->ref_nr-1);
 		adj->ref_nr--;
 		return;
 	}
@@ -4600,13 +4660,25 @@ void __netdev_adjacent_dev_remove(struct net_device *dev,
 static inline void __netdev_upper_dev_remove(struct net_device *dev,
 					     struct net_device *udev)
 {
-	return __netdev_adjacent_dev_remove(dev, udev, true);
+	return __netdev_adjacent_dev_remove(dev, udev, true, false);
+}
+
+static inline void __netdev_upper_dev_remove_neighbour(struct net_device *dev,
+						struct net_device *udev)
+{
+	return __netdev_adjacent_dev_remove(dev, udev, true, true);
 }
 
 static inline void __netdev_lower_dev_remove(struct net_device *dev,
 					     struct net_device *ldev)
 {
-	return __netdev_adjacent_dev_remove(dev, ldev, false);
+	return __netdev_adjacent_dev_remove(dev, ldev, false, false);
+}
+
+static inline void __netdev_lower_dev_remove_neighbour(struct net_device *dev,
+						struct net_device *ldev)
+{
+	return __netdev_adjacent_dev_remove(dev, ldev, false, true);
 }
 
 int __netdev_adjacent_dev_insert_link(struct net_device *dev,
@@ -4648,6 +4720,13 @@ void __netdev_adjacent_dev_unlink(struct net_device *dev,
 	__netdev_lower_dev_remove(upper_dev, dev);
 }
 
+void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
+					    struct net_device *upper_dev)
+{
+	__netdev_upper_dev_remove_neighbour(dev, upper_dev);
+	__netdev_lower_dev_remove_neighbour(upper_dev, dev);
+}
+
 
 static int __netdev_upper_dev_link(struct net_device *dev,
 				   struct net_device *upper_dev, bool master)
@@ -4661,10 +4740,10 @@ static int __netdev_upper_dev_link(struct net_device *dev,
 		return -EBUSY;
 
 	/* To prevent loops, check if dev is not upper device to upper_dev. */
-	if (__netdev_find_upper(upper_dev, dev))
+	if (__netdev_all_upper_find(upper_dev, dev))
 		return -EBUSY;
 
-	if (__netdev_find_upper(dev, upper_dev))
+	if (__netdev_all_upper_find(dev, upper_dev))
 		return -EEXIST;
 
 	if (master && netdev_master_upper_dev_get(dev))
@@ -4675,12 +4754,14 @@ static int __netdev_upper_dev_link(struct net_device *dev,
 		return ret;
 
 	/* Now that we linked these devs, make all the upper_dev's
-	 * upper_dev_list visible to every dev's lower_dev_list and vice
+	 * all_adj_list.upper visible to every dev's all_adj_list.lower an
 	 * versa, and don't forget the devices itself. All of these
 	 * links are non-neighbours.
 	 */
-	list_for_each_entry(i, &dev->lower_dev_list, list) {
-		list_for_each_entry(j, &upper_dev->upper_dev_list, list) {
+	list_for_each_entry(i, &dev->all_adj_list.lower, list) {
+		list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) {
+			pr_debug("Interlinking %s with %s, non-neighbour\n",
+				 i->dev->name, j->dev->name);
 			ret = __netdev_adjacent_dev_link(i->dev, j->dev);
 			if (ret)
 				goto rollback_mesh;
@@ -4688,14 +4769,18 @@ static int __netdev_upper_dev_link(struct net_device *dev,
 	}
 
 	/* add dev to every upper_dev's upper device */
-	list_for_each_entry(i, &upper_dev->upper_dev_list, list) {
+	list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) {
+		pr_debug("linking %s's upper device %s with %s\n",
+			 upper_dev->name, i->dev->name, dev->name);
 		ret = __netdev_adjacent_dev_link(dev, i->dev);
 		if (ret)
 			goto rollback_upper_mesh;
 	}
 
 	/* add upper_dev to every dev's lower device */
-	list_for_each_entry(i, &dev->lower_dev_list, list) {
+	list_for_each_entry(i, &dev->all_adj_list.lower, list) {
+		pr_debug("linking %s's lower device %s with %s\n", dev->name,
+			 i->dev->name, upper_dev->name);
 		ret = __netdev_adjacent_dev_link(i->dev, upper_dev);
 		if (ret)
 			goto rollback_lower_mesh;
@@ -4706,7 +4791,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
 
 rollback_lower_mesh:
 	to_i = i;
-	list_for_each_entry(i, &dev->lower_dev_list, list) {
+	list_for_each_entry(i, &dev->all_adj_list.lower, list) {
 		if (i == to_i)
 			break;
 		__netdev_adjacent_dev_unlink(i->dev, upper_dev);
@@ -4716,7 +4801,7 @@ rollback_lower_mesh:
 
 rollback_upper_mesh:
 	to_i = i;
-	list_for_each_entry(i, &upper_dev->upper_dev_list, list) {
+	list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) {
 		if (i == to_i)
 			break;
 		__netdev_adjacent_dev_unlink(dev, i->dev);
@@ -4727,8 +4812,8 @@ rollback_upper_mesh:
 rollback_mesh:
 	to_i = i;
 	to_j = j;
-	list_for_each_entry(i, &dev->lower_dev_list, list) {
-		list_for_each_entry(j, &upper_dev->upper_dev_list, list) {
+	list_for_each_entry(i, &dev->all_adj_list.lower, list) {
+		list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) {
 			if (i == to_i && j == to_j)
 				break;
 			__netdev_adjacent_dev_unlink(i->dev, j->dev);
@@ -4737,7 +4822,7 @@ rollback_mesh:
 			break;
 	}
 
-	__netdev_adjacent_dev_unlink(dev, upper_dev);
+	__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
 
 	return ret;
 }
@@ -4791,23 +4876,23 @@ void netdev_upper_dev_unlink(struct net_device *dev,
 	struct netdev_adjacent *i, *j;
 	ASSERT_RTNL();
 
-	__netdev_adjacent_dev_unlink(dev, upper_dev);
+	__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
 
 	/* Here is the tricky part. We must remove all dev's lower
 	 * devices from all upper_dev's upper devices and vice
 	 * versa, to maintain the graph relationship.
 	 */
-	list_for_each_entry(i, &dev->lower_dev_list, list)
-		list_for_each_entry(j, &upper_dev->upper_dev_list, list)
+	list_for_each_entry(i, &dev->all_adj_list.lower, list)
+		list_for_each_entry(j, &upper_dev->all_adj_list.upper, list)
 			__netdev_adjacent_dev_unlink(i->dev, j->dev);
 
 	/* remove also the devices itself from lower/upper device
 	 * list
 	 */
-	list_for_each_entry(i, &dev->lower_dev_list, list)
+	list_for_each_entry(i, &dev->all_adj_list.lower, list)
 		__netdev_adjacent_dev_unlink(i->dev, upper_dev);
 
-	list_for_each_entry(i, &upper_dev->upper_dev_list, list)
+	list_for_each_entry(i, &upper_dev->all_adj_list.upper, list)
 		__netdev_adjacent_dev_unlink(dev, i->dev);
 
 	call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev);
@@ -6069,8 +6154,10 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 	INIT_LIST_HEAD(&dev->napi_list);
 	INIT_LIST_HEAD(&dev->unreg_list);
 	INIT_LIST_HEAD(&dev->link_watch_list);
-	INIT_LIST_HEAD(&dev->upper_dev_list);
-	INIT_LIST_HEAD(&dev->lower_dev_list);
+	INIT_LIST_HEAD(&dev->adj_list.upper);
+	INIT_LIST_HEAD(&dev->adj_list.lower);
+	INIT_LIST_HEAD(&dev->all_adj_list.upper);
+	INIT_LIST_HEAD(&dev->all_adj_list.lower);
 	dev->priv_flags = IFF_XMIT_DST_RELEASE;
 	setup(dev);
 
-- 
1.8.4

^ permalink raw reply related

* Re: [PATCH v2] bonding: Make alb learning packet interval configurable
From: Veaceslav Falico @ 2013-09-10 20:55 UTC (permalink / raw)
  To: Neil Horman
  Cc: netdev, Neil Horman, Jay Vosburgh, Andy Gospodarek,
	David S. Miller
In-Reply-To: <1378845543-14876-1-git-send-email-nhorman@tuxdriver.com>

On Tue, Sep 10, 2013 at 04:39:03PM -0400, Neil Horman wrote:
>From: Neil Horman <nhorman@redhat.com>
>
>running bonding in ALB mode requires that learning packets be sent periodically,
>so that the switch knows where to send responding traffic.  However, depending
>on switch configuration, there may not be any need to send traffic at the
>default rate of 3 packets per second, which represents little more than wasted
>data.  Allow the ALB learning packet interval to be made configurable via sysfs
>
>Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>CC: Jay Vosburgh <fubar@us.ibm.com>
>CC: Andy Gospodarek <andy@greyhouse.net>
>CC: "David S. Miller" <davem@davemloft.net>
>
>---
>Change Notes:
>v2)
>Add documentation

Nice, thank you!

Acked-by: Veaceslav Falico <vfalico@redhat.com>

>---
> Documentation/networking/bonding.txt |  5 +++++
> drivers/net/bonding/bond_alb.c       |  2 +-
> drivers/net/bonding/bond_alb.h       |  8 ++++----
> drivers/net/bonding/bond_main.c      |  1 +
> drivers/net/bonding/bond_sysfs.c     | 39 ++++++++++++++++++++++++++++++++++++
> drivers/net/bonding/bonding.h        |  1 +
> 6 files changed, 51 insertions(+), 5 deletions(-)
>
>diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
>index 87bbcfe..5928f6f 100644
>--- a/Documentation/networking/bonding.txt
>+++ b/Documentation/networking/bonding.txt
>@@ -1362,6 +1362,11 @@ To add ARP targets:
> To remove an ARP target:
> # echo -192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target
>
>+To configure the interval between learning packet transmits:
>+# echo 12 > /sys/class/net/bond0/bonding/lp_interval
>+	NOTE: the lp_inteval is the number of seconds between instances where
>+the bonding driver sends learning packets to each slaves peer switch.
>+
> Example Configuration
> ---------------------
> 	We begin with the same example that is shown in section 3.3,
>diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
>index 91f179d..f428ef57 100644
>--- a/drivers/net/bonding/bond_alb.c
>+++ b/drivers/net/bonding/bond_alb.c
>@@ -1472,7 +1472,7 @@ void bond_alb_monitor(struct work_struct *work)
> 	bond_info->lp_counter++;
>
> 	/* send learning packets */
>-	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
>+	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS(bond)) {
> 		/* change of curr_active_slave involves swapping of mac addresses.
> 		 * in order to avoid this swapping from happening while
> 		 * sending the learning packets, the curr_slave_lock must be held for
>diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
>index 28d8e4c..e78fd9b 100644
>--- a/drivers/net/bonding/bond_alb.h
>+++ b/drivers/net/bonding/bond_alb.h
>@@ -36,14 +36,14 @@ struct slave;
> 					 * Used for division - never set
> 					 * to zero !!!
> 					 */
>-#define BOND_ALB_LP_INTERVAL	    1	/* In seconds, periodic send of
>-					 * learning packets to the switch
>-					 */
>+#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval)	/* In seconds, periodic send of
>+								 * learning packets to the switch
>+								 */
>
> #define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
> 				  * ALB_TIMER_TICKS_PER_SEC)
>
>-#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
>+#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
> 			   * ALB_TIMER_TICKS_PER_SEC)
>
> #define TLB_HASH_TABLE_SIZE 256	/* The size of the clients hash table.
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index 39e5b1c..b8c9ec3 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -4416,6 +4416,7 @@ static int bond_check_params(struct bond_params *params)
> 	params->all_slaves_active = all_slaves_active;
> 	params->resend_igmp = resend_igmp;
> 	params->min_links = min_links;
>+	params->lp_interval = 1;
>
> 	if (primary) {
> 		strncpy(params->primary, primary, IFNAMSIZ);
>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>index ce46776..4532259 100644
>--- a/drivers/net/bonding/bond_sysfs.c
>+++ b/drivers/net/bonding/bond_sysfs.c
>@@ -1680,6 +1680,44 @@ out:
> static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
> 		   bonding_show_resend_igmp, bonding_store_resend_igmp);
>
>+
>+static ssize_t bonding_show_lp_interval(struct device *d,
>+					struct device_attribute *attr,
>+					char *buf)
>+{
>+	struct bonding *bond = to_bond(d);
>+	return sprintf(buf, "%d\n", bond->params.lp_interval);
>+}
>+
>+static ssize_t bonding_store_lp_interval(struct device *d,
>+					 struct device_attribute *attr,
>+					 const char *buf, size_t count)
>+{
>+	struct bonding *bond = to_bond(d);
>+	int new_value, ret = count;
>+
>+	if (sscanf(buf, "%d", &new_value) != 1) {
>+		pr_err("%s: no lp interval value specified.\n",
>+			bond->dev->name);
>+		ret = -EINVAL;
>+		goto out;
>+	}
>+
>+	if (new_value <= 0) {
>+		pr_err ("%s: lp_interval must be between 1 and %d\n",
>+			bond->dev->name, INT_MAX);
>+		ret = -EINVAL;
>+		goto out;
>+	}
>+
>+	bond->params.lp_interval = new_value;
>+out:
>+	return ret;
>+}
>+
>+static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
>+		   bonding_show_lp_interval, bonding_store_lp_interval);
>+
> static struct attribute *per_bond_attrs[] = {
> 	&dev_attr_slaves.attr,
> 	&dev_attr_mode.attr,
>@@ -1710,6 +1748,7 @@ static struct attribute *per_bond_attrs[] = {
> 	&dev_attr_all_slaves_active.attr,
> 	&dev_attr_resend_igmp.attr,
> 	&dev_attr_min_links.attr,
>+	&dev_attr_lp_interval.attr,
> 	NULL,
> };
>
>diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>index f7ab161..4bd9d5b 100644
>--- a/drivers/net/bonding/bonding.h
>+++ b/drivers/net/bonding/bonding.h
>@@ -176,6 +176,7 @@ struct bond_params {
> 	int tx_queues;
> 	int all_slaves_active;
> 	int resend_igmp;
>+	int lp_interval;
> };
>
> struct bond_parm_tbl {
>-- 
>1.8.3.1
>

^ permalink raw reply

* [PATCH v2] bonding: Make alb learning packet interval configurable
From: Neil Horman @ 2013-09-10 20:39 UTC (permalink / raw)
  To: netdev
  Cc: vfalico, Neil Horman, Neil Horman, Jay Vosburgh, Andy Gospodarek,
	David S. Miller
In-Reply-To: <1378822490-28667-1-git-send-email-nhorman@tuxdriver.com>

From: Neil Horman <nhorman@redhat.com>

running bonding in ALB mode requires that learning packets be sent periodically,
so that the switch knows where to send responding traffic.  However, depending
on switch configuration, there may not be any need to send traffic at the
default rate of 3 packets per second, which represents little more than wasted
data.  Allow the ALB learning packet interval to be made configurable via sysfs

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>

---
Change Notes:
v2)
Add documentation
---
 Documentation/networking/bonding.txt |  5 +++++
 drivers/net/bonding/bond_alb.c       |  2 +-
 drivers/net/bonding/bond_alb.h       |  8 ++++----
 drivers/net/bonding/bond_main.c      |  1 +
 drivers/net/bonding/bond_sysfs.c     | 39 ++++++++++++++++++++++++++++++++++++
 drivers/net/bonding/bonding.h        |  1 +
 6 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 87bbcfe..5928f6f 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -1362,6 +1362,11 @@ To add ARP targets:
 To remove an ARP target:
 # echo -192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target
 
+To configure the interval between learning packet transmits:
+# echo 12 > /sys/class/net/bond0/bonding/lp_interval
+	NOTE: the lp_inteval is the number of seconds between instances where
+the bonding driver sends learning packets to each slaves peer switch.
+
 Example Configuration
 ---------------------
 	We begin with the same example that is shown in section 3.3,
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 91f179d..f428ef57 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1472,7 +1472,7 @@ void bond_alb_monitor(struct work_struct *work)
 	bond_info->lp_counter++;
 
 	/* send learning packets */
-	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
+	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS(bond)) {
 		/* change of curr_active_slave involves swapping of mac addresses.
 		 * in order to avoid this swapping from happening while
 		 * sending the learning packets, the curr_slave_lock must be held for
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 28d8e4c..e78fd9b 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -36,14 +36,14 @@ struct slave;
 					 * Used for division - never set
 					 * to zero !!!
 					 */
-#define BOND_ALB_LP_INTERVAL	    1	/* In seconds, periodic send of
-					 * learning packets to the switch
-					 */
+#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval)	/* In seconds, periodic send of
+								 * learning packets to the switch
+								 */
 
 #define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
 				  * ALB_TIMER_TICKS_PER_SEC)
 
-#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
+#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
 			   * ALB_TIMER_TICKS_PER_SEC)
 
 #define TLB_HASH_TABLE_SIZE 256	/* The size of the clients hash table.
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 39e5b1c..b8c9ec3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4416,6 +4416,7 @@ static int bond_check_params(struct bond_params *params)
 	params->all_slaves_active = all_slaves_active;
 	params->resend_igmp = resend_igmp;
 	params->min_links = min_links;
+	params->lp_interval = 1;
 
 	if (primary) {
 		strncpy(params->primary, primary, IFNAMSIZ);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index ce46776..4532259 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1680,6 +1680,44 @@ out:
 static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
 		   bonding_show_resend_igmp, bonding_store_resend_igmp);
 
+
+static ssize_t bonding_show_lp_interval(struct device *d,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct bonding *bond = to_bond(d);
+	return sprintf(buf, "%d\n", bond->params.lp_interval);
+}
+
+static ssize_t bonding_store_lp_interval(struct device *d,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	struct bonding *bond = to_bond(d);
+	int new_value, ret = count;
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		pr_err("%s: no lp interval value specified.\n",
+			bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (new_value <= 0) {
+		pr_err ("%s: lp_interval must be between 1 and %d\n",
+			bond->dev->name, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	bond->params.lp_interval = new_value;
+out:
+	return ret;
+}
+
+static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
+		   bonding_show_lp_interval, bonding_store_lp_interval);
+
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
@@ -1710,6 +1748,7 @@ static struct attribute *per_bond_attrs[] = {
 	&dev_attr_all_slaves_active.attr,
 	&dev_attr_resend_igmp.attr,
 	&dev_attr_min_links.attr,
+	&dev_attr_lp_interval.attr,
 	NULL,
 };
 
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index f7ab161..4bd9d5b 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -176,6 +176,7 @@ struct bond_params {
 	int tx_queues;
 	int all_slaves_active;
 	int resend_igmp;
+	int lp_interval;
 };
 
 struct bond_parm_tbl {
-- 
1.8.3.1

^ permalink raw reply related

* [skge.c] [BUG kernel 3.11] recent commits render ethernet broken/reverting fixes
From: member graysky @ 2013-09-10 19:50 UTC (permalink / raw)
  To: mlindner, stephen, netdev

[-- Attachment #1: Type: text/plain, Size: 1159 bytes --]

Note: I am not subscribed to any mailing list/please cc me on any
communications.

Bug: Linux kernel v3.11.0 for my 10-year-old machine (Asus A7N8X-E
Deluxe) gives me a partially functional network.  I am running Arch
Linux i686.  I do not see anything obvious in the dmesg output to
indicate that a problem exists.  I am happy to supply any additional
info to help you further diagnose this issue.

Attachments:
*dmesg
*proposed patch to fix problem

Bug fix: Reverting the last 3 commits against
drivers/net/ethernet/marvell/skge.c which is contained in the attached
patch fixes the issue.  I do not know which of the 3 caused the
problem; I am not a programmer/developer.

More info: in the bug state (i.e. using the unmodified 3.11 source):

What works:
*Netctl successfully bring up the interface
*I can ping internal IP addresses
*I can resolve domain names; wget can start a download from the AUR
(aur.archlinux.org gets resolved to a numerical IP but the download
never starts).

What doesn't work:
*I cannot ping external addresses (names or numerical)
*I cannot ssh out or into the box
*I cannot receive data via wget which just hangs indefinitely.

[-- Attachment #2: dmesg_output --]
[-- Type: application/octet-stream, Size: 38244 bytes --]

o[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 3.11.0-1-ARCH (tobias@testing-i686) (gcc version 4.8.1 20130725 (prerelease) (GCC) ) #1 SMP PREEMPT Tue Sep 3 09:40:44 CEST 2013
[    0.000000] e820: BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
[    0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000003ffeffff] usable
[    0.000000] BIOS-e820: [mem 0x000000003fff0000-0x000000003fff2fff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x000000003fff3000-0x000000003fffffff] ACPI data
[    0.000000] BIOS-e820: [mem 0x00000000fec00000-0x00000000fec00fff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000fee00000-0x00000000fee00fff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000ffff0000-0x00000000ffffffff] reserved
[    0.000000] Notice: NX (Execute Disable) protection missing in CPU!
[    0.000000] SMBIOS 2.2 present.
[    0.000000] DMI: ASUSTeK Computer INC. A7N8X-E/A7N8X-E, BIOS ASUS A7N8X-E Deluxe ACPI BIOS Rev 1013  11/12/2004
[    0.000000] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
[    0.000000] e820: remove [mem 0x000a0000-0x000fffff] usable
[    0.000000] e820: last_pfn = 0x3fff0 max_arch_pfn = 0x100000
[    0.000000] MTRR default type: uncachable
[    0.000000] MTRR fixed ranges enabled:
[    0.000000]   00000-9FFFF write-back
[    0.000000]   A0000-BFFFF uncachable
[    0.000000]   C0000-C7FFF write-protect
[    0.000000]   C8000-FFFFF uncachable
[    0.000000] MTRR variable ranges enabled:
[    0.000000]   0 base 000000000 mask FC0000000 write-back
[    0.000000]   1 base 0A0000000 mask FE0000000 write-combining
[    0.000000]   2 disabled
[    0.000000]   3 disabled
[    0.000000]   4 disabled
[    0.000000]   5 disabled
[    0.000000]   6 disabled
[    0.000000]   7 disabled
[    0.000000] x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106
[    0.000000] Scanning 1 areas for low memory corruption
[    0.000000] initial memory mapped: [mem 0x00000000-0x01bfffff]
[    0.000000] Base memory trampoline at [c009b000] 9b000 size 16384
[    0.000000] init_memory_mapping: [mem 0x00000000-0x000fffff]
[    0.000000]  [mem 0x00000000-0x000fffff] page 4k
[    0.000000] init_memory_mapping: [mem 0x37000000-0x373fffff]
[    0.000000]  [mem 0x37000000-0x373fffff] page 2M
[    0.000000] init_memory_mapping: [mem 0x30000000-0x36ffffff]
[    0.000000]  [mem 0x30000000-0x36ffffff] page 2M
[    0.000000] init_memory_mapping: [mem 0x00100000-0x2fffffff]
[    0.000000]  [mem 0x00100000-0x003fffff] page 4k
[    0.000000]  [mem 0x00400000-0x2fffffff] page 2M
[    0.000000] init_memory_mapping: [mem 0x37400000-0x377fdfff]
[    0.000000]  [mem 0x37400000-0x377fdfff] page 4k
[    0.000000] BRK [0x0177b000, 0x0177bfff] PGTABLE
[    0.000000] RAMDISK: [mem 0x37840000-0x37c17fff]
[    0.000000] Allocated new RAMDISK: [mem 0x37426000-0x377fd85f]
[    0.000000] Move RAMDISK from [mem 0x37840000-0x37c1785f] to [mem 0x37426000-0x377fd85f]
[    0.000000] ACPI: RSDP 000f75e0 00014 (v00 Nvidia)
[    0.000000] ACPI: RSDT 3fff3000 0002C (v01 Nvidia AWRDACPI 42302E31 AWRD 00000000)
[    0.000000] ACPI: FACP 3fff3040 00074 (v01 Nvidia AWRDACPI 42302E31 AWRD 00000000)
[    0.000000] ACPI: DSDT 3fff30c0 04561 (v01 NVIDIA AWRDACPI 00001000 MSFT 0100000E)
[    0.000000] ACPI: FACS 3fff0000 00040
[    0.000000] ACPI: APIC 3fff7640 0006E (v01 Nvidia AWRDACPI 42302E31 AWRD 00000000)
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] 135MB HIGHMEM available.
[    0.000000] 887MB LOWMEM available.
[    0.000000]   mapped low ram: 0 - 377fe000
[    0.000000]   low ram: 0 - 377fe000
[    0.000000] BRK [0x0177c000, 0x0177cfff] PGTABLE
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x00001000-0x00ffffff]
[    0.000000]   Normal   [mem 0x01000000-0x377fdfff]
[    0.000000]   HighMem  [mem 0x377fe000-0x3ffeffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x00001000-0x0009ffff]
[    0.000000]   node   0: [mem 0x00100000-0x3ffeffff]
[    0.000000] On node 0 totalpages: 262031
[    0.000000] free_area_init_node: node 0, pgdat c15d7680, node_mem_map f6c26020
[    0.000000]   DMA zone: 32 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 3999 pages, LIFO batch:0
[    0.000000]   Normal zone: 1744 pages used for memmap
[    0.000000]   Normal zone: 223230 pages, LIFO batch:31
[    0.000000]   HighMem zone: 272 pages used for memmap
[    0.000000]   HighMem zone: 34802 pages, LIFO batch:7
[    0.000000] Using APIC driver default
[    0.000000] Nvidia board detected. Ignoring ACPI timer override.
[    0.000000] If you got timer trouble try acpi_use_timer_override
[    0.000000] ACPI: PM-Timer IO Port: 0x4008
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
[    0.000000] ACPI: LAPIC_NMI (acpi_id[0x00] high edge lint[0x1])
[    0.000000] ACPI: IOAPIC (id[0x02] address[0xfec00000] gsi_base[0])
[    0.000000] IOAPIC[0]: apic_id 2, version 17, address 0xfec00000, GSI 0-23
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.000000] ACPI: BIOS IRQ0 override ignored.
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 14 global_irq 14 high edge)
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 15 global_irq 15 high edge)
[    0.000000] ACPI: IRQ9 used by override.
[    0.000000] ACPI: IRQ14 used by override.
[    0.000000] ACPI: IRQ15 used by override.
[    0.000000] Using ACPI (MADT) for SMP configuration information
[    0.000000] smpboot: Allowing 1 CPUs, 0 hotplug CPUs
[    0.000000] nr_irqs_gsi: 40
[    0.000000] PM: Registered nosave memory: [mem 0x000a0000-0x000effff]
[    0.000000] PM: Registered nosave memory: [mem 0x000f0000-0x000fffff]
[    0.000000] e820: [mem 0x40000000-0xfebfffff] available for PCI devices
[    0.000000] Booting paravirtualized kernel on bare hardware
[    0.000000] setup_percpu: NR_CPUS:8 nr_cpumask_bits:8 nr_cpu_ids:1 nr_node_ids:1
[    0.000000] PERCPU: Embedded 14 pages/cpu @f6c11000 s33536 r0 d23808 u57344
[    0.000000] pcpu-alloc: s33536 r0 d23808 u57344 alloc=14*4096
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260255
[    0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-linux root=UUID=e44cf5d1-6138-4fcd-9a42-24ea02a17429 rw quiet
[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
[    0.000000] Initializing CPU#0
[    0.000000] allocated 2097016 bytes of page_cgroup
[    0.000000] please try 'cgroup_disable=memory' option if you don't want memory cgroups
[    0.000000] Initializing HighMem for node 0 (000377fe:0003fff0)
[    0.000000] Memory: 1025320K/1048124K available (4259K kernel code, 430K rwdata, 1356K rodata, 608K init, 948K bss, 22804K reserved, 139208K highmem)
[    0.000000] virtual kernel memory layout:
    fixmap  : 0xfff15000 - 0xfffff000   ( 936 kB)
    pkmap   : 0xff800000 - 0xffc00000   (4096 kB)
    vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)
    lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)
      .init : 0xc15e9000 - 0xc1681000   ( 608 kB)
      .data : 0xc1428f5e - 0xc15e8940   (1790 kB)
      .text : 0xc1000000 - 0xc1428f5e   (4259 kB)
[    0.000000] Checking if this processor honours the WP bit even in supervisor mode...Ok.
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] 	RCU dyntick-idle grace-period acceleration is enabled.
[    0.000000] 	Dump stacks of tasks blocking RCU-preempt GP.
[    0.000000] 	RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] NR_IRQS:2304 nr_irqs:256 16
[    0.000000] CPU 0 irqstacks, hard=f6406000 soft=f6408000
[    0.000000] Console: colour dummy device 80x25
[    0.000000] console [tty0] enabled
[    0.000000] tsc: Fast TSC calibration using PIT
[    0.000000] tsc: Detected 2191.342 MHz processor
[    0.003336] Calibrating delay loop (skipped), value calculated using timer frequency.. 4384.29 BogoMIPS (lpj=7304473)
[    0.003340] pid_max: default: 32768 minimum: 301
[    0.003404] Security Framework initialized
[    0.003424] AppArmor: AppArmor disabled by boot time parameter
[    0.003442] Mount-cache hash table entries: 512
[    0.003784] Initializing cgroup subsys memory
[    0.003810] Initializing cgroup subsys devices
[    0.003814] Initializing cgroup subsys freezer
[    0.003817] Initializing cgroup subsys net_cls
[    0.003820] Initializing cgroup subsys blkio
[    0.003857] mce: CPU supports 4 MCE banks
[    0.003878] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0
Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0
tlb_flushall_shift: -1
[    0.010167] Freeing SMP alternatives memory: 20K (c1681000 - c1686000)
[    0.011045] ACPI: Core revision 20130517
[    0.014805] ACPI: All ACPI Tables successfully acquired
[    0.015605] ftrace: allocating 19083 entries in 38 pages
[    0.023487] Enabling APIC mode:  Flat.  Using 1 I/O APICs
[    0.023931] ..TIMER: vector=0x30 apic1=0 pin1=0 apic2=-1 pin2=-1
[    0.058245] smpboot: CPU0: AMD Athlon(tm) XP 3200+ (fam: 06, model: 0a, stepping: 00)
[    0.059999] Performance Events: AMD PMU driver.
[    0.059999] ... version:                0
[    0.059999] ... bit width:              48
[    0.059999] ... generic registers:      4
[    0.059999] ... value mask:             0000ffffffffffff
[    0.059999] ... max period:             00007fffffffffff
[    0.059999] ... fixed-purpose events:   0
[    0.059999] ... event mask:             000000000000000f
[    0.076672] Brought up 1 CPUs
[    0.076679] smpboot: Total of 1 processors activated (4384.29 BogoMIPS)
[    0.077080] NMI watchdog: enabled on all CPUs, permanently consumes one hw-PMU counter.
[    0.077245] devtmpfs: initialized
[    0.077523] PM: Registering ACPI NVS region [mem 0x3fff0000-0x3fff2fff] (12288 bytes)
[    0.079094] RTC time: 17:00:47, date: 09/09/13
[    0.079157] NET: Registered protocol family 16
[    0.079371] ACPI: bus type PCI registered
[    0.079375] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[    0.111138] PCI: PCI BIOS revision 2.10 entry at 0xfb410, last bus=3
[    0.111140] PCI: Using configuration type 1 for base access
[    0.112142] bio: create slab <bio-0> at 0
[    0.112302] ACPI: Added _OSI(Module Device)
[    0.112305] ACPI: Added _OSI(Processor Device)
[    0.112307] ACPI: Added _OSI(3.0 _SCP Extensions)
[    0.112310] ACPI: Added _OSI(Processor Aggregator Device)
[    0.113217] ACPI: EC: Look up EC in DSDT
[    0.116900] ACPI: Interpreter enabled
[    0.116919] ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S2_] (20130517/hwxface-571)
[    0.116925] ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S3_] (20130517/hwxface-571)
[    0.116938] ACPI: (supports S0 S1 S4 S5)
[    0.116941] ACPI: Using IOAPIC for interrupt routing
[    0.116978] PCI: Ignoring host bridge windows from ACPI; if necessary, use "pci=use_crs" and report a bug
[    0.117081] ACPI: No dock devices found.
[    0.125228] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.125323] acpi PNP0A03:00: host bridge window [io  0x0000-0x0cf7] (ignored)
[    0.125327] acpi PNP0A03:00: host bridge window [io  0x0d00-0xffff] (ignored)
[    0.125331] acpi PNP0A03:00: host bridge window [mem 0x000a0000-0x000bffff] (ignored)
[    0.125334] acpi PNP0A03:00: host bridge window [mem 0x000c0000-0x000dffff] (ignored)
[    0.125337] acpi PNP0A03:00: host bridge window [mem 0x40000000-0xfebfffff] (ignored)
[    0.125340] PCI: root bus 00: using default resources
[    0.125344] acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.
[    0.125547] PCI host bridge to bus 0000:00
[    0.125553] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.125556] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
[    0.125559] pci_bus 0000:00: root bus resource [mem 0x00000000-0xffffffff]
[    0.125574] pci 0000:00:00.0: [10de:01e0] type 00 class 0x060000
[    0.125584] pci 0000:00:00.0: reg 0x10: [mem 0xa0000000-0xbfffffff pref]
[    0.125600] pci 0000:00:00.0: nForce2 C1 Halt Disconnect fixup
[    0.125733] pci 0000:00:00.1: [10de:01eb] type 00 class 0x050000
[    0.125874] pci 0000:00:00.2: [10de:01ee] type 00 class 0x050000
[    0.126005] pci 0000:00:00.3: [10de:01ed] type 00 class 0x050000
[    0.126129] pci 0000:00:00.4: [10de:01ec] type 00 class 0x050000
[    0.126258] pci 0000:00:00.5: [10de:01ef] type 00 class 0x050000
[    0.126389] pci 0000:00:01.0: [10de:0060] type 00 class 0x060100
[    0.126569] pci 0000:00:01.1: [10de:0064] type 00 class 0x0c0500
[    0.126584] pci 0000:00:01.1: reg 0x10: [io  0xdc00-0xdc1f]
[    0.126640] pci 0000:00:01.1: PME# supported from D3hot D3cold
[    0.126778] pci 0000:00:02.0: [10de:0067] type 00 class 0x0c0310
[    0.126793] pci 0000:00:02.0: reg 0x10: [mem 0xd6083000-0xd6083fff]
[    0.126848] pci 0000:00:02.0: supports D1 D2
[    0.126851] pci 0000:00:02.0: PME# supported from D0 D1 D2 D3hot D3cold
[    0.126930] pci 0000:00:02.0: System wakeup disabled by ACPI
[    0.126984] pci 0000:00:02.1: [10de:0067] type 00 class 0x0c0310
[    0.126999] pci 0000:00:02.1: reg 0x10: [mem 0xd6081000-0xd6081fff]
[    0.127053] pci 0000:00:02.1: supports D1 D2
[    0.127056] pci 0000:00:02.1: PME# supported from D0 D1 D2 D3hot D3cold
[    0.127135] pci 0000:00:02.1: System wakeup disabled by ACPI
[    0.127191] pci 0000:00:02.2: [10de:0068] type 00 class 0x0c0320
[    0.127208] pci 0000:00:02.2: reg 0x10: [mem 0xd6082000-0xd60820ff]
[    0.127272] pci 0000:00:02.2: supports D1 D2
[    0.127275] pci 0000:00:02.2: PME# supported from D0 D1 D2 D3hot D3cold
[    0.127374] pci 0000:00:02.2: System wakeup disabled by ACPI
[    0.127430] pci 0000:00:05.0: [10de:006b] type 00 class 0x040100
[    0.127445] pci 0000:00:05.0: reg 0x10: [mem 0xd6000000-0xd607ffff]
[    0.127500] pci 0000:00:05.0: supports D1 D2
[    0.127623] pci 0000:00:06.0: [10de:006a] type 00 class 0x040100
[    0.127638] pci 0000:00:06.0: reg 0x10: [io  0xe000-0xe0ff]
[    0.127647] pci 0000:00:06.0: reg 0x14: [io  0xd000-0xd07f]
[    0.127656] pci 0000:00:06.0: reg 0x18: [mem 0xd6084000-0xd6084fff]
[    0.127699] pci 0000:00:06.0: supports D1 D2
[    0.127810] pci 0000:00:08.0: [10de:006c] type 01 class 0x060400
[    0.127911] pci 0000:00:08.0: System wakeup disabled by ACPI
[    0.127964] pci 0000:00:09.0: [10de:0065] type 00 class 0x01018a
[    0.128001] pci 0000:00:09.0: reg 0x20: [io  0xf000-0xf00f]
[    0.128162] pci 0000:00:1e.0: [10de:01e8] type 01 class 0x060400
[    0.128336] pci 0000:01:04.0: [11ab:4320] type 00 class 0x020000
[    0.128358] pci 0000:01:04.0: reg 0x10: [mem 0xd5000000-0xd5003fff]
[    0.128370] pci 0000:01:04.0: reg 0x14: [io  0xa000-0xa0ff]
[    0.128417] pci 0000:01:04.0: reg 0x30: [mem 0x00000000-0x0001ffff pref]
[    0.128456] pci 0000:01:04.0: supports D1 D2
[    0.128459] pci 0000:01:04.0: PME# supported from D0 D1 D2 D3hot D3cold
[    0.128533] pci 0000:01:0b.0: [1095:3112] type 00 class 0x010400
[    0.128553] pci 0000:01:0b.0: reg 0x10: [io  0xa400-0xa407]
[    0.128564] pci 0000:01:0b.0: reg 0x14: [io  0xa800-0xa803]
[    0.128576] pci 0000:01:0b.0: reg 0x18: [io  0xac00-0xac07]
[    0.128587] pci 0000:01:0b.0: reg 0x1c: [io  0xb000-0xb003]
[    0.128599] pci 0000:01:0b.0: reg 0x20: [io  0xb400-0xb40f]
[    0.128611] pci 0000:01:0b.0: reg 0x24: [mem 0xd5004000-0xd50041ff]
[    0.128622] pci 0000:01:0b.0: reg 0x30: [mem 0x00000000-0x0007ffff pref]
[    0.128652] pci 0000:01:0b.0: supports D1 D2
[    0.128722] pci 0000:00:08.0: PCI bridge to [bus 01]
[    0.128727] pci 0000:00:08.0:   bridge window [io  0xa000-0xbfff]
[    0.128732] pci 0000:00:08.0:   bridge window [mem 0xd4000000-0xd5ffffff]
[    0.128787] pci 0000:03:00.0: [10de:0221] type 00 class 0x030000
[    0.128803] pci 0000:03:00.0: reg 0x10: [mem 0xd1000000-0xd1ffffff]
[    0.128812] pci 0000:03:00.0: reg 0x14: [mem 0xc0000000-0xcfffffff pref]
[    0.128821] pci 0000:03:00.0: reg 0x18: [mem 0xd2000000-0xd2ffffff]
[    0.128846] pci 0000:03:00.0: reg 0x30: [mem 0x00000000-0x0001ffff pref]
[    0.128944] pci 0000:00:1e.0: PCI bridge to [bus 03]
[    0.128950] pci 0000:00:1e.0:   bridge window [mem 0xd1000000-0xd3ffffff]
[    0.128955] pci 0000:00:1e.0:   bridge window [mem 0xc0000000-0xcfffffff pref]
[    0.128965] pci_bus 0000:00: on NUMA node 0
[    0.128969] acpi PNP0A03:00: ACPI _OSC support notification failed, disabling PCIe ASPM
[    0.128973] acpi PNP0A03:00: Unable to request _OSC control (_OSC support mask: 0x08)
[    0.129112] ACPI: PCI Interrupt Link [LNK1] (IRQs 3 4 5 6 7 9 10 11 12 14 15) *0, disabled.
[    0.129191] ACPI: PCI Interrupt Link [LNK2] (IRQs 3 4 *5 6 7 9 10 11 12 14 15)
[    0.129271] ACPI: PCI Interrupt Link [LNK3] (IRQs 3 4 5 6 7 9 10 *11 12 14 15)
[    0.129346] ACPI: PCI Interrupt Link [LNK4] (IRQs 3 4 *5 6 7 9 10 11 12 14 15)
[    0.129420] ACPI: PCI Interrupt Link [LNK5] (IRQs 3 4 5 6 7 9 10 11 12 14 15) *0, disabled.
[    0.129496] ACPI: PCI Interrupt Link [LUBA] (IRQs 3 4 *5 6 7 9 10 11 12 14 15)
[    0.129579] ACPI: PCI Interrupt Link [LUBB] (IRQs 3 4 5 6 7 9 10 11 *12 14 15)
[    0.129784] ACPI: PCI Interrupt Link [LMAC] (IRQs 3 4 5 6 7 9 10 11 12 14 15) *0, disabled.
[    0.129860] ACPI: PCI Interrupt Link [LAPU] (IRQs 3 4 5 6 *7 9 10 11 12 14 15)
[    0.129933] ACPI: PCI Interrupt Link [LACI] (IRQs 3 4 5 6 7 *9 10 11 12 14 15)
[    0.130016] ACPI: PCI Interrupt Link [LMCI] (IRQs 3 4 5 6 7 9 10 11 12 14 15) *0, disabled.
[    0.130094] ACPI: PCI Interrupt Link [LSMB] (IRQs 3 4 5 6 *7 9 10 11 12 14 15)
[    0.130174] ACPI: PCI Interrupt Link [LUB2] (IRQs 3 4 5 6 7 9 10 *11 12 14 15)
[    0.130253] ACPI: PCI Interrupt Link [LFIR] (IRQs 3 4 5 6 7 9 10 11 12 14 15) *0, disabled.
[    0.130327] ACPI: PCI Interrupt Link [L3CM] (IRQs 3 4 5 6 7 9 10 11 12 14 15) *0, disabled.
[    0.130401] ACPI: PCI Interrupt Link [LIDE] (IRQs 3 4 5 6 7 9 10 11 12 14 15) *0, disabled.
[    0.130480] ACPI: PCI Interrupt Link [APC1] (IRQs *16), disabled.
[    0.130543] ACPI: PCI Interrupt Link [APC2] (IRQs *17)
[    0.130605] ACPI: PCI Interrupt Link [APC3] (IRQs *18)
[    0.130667] ACPI: PCI Interrupt Link [APC4] (IRQs *19)
[    0.130728] ACPI: PCI Interrupt Link [APC5] (IRQs *16), disabled.
[    0.130822] ACPI: PCI Interrupt Link [APCF] (IRQs 20 21 22) *0
[    0.130917] ACPI: PCI Interrupt Link [APCG] (IRQs 20 21 22) *0
[    0.131010] ACPI: PCI Interrupt Link [APCH] (IRQs 20 21 22) *0, disabled.
[    0.131104] ACPI: PCI Interrupt Link [APCI] (IRQs 20 21 22) *0
[    0.131197] ACPI: PCI Interrupt Link [APCJ] (IRQs 20 21 22) *0
[    0.131290] ACPI: PCI Interrupt Link [APCK] (IRQs 20 21 22) *0, disabled.
[    0.131354] ACPI: PCI Interrupt Link [APCS] (IRQs *23)
[    0.131445] ACPI: PCI Interrupt Link [APCL] (IRQs 20 21 22) *0
[    0.131539] ACPI: PCI Interrupt Link [APCM] (IRQs 20 21 22) *0, disabled.
[    0.131632] ACPI: PCI Interrupt Link [AP3C] (IRQs 20 21 22) *0, disabled.
[    0.131725] ACPI: PCI Interrupt Link [APCZ] (IRQs 20 21 22) *0, disabled.
[    0.132431] ACPI: \_SB_.PCI0: notify handler is installed
[    0.132471] Found 1 acpi root devices
[    0.132619] vgaarb: device added: PCI:0000:03:00.0,decodes=io+mem,owns=io+mem,locks=none
[    0.132621] vgaarb: loaded
[    0.132623] vgaarb: bridge control possible 0000:03:00.0
[    0.132697] PCI: Using ACPI for IRQ routing
[    0.132724] PCI: pci_cache_line_size set to 32 bytes
[    0.132763] e820: reserve RAM buffer [mem 0x3fff0000-0x3fffffff]
[    0.132920] NetLabel: Initializing
[    0.132923] NetLabel:  domain hash size = 128
[    0.132925] NetLabel:  protocols = UNLABELED CIPSOv4
[    0.132944] NetLabel:  unlabeled traffic allowed by default
[    0.132995] Switched to clocksource refined-jiffies
[    0.141261] pnp: PnP ACPI init
[    0.141296] ACPI: bus type PNP registered
[    0.141637] system 00:00: [io  0x4000-0x407f] has been reserved
[    0.141641] system 00:00: [io  0x4080-0x40ff] has been reserved
[    0.141645] system 00:00: [io  0x4400-0x447f] has been reserved
[    0.141648] system 00:00: [io  0x4480-0x44ff] has been reserved
[    0.141652] system 00:00: [io  0x4200-0x427f] has been reserved
[    0.141655] system 00:00: [io  0x4280-0x42ff] has been reserved
[    0.141661] system 00:00: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.141707] system 00:01: [io  0x5000-0x503f] has been reserved
[    0.141712] system 00:01: [io  0x5500-0x553f] has been reserved
[    0.141716] system 00:01: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.141932] system 00:02: [mem 0x000d9800-0x000dbfff] has been reserved
[    0.141937] system 00:02: [mem 0x000f0000-0x000f7fff] could not be reserved
[    0.141941] system 00:02: [mem 0x000f8000-0x000fbfff] could not be reserved
[    0.141945] system 00:02: [mem 0x000fc000-0x000fffff] could not be reserved
[    0.141948] system 00:02: [mem 0x3fff0000-0x3fffffff] could not be reserved
[    0.141952] system 00:02: [mem 0xffff0000-0xffffffff] has been reserved
[    0.141955] system 00:02: [mem 0x00000000-0x0009ffff] could not be reserved
[    0.141959] system 00:02: [mem 0x00100000-0x3ffeffff] could not be reserved
[    0.141962] system 00:02: [mem 0xfec00000-0xfec00fff] could not be reserved
[    0.141966] system 00:02: [mem 0xfee00000-0xfee00fff] has been reserved
[    0.141970] system 00:02: Plug and Play ACPI device, IDs PNP0c01 (active)
[    0.142573] system 00:03: [io  0x04d0-0x04d1] has been reserved
[    0.142578] system 00:03: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.142596] pnp 00:04: [dma 4]
[    0.142633] pnp 00:04: Plug and Play ACPI device, IDs PNP0200 (active)
[    0.142692] pnp 00:05: Plug and Play ACPI device, IDs PNP0b00 (active)
[    0.142733] pnp 00:06: Plug and Play ACPI device, IDs PNP0800 (active)
[    0.142784] pnp 00:07: Plug and Play ACPI device, IDs PNP0c04 (active)
[    0.143142] pnp 00:08: Plug and Play ACPI device, IDs PNP0501 (active)
[    0.143443] pnp 00:09: Plug and Play ACPI device, IDs PNP0501 (active)
[    0.143732] pnp 00:0a: Plug and Play ACPI device, IDs PNP0303 PNP030b (active)
[    0.143982] pnp 00:0b: Plug and Play ACPI device, IDs PNPb006 (active)
[    0.144194] pnp 00:0c: Plug and Play ACPI device, IDs PNPb02f (active)
[    0.144202] pnp: PnP ACPI: found 13 devices
[    0.144205] ACPI: bus type PNP unregistered
[    0.181223] Switched to clocksource acpi_pm
[    0.181259] pci 0000:00:08.0: BAR 15: assigned [mem 0x40000000-0x400fffff pref]
[    0.181264] pci 0000:01:0b.0: BAR 6: assigned [mem 0x40000000-0x4007ffff pref]
[    0.181269] pci 0000:01:04.0: BAR 6: assigned [mem 0x40080000-0x4009ffff pref]
[    0.181273] pci 0000:00:08.0: PCI bridge to [bus 01]
[    0.181277] pci 0000:00:08.0:   bridge window [io  0xa000-0xbfff]
[    0.181283] pci 0000:00:08.0:   bridge window [mem 0xd4000000-0xd5ffffff]
[    0.181288] pci 0000:00:08.0:   bridge window [mem 0x40000000-0x400fffff pref]
[    0.181296] pci 0000:03:00.0: BAR 6: assigned [mem 0xd3000000-0xd301ffff pref]
[    0.181299] pci 0000:00:1e.0: PCI bridge to [bus 03]
[    0.181304] pci 0000:00:1e.0:   bridge window [mem 0xd1000000-0xd3ffffff]
[    0.181308] pci 0000:00:1e.0:   bridge window [mem 0xc0000000-0xcfffffff pref]
[    0.181322] pci 0000:00:08.0: setting latency timer to 64
[    0.181330] pci_bus 0000:00: resource 4 [io  0x0000-0xffff]
[    0.181333] pci_bus 0000:00: resource 5 [mem 0x00000000-0xffffffff]
[    0.181336] pci_bus 0000:01: resource 0 [io  0xa000-0xbfff]
[    0.181339] pci_bus 0000:01: resource 1 [mem 0xd4000000-0xd5ffffff]
[    0.181342] pci_bus 0000:01: resource 2 [mem 0x40000000-0x400fffff pref]
[    0.181346] pci_bus 0000:03: resource 1 [mem 0xd1000000-0xd3ffffff]
[    0.181349] pci_bus 0000:03: resource 2 [mem 0xc0000000-0xcfffffff pref]
[    0.181408] NET: Registered protocol family 2
[    0.181638] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[    0.181714] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)
[    0.181792] TCP: Hash tables configured (established 8192 bind 8192)
[    0.181862] TCP: reno registered
[    0.181866] UDP hash table entries: 512 (order: 2, 16384 bytes)
[    0.181887] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
[    0.181983] NET: Registered protocol family 1
[    0.182282] ACPI: PCI Interrupt Link [APCF] enabled at IRQ 22
[    0.250255] ACPI: PCI Interrupt Link [APCG] enabled at IRQ 21
[    0.326920] ACPI: PCI Interrupt Link [APCL] enabled at IRQ 20
[    0.327032] pci 0000:03:00.0: Boot video device
[    0.327037] PCI: CLS 32 bytes, default 32
[    0.327105] Unpacking initramfs...
[    0.362835] Freeing initrd memory: 3936K (f7426000 - f77fe000)
[    0.362969] apm: BIOS not found.
[    0.363032] Scanning for low memory corruption every 60 seconds
[    0.363495] audit: initializing netlink socket (disabled)
[    0.363516] type=2000 audit(1378746047.363:1): initialized
[    0.376513] bounce pool size: 64 pages
[    0.376536] HugeTLB registered 4 MB page size, pre-allocated 0 pages
[    0.378493] zbud: loaded
[    0.378602] VFS: Disk quotas dquot_6.5.2
[    0.378668] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[    0.378953] msgmni has been set to 1738
[    0.379253] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[    0.379293] io scheduler noop registered
[    0.379296] io scheduler deadline registered
[    0.379339] io scheduler cfq registered (default)
[    0.379504] pci_hotplug: PCI Hot Plug PCI Core version: 0.5
[    0.379531] pciehp: PCI Express Hot Plug Controller Driver version: 0.4
[    0.379633] vesafb: mode is 1024x768x32, linelength=4096, pages=0
[    0.379636] vesafb: scrolling: redraw
[    0.379639] vesafb: Truecolor: size=8:8:8:8, shift=24:16:8:0
[    0.379843] vesafb: framebuffer at 0xc0000000, mapped to 0xf8080000, using 3072k, total 3072k
[    0.435747] Console: switching to colour frame buffer device 128x48
[    0.491469] fb0: VESA VGA frame buffer device
[    0.491537] GHES: HEST is not enabled!
[    0.491556] isapnp: Scanning for PnP cards...
[    0.804800] isapnp: No Plug & Play device found
[    0.804853] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    0.825495] 00:08: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    0.846111] 00:09: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[    0.846589] i8042: PNP: PS/2 Controller [PNP0303:PS2K] at 0x60,0x64 irq 1
[    0.846591] i8042: PNP: PS/2 appears to have AUX port disabled, if this is incorrect please boot with i8042.nopnp
[    0.847491] serio: i8042 KBD port at 0x60,0x64 irq 1
[    0.847629] mousedev: PS/2 mouse device common for all mice
[    0.847730] rtc_cmos 00:05: RTC can wake from S4
[    0.847876] rtc_cmos 00:05: rtc core: registered rtc_cmos as rtc0
[    0.847904] rtc_cmos 00:05: alarms up to one year, y3k, 242 bytes nvram
[    0.847939] cpuidle: using governor ladder
[    0.847942] cpuidle: using governor menu
[    0.847999] drop_monitor: Initializing network drop monitor service
[    0.848098] TCP: cubic registered
[    0.848278] NET: Registered protocol family 10
[    0.848507] NET: Registered protocol family 17
[    0.848522] Key type dns_resolver registered
[    0.848652] Using IPI No-Shortcut mode
[    0.848762] PM: Hibernation image not present or could not be loaded.
[    0.848784] registered taskstats version 1
[    0.849195]   Magic number: 13:458:36
[    0.849296] rtc_cmos 00:05: setting system clock to 2013-09-09 17:00:48 UTC (1378746048)
[    0.849972] Freeing unused kernel memory: 608K (c15e9000 - c1681000)
[    0.849996] Write protecting the kernel text: 4260k
[    0.850104] Write protecting the kernel read-only data: 1360k
[    0.863566] systemd-udevd[39]: starting version 204
[    0.874646] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input0
[    0.928667] ACPI: bus type USB registered
[    0.928716] usbcore: registered new interface driver usbfs
[    0.928741] usbcore: registered new interface driver hub
[    0.932214] usbcore: registered new device driver usb
[    0.932890] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.933073] ehci-pci: EHCI PCI platform driver
[    0.933236] ehci-pci 0000:00:02.2: setting latency timer to 64
[    0.933250] ehci-pci 0000:00:02.2: EHCI Host Controller
[    0.933260] ehci-pci 0000:00:02.2: new USB bus registered, assigned bus number 1
[    0.933275] ehci-pci 0000:00:02.2: debug port 1
[    0.933310] ehci-pci 0000:00:02.2: cache line size of 32 is not supported
[    0.933405] ehci-pci 0000:00:02.2: irq 20, io mem 0xd6082000
[    0.933923] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    0.934096] ohci-pci: OHCI PCI platform driver
[    0.938056] SCSI subsystem initialized
[    0.943407] ehci-pci 0000:00:02.2: USB 2.0 started, EHCI 1.00
[    0.943620] hub 1-0:1.0: USB hub found
[    0.943628] hub 1-0:1.0: 6 ports detected
[    0.943966] ohci-pci 0000:00:02.0: setting latency timer to 64
[    0.943971] ohci-pci 0000:00:02.0: OHCI PCI host controller
[    0.943979] ohci-pci 0000:00:02.0: new USB bus registered, assigned bus number 2
[    0.944021] ohci-pci 0000:00:02.0: irq 22, io mem 0xd6083000
[    0.947956] ACPI: bus type ATA registered
[    0.952016] libata version 3.00 loaded.
[    0.952691] sata_sil 0000:01:0b.0: version 2.4
[    0.952976] ACPI: PCI Interrupt Link [APC3] enabled at IRQ 18
[    0.956520] scsi0 : sata_sil
[    0.959744] scsi1 : sata_sil
[    0.959823] ata1: SATA max UDMA/100 mmio m512@0xd5004000 tf 0xd5004080 irq 18
[    0.959828] ata2: SATA max UDMA/100 mmio m512@0xd5004000 tf 0xd50040c0 irq 18
[    0.998900] hub 2-0:1.0: USB hub found
[    0.998912] hub 2-0:1.0: 3 ports detected
[    0.999073] pata_amd 0000:00:09.0: version 0.4.1
[    0.999134] pata_amd 0000:00:09.0: setting latency timer to 64
[    0.999815] scsi2 : pata_amd
[    1.000258] scsi3 : pata_amd
[    1.000549] ata3: PATA max UDMA/133 cmd 0x1f0 ctl 0x3f6 bmdma 0xf000 irq 14
[    1.000552] ata4: PATA max UDMA/133 cmd 0x170 ctl 0x376 bmdma 0xf008 irq 15
[    1.000684] ohci-pci 0000:00:02.1: setting latency timer to 64
[    1.000689] ohci-pci 0000:00:02.1: OHCI PCI host controller
[    1.000698] ohci-pci 0000:00:02.1: new USB bus registered, assigned bus number 3
[    1.000739] ohci-pci 0000:00:02.1: irq 21, io mem 0xd6081000
[    1.055635] hub 3-0:1.0: USB hub found
[    1.055645] hub 3-0:1.0: 3 ports detected
[    1.276705] ata1: SATA link down (SStatus 0 SControl 310)
[    1.363357] tsc: Refined TSC clocksource calibration: 2191.226 MHz
[    1.596715] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
[    1.603799] ata2.00: HPA detected: current 156299375, native 156301488
[    1.603806] ata2.00: ATA-6: ST380013AS, 3.18, max UDMA/133
[    1.603809] ata2.00: 156299375 sectors, multi 16: LBA48 
[    1.617155] ata2.00: configured for UDMA/100
[    1.617321] scsi 1:0:0:0: Direct-Access     ATA      ST380013AS       3.18 PQ: 0 ANSI: 5
[    1.777042] ata4.00: ATAPI: PIONEER DVD-RW  DVR-107D, 1.21, max UDMA/33
[    1.777051] ata4: nv_mode_filter: 0x739f&0x739f->0x739f, BIOS=0x7000 (0xc000) ACPI=0x701f (60:600:0x13)
[    1.790272] ata4.00: configured for UDMA/33
[    1.797187] scsi 3:0:0:0: CD-ROM            PIONEER  DVD-RW  DVR-107D 1.21 PQ: 0 ANSI: 5
[    1.803907] sd 1:0:0:0: [sda] 156299375 512-byte logical blocks: (80.0 GB/74.5 GiB)
[    1.803995] sd 1:0:0:0: [sda] Write Protect is off
[    1.804000] sd 1:0:0:0: [sda] Mode Sense: 00 3a 00 00
[    1.804037] sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    1.812982] sr0: scsi3-mmc drive: 40x/40x writer cd/rw xa/form2 cdda tray
[    1.812989] cdrom: Uniform CD-ROM driver Revision: 3.20
[    1.813247] sr 3:0:0:0: Attached scsi CD-ROM sr0
[    1.856419]  sda: sda1 sda2 sda3 sda4 sda5 sda6
[    1.857176] sd 1:0:0:0: [sda] Attached SCSI disk
[    2.363410] Switched to clocksource tsc
[    2.637191] EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: (null)
[    3.355776] systemd[1]: systemd 204 running in system mode. (+PAM -LIBWRAP -AUDIT -SELINUX -IMA -SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ)
[    3.372392] systemd[1]: Set hostname to <sub>.
[    4.034589] systemd[1]: Starting Forward Password Requests to Wall Directory Watch.
[    4.034668] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
[    4.034692] systemd[1]: Expecting device sys-subsystem-net-devices-enp1s4.device...
[    4.034714] systemd[1]: Starting Remote File Systems.
[    4.034733] systemd[1]: Reached target Remote File Systems.
[    4.034751] systemd[1]: Starting Delayed Shutdown Socket.
[    4.034800] systemd[1]: Listening on Delayed Shutdown Socket.
[    4.034817] systemd[1]: Starting /dev/initctl Compatibility Named Pipe.
[    4.034853] systemd[1]: Listening on /dev/initctl Compatibility Named Pipe.
[    4.034870] systemd[1]: Starting Device-mapper event daemon FIFOs.
[    4.034910] systemd[1]: Listening on Device-mapper event daemon FIFOs.
[    4.034933] systemd[1]: Starting Dispatch Password Requests to Console Directory Watch.
[    4.034983] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
[    4.034999] systemd[1]: Starting Paths.
[    4.035017] systemd[1]: Reached target Paths.
[    4.035035] systemd[1]: Starting Journal Socket.
[    4.035102] systemd[1]: Listening on Journal Socket.
[    4.035126] systemd[1]: Starting Setup Virtual Console...
[    4.073117] systemd[1]: Starting Load Kernel Modules...
[    4.073863] systemd[1]: Starting Journal Service...
[    4.074569] systemd[1]: Started Journal Service.
[    4.074664] systemd[1]: Mounting Debug File System...
[    4.075284] systemd[1]: Starting Encrypted Volumes.
[    4.075313] systemd[1]: Reached target Encrypted Volumes.
[    4.075377] systemd[1]: Starting Arbitrary Executable File Formats File System Automount Point.
[    4.075555] systemd[1]: Set up automount Arbitrary Executable File Formats File System Automount Point.
[    4.102323] systemd[1]: Started Set Up Additional Binary Formats.
[    4.102460] systemd[1]: Starting udev Kernel Socket.
[    4.102519] systemd[1]: Listening on udev Kernel Socket.
[    4.102611] systemd[1]: Starting udev Control Socket.
[    4.102658] systemd[1]: Listening on udev Control Socket.
[    4.102743] systemd[1]: Starting udev Coldplug all Devices...
[    4.104209] systemd[1]: Mounting Huge Pages File System...
[    4.104909] systemd[1]: Starting Create static device nodes in /dev...
[    4.105595] systemd[1]: Mounting POSIX Message Queue File System...
[    4.128406] systemd[1]: Starting Apply Kernel Variables...
[    4.129193] systemd[1]: Expecting device dev-disk-by\x2dlabel-swap.device...
[    4.129239] systemd[1]: Started File System Check on Root Device.
[    4.129270] systemd[1]: Mounting Temporary Directory...
[    4.150626] systemd[1]: Starting Remount Root and Kernel File Systems...
[    4.151333] systemd[1]: Expecting device dev-disk-by\x2dlabel-boot.device...
[    4.151359] systemd[1]: Expecting device dev-disk-by\x2dlabel-homes.device...
[    4.874094] systemd-udevd[109]: starting version 204
[    5.091469] FS-Cache: Loaded
[    5.123824] RPC: Registered named UNIX socket transport module.
[    5.123830] RPC: Registered udp transport module.
[    5.123832] RPC: Registered tcp transport module.
[    5.123834] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    5.193221] FS-Cache: Netfs 'nfs' registered for caching
[    5.212678] EXT4-fs (sda2): re-mounted. Opts: (null)
[    5.539182] input: Power Button as /devices/LNXSYSTM:00/device:00/PNP0C0C:00/input/input1
[    5.539194] ACPI: Power Button [PWRB]
[    5.539293] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input2
[    5.539297] ACPI: Power Button [PWRF]
[    5.621556] Linux agpgart interface v0.103
[    5.637170] agpgart: Detected NVIDIA nForce2 chipset
[    5.666970] agpgart-nvidia 0000:00:00.0: AGP aperture is 512M @ 0xa0000000
[    5.667026] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
[    5.854746] i2c i2c-0: nForce2 SMBus adapter at 0x5000
[    5.854780] i2c i2c-1: nForce2 SMBus adapter at 0x5500
[    5.884663] ACPI: PCI Interrupt Link [APCJ] enabled at IRQ 22
[    5.884702] snd_intel8x0 0000:00:06.0: setting latency timer to 64
[    5.916201] input: PC Speaker as /devices/platform/pcspkr/input/input3
[    5.971066] gameport gameport0: NS558 PnP Gameport is pnp00:0c/gameport0, io 0x201, speed 701kHz
[    6.020372] ACPI: PCI Interrupt Link [APC2] enabled at IRQ 17
[    6.020443] skge: 1.14 addr 0xd5000000 irq 17 chip Yukon-Lite rev 7
[    6.020977] skge 0000:01:04.0 eth0: addr 00:0e:a6:70:b8:12
[    6.080144] systemd-udevd[122]: renamed network interface eth0 to enp1s4
[    6.206695] intel8x0_measure_ac97_clock: measured 52005 usecs (2528 samples)
[    6.206702] intel8x0: clocking to 47397
[    7.463433] Adding 1048572k swap on /dev/sda5.  Priority:-1 extents:1 across:1048572k FS
[    7.938849] EXT4-fs (sda4): mounted filesystem with ordered data mode. Opts: (null)
[    8.117195] EXT4-fs (sda6): mounted filesystem with ordered data mode. Opts: (null)
[    9.009004] skge 0000:01:04.0 enp1s4: enabling interface
[    9.012600] IPv6: ADDRCONF(NETDEV_UP): enp1s4: link is not ready
[   11.906824] skge 0000:01:04.0 enp1s4: Link is up at 1000 Mbps, full duplex, flow control both
[   11.906848] IPv6: ADDRCONF(NETDEV_CHANGE): enp1s4: link becomes ready
[   12.093470] skge 0000:01:04.0 enp1s4: disabling interface
[   12.095851] skge 0000:01:04.0 enp1s4: enabling interface
[   15.733743] skge 0000:01:04.0 enp1s4: Link is up at 1000 Mbps, full duplex, flow control both
[   16.197821] NFS: Registering the id_resolver key type
[   16.197847] Key type id_resolver registered
[   16.197849] Key type id_legacy registered

[-- Attachment #3: revert_skge_commits.patch --]
[-- Type: application/octet-stream, Size: 4497 bytes --]

--- linux-3.11/drivers/net/ethernet/marvell/skge.c	2013-09-02 16:46:10.000000000 -0400
+++ linux-3.11.mod/drivers/net/ethernet/marvell/skge.c	2013-09-10 15:05:36.119772745 -0400
@@ -931,20 +931,17 @@
 }
 
 /* Allocate and setup a new buffer for receiving */
-static int skge_rx_setup(struct skge_port *skge, struct skge_element *e,
-			 struct sk_buff *skb, unsigned int bufsize)
+static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+			  struct sk_buff *skb, unsigned int bufsize)
 {
 	struct skge_rx_desc *rd = e->desc;
-	dma_addr_t map;
+	u64 map;
 
 	map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
 			     PCI_DMA_FROMDEVICE);
 
-	if (pci_dma_mapping_error(skge->hw->pdev, map))
-		return -1;
-
-	rd->dma_lo = lower_32_bits(map);
-	rd->dma_hi = upper_32_bits(map);
+	rd->dma_lo = map;
+	rd->dma_hi = map >> 32;
 	e->skb = skb;
 	rd->csum1_start = ETH_HLEN;
 	rd->csum2_start = ETH_HLEN;
@@ -956,7 +953,6 @@
 	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, bufsize);
-	return 0;
 }
 
 /* Resume receiving using existing skb,
@@ -1018,10 +1014,7 @@
 			return -ENOMEM;
 
 		skb_reserve(skb, NET_IP_ALIGN);
-		if (skge_rx_setup(skge, e, skb, skge->rx_buf_size) < 0) {
-			dev_kfree_skb(skb);
-			return -EIO;
-		}
+		skge_rx_setup(skge, e, skb, skge->rx_buf_size);
 	} while ((e = e->next) != ring->start);
 
 	ring->to_clean = ring->start;
@@ -2551,7 +2544,7 @@
 
 	BUG_ON(skge->dma & 7);
 
-	if (upper_32_bits(skge->dma) != upper_32_bits(skge->dma + skge->mem_size)) {
+	if ((u64)skge->dma >> 32 != ((u64) skge->dma + skge->mem_size) >> 32) {
 		dev_err(&hw->pdev->dev, "pci_alloc_consistent region crosses 4G boundary\n");
 		err = -EINVAL;
 		goto free_pci_mem;
@@ -2736,7 +2729,7 @@
 	struct skge_tx_desc *td;
 	int i;
 	u32 control, len;
-	dma_addr_t map;
+	u64 map;
 
 	if (skb_padto(skb, ETH_ZLEN))
 		return NETDEV_TX_OK;
@@ -2750,14 +2743,11 @@
 	e->skb = skb;
 	len = skb_headlen(skb);
 	map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(hw->pdev, map))
-		goto mapping_error;
-
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, len);
 
-	td->dma_lo = lower_32_bits(map);
-	td->dma_hi = upper_32_bits(map);
+	td->dma_lo = map;
+	td->dma_hi = map >> 32;
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		const int offset = skb_checksum_start_offset(skb);
@@ -2788,16 +2778,14 @@
 
 			map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
 					       skb_frag_size(frag), DMA_TO_DEVICE);
-			if (dma_mapping_error(&hw->pdev->dev, map))
-				goto mapping_unwind;
 
 			e = e->next;
 			e->skb = skb;
 			tf = e->desc;
 			BUG_ON(tf->control & BMU_OWN);
 
-			tf->dma_lo = lower_32_bits(map);
-			tf->dma_hi = upper_32_bits(map);
+			tf->dma_lo = map;
+			tf->dma_hi = (u64) map >> 32;
 			dma_unmap_addr_set(e, mapaddr, map);
 			dma_unmap_len_set(e, maplen, skb_frag_size(frag));
 
@@ -2827,26 +2815,6 @@
 	}
 
 	return NETDEV_TX_OK;
-
-mapping_unwind:
-	e = skge->tx_ring.to_use;
-	pci_unmap_single(hw->pdev,
-			 dma_unmap_addr(e, mapaddr),
-			 dma_unmap_len(e, maplen),
-			 PCI_DMA_TODEVICE);
-	while (i-- > 0) {
-		e = e->next;
-		pci_unmap_page(hw->pdev,
-			       dma_unmap_addr(e, mapaddr),
-			       dma_unmap_len(e, maplen),
-			       PCI_DMA_TODEVICE);
-	}
-
-mapping_error:
-	if (net_ratelimit())
-		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
-	dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
 }
 
 
@@ -3077,13 +3045,11 @@
 
 		pci_dma_sync_single_for_cpu(skge->hw->pdev,
 					    dma_unmap_addr(e, mapaddr),
-					    dma_unmap_len(e, maplen),
-					    PCI_DMA_FROMDEVICE);
+					    len, PCI_DMA_FROMDEVICE);
 		skb_copy_from_linear_data(e->skb, skb->data, len);
 		pci_dma_sync_single_for_device(skge->hw->pdev,
 					       dma_unmap_addr(e, mapaddr),
-					       dma_unmap_len(e, maplen),
-					       PCI_DMA_FROMDEVICE);
+					       len, PCI_DMA_FROMDEVICE);
 		skge_rx_reuse(e, skge->rx_buf_size);
 	} else {
 		struct sk_buff *nskb;
@@ -3092,17 +3058,13 @@
 		if (!nskb)
 			goto resubmit;
 
-		if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) {
-			dev_kfree_skb(nskb);
-			goto resubmit;
-		}
-
 		pci_unmap_single(skge->hw->pdev,
 				 dma_unmap_addr(e, mapaddr),
 				 dma_unmap_len(e, maplen),
 				 PCI_DMA_FROMDEVICE);
 		skb = e->skb;
 		prefetch(skb->data);
+		skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
 	}
 
 	skb_put(skb, len);

^ permalink raw reply

* pull request: wireless 2013-09-10
From: John W. Linville @ 2013-09-10 19:38 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 12858 bytes --]

Dave,

This is a pull request for a few early fixes for the 3.12 stream.

Alexey Khoroshilov corrects a use-after-free issue on rtl8187 found
by the Linux Driver Verification project.

Arend van Spriel provides a brcmfmac patch to fix a build issue
reported by Randy Dunlap.

Hauke Mehrtens offers a bcma fix to properly account for the storage
width of error code values before checking them.

Solomon Peachy brings a pair of cw1200 fixes to avoid hangs in that
driver with SPI devices.  One avoids transfers in interrupt context,
the other fixes a locking issue.

Stanislaw Gruszka changes the initialization of the rt2800 driver to
avoid a freeze, addressing a bug in the Red Hat bugzilla.

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit e7d33bb5ea82922e6ddcfc6b28a630b1a4ced071:

  lockref: add ability to mark lockrefs "dead" (2013-09-07 15:49:18 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git tags/master-2013-09-09

for you to fetch changes up to f4e1a4d3ecbb9e42bdf8e7869ee8a4ebfa27fb20:

  rt2800: change initialization sequence to fix system freeze (2013-09-09 14:44:34 -0400)

----------------------------------------------------------------
Alexey Khoroshilov (1):
      rtl8187: fix use after free on failure path in rtl8187_init_urbs()

Arend van Spriel (1):
      brcmfmac: fix bus interface selection in Kconfig

Hauke Mehrtens (1):
      bcma: fix error code handling on 64 Bit systems

Solomon Peachy (2):
      cw1200: Don't perform SPI transfers in interrupt context
      cw1200: Prevent a lock-related hang in the cw1200_spi driver

Stanislaw Gruszka (1):
      rt2800: change initialization sequence to fix system freeze

 drivers/bcma/scan.c                        | 12 +++++++-----
 drivers/net/wireless/brcm80211/Kconfig     |  4 ++--
 drivers/net/wireless/cw1200/cw1200_spi.c   | 28 +++++++++++++++++++++++++---
 drivers/net/wireless/cw1200/fwio.c         |  2 +-
 drivers/net/wireless/cw1200/hwbus.h        |  1 +
 drivers/net/wireless/cw1200/hwio.c         | 15 +++++++++++++++
 drivers/net/wireless/rt2x00/rt2800lib.c    | 11 ++++++-----
 drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
 8 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index cd6b20f..3776840 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -269,6 +269,8 @@ static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 core
 	return NULL;
 }
 
+#define IS_ERR_VALUE_U32(x) ((x) >= (u32)-MAX_ERRNO)
+
 static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 			      struct bcma_device_id *match, int core_num,
 			      struct bcma_device *core)
@@ -351,11 +353,11 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 	 * the main register space for the core
 	 */
 	tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
-	if (tmp == 0 || IS_ERR_VALUE(tmp)) {
+	if (tmp == 0 || IS_ERR_VALUE_U32(tmp)) {
 		/* Try again to see if it is a bridge */
 		tmp = bcma_erom_get_addr_desc(bus, eromptr,
 					      SCAN_ADDR_TYPE_BRIDGE, 0);
-		if (tmp == 0 || IS_ERR_VALUE(tmp)) {
+		if (tmp == 0 || IS_ERR_VALUE_U32(tmp)) {
 			return -EILSEQ;
 		} else {
 			bcma_info(bus, "Bridge found\n");
@@ -369,7 +371,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 		for (j = 0; ; j++) {
 			tmp = bcma_erom_get_addr_desc(bus, eromptr,
 				SCAN_ADDR_TYPE_SLAVE, i);
-			if (IS_ERR_VALUE(tmp)) {
+			if (IS_ERR_VALUE_U32(tmp)) {
 				/* no more entries for port _i_ */
 				/* pr_debug("erom: slave port %d "
 				 * "has %d descriptors\n", i, j); */
@@ -386,7 +388,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 		for (j = 0; ; j++) {
 			tmp = bcma_erom_get_addr_desc(bus, eromptr,
 				SCAN_ADDR_TYPE_MWRAP, i);
-			if (IS_ERR_VALUE(tmp)) {
+			if (IS_ERR_VALUE_U32(tmp)) {
 				/* no more entries for port _i_ */
 				/* pr_debug("erom: master wrapper %d "
 				 * "has %d descriptors\n", i, j); */
@@ -404,7 +406,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 		for (j = 0; ; j++) {
 			tmp = bcma_erom_get_addr_desc(bus, eromptr,
 				SCAN_ADDR_TYPE_SWRAP, i + hack);
-			if (IS_ERR_VALUE(tmp)) {
+			if (IS_ERR_VALUE_U32(tmp)) {
 				/* no more entries for port _i_ */
 				/* pr_debug("erom: master wrapper %d "
 				 * has %d descriptors\n", i, j); */
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index fc8a0fa..b00a7e9 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -28,7 +28,7 @@ config BRCMFMAC
 
 config BRCMFMAC_SDIO
 	bool "SDIO bus interface support for FullMAC driver"
-	depends on MMC
+	depends on (MMC = y || MMC = BRCMFMAC)
 	depends on BRCMFMAC
 	select FW_LOADER
 	default y
@@ -39,7 +39,7 @@ config BRCMFMAC_SDIO
 
 config BRCMFMAC_USB
 	bool "USB bus interface support for FullMAC driver"
-	depends on USB
+	depends on (USB = y || USB = BRCMFMAC)
 	depends on BRCMFMAC
 	select FW_LOADER
 	---help---
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index d063760..f5e6b48 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -40,7 +40,9 @@ struct hwbus_priv {
 	struct cw1200_common	*core;
 	const struct cw1200_platform_data_spi *pdata;
 	spinlock_t		lock; /* Serialize all bus operations */
+	wait_queue_head_t       wq;
 	int claimed;
+	int irq_disabled;
 };
 
 #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
@@ -197,8 +199,11 @@ static void cw1200_spi_lock(struct hwbus_priv *self)
 {
 	unsigned long flags;
 
+	DECLARE_WAITQUEUE(wait, current);
+
 	might_sleep();
 
+	add_wait_queue(&self->wq, &wait);
 	spin_lock_irqsave(&self->lock, flags);
 	while (1) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
@@ -211,6 +216,7 @@ static void cw1200_spi_lock(struct hwbus_priv *self)
 	set_current_state(TASK_RUNNING);
 	self->claimed = 1;
 	spin_unlock_irqrestore(&self->lock, flags);
+	remove_wait_queue(&self->wq, &wait);
 
 	return;
 }
@@ -222,6 +228,8 @@ static void cw1200_spi_unlock(struct hwbus_priv *self)
 	spin_lock_irqsave(&self->lock, flags);
 	self->claimed = 0;
 	spin_unlock_irqrestore(&self->lock, flags);
+	wake_up(&self->wq);
+
 	return;
 }
 
@@ -230,6 +238,8 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
 	struct hwbus_priv *self = dev_id;
 
 	if (self->core) {
+		disable_irq_nosync(self->func->irq);
+		self->irq_disabled = 1;
 		cw1200_irq_handler(self->core);
 		return IRQ_HANDLED;
 	} else {
@@ -263,13 +273,22 @@ exit:
 
 static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
 {
-	int ret = 0;
-
 	pr_debug("SW IRQ unsubscribe\n");
 	disable_irq_wake(self->func->irq);
 	free_irq(self->func->irq, self);
 
-	return ret;
+	return 0;
+}
+
+static int cw1200_spi_irq_enable(struct hwbus_priv *self, int enable)
+{
+	/* Disables are handled by the interrupt handler */
+	if (enable && self->irq_disabled) {
+		enable_irq(self->func->irq);
+		self->irq_disabled = 0;
+	}
+
+	return 0;
 }
 
 static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
@@ -349,6 +368,7 @@ static struct hwbus_ops cw1200_spi_hwbus_ops = {
 	.unlock			= cw1200_spi_unlock,
 	.align_size		= cw1200_spi_align_size,
 	.power_mgmt		= cw1200_spi_pm,
+	.irq_enable             = cw1200_spi_irq_enable,
 };
 
 /* Probe Function to be called by SPI stack when device is discovered */
@@ -400,6 +420,8 @@ static int cw1200_spi_probe(struct spi_device *func)
 
 	spi_set_drvdata(func, self);
 
+	init_waitqueue_head(&self->wq);
+
 	status = cw1200_spi_irq_subscribe(self);
 
 	status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
index acdff0f..0b2061b 100644
--- a/drivers/net/wireless/cw1200/fwio.c
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -485,7 +485,7 @@ int cw1200_load_firmware(struct cw1200_common *priv)
 
 	/* Enable interrupt signalling */
 	priv->hwbus_ops->lock(priv->hwbus_priv);
-	ret = __cw1200_irq_enable(priv, 1);
+	ret = __cw1200_irq_enable(priv, 2);
 	priv->hwbus_ops->unlock(priv->hwbus_priv);
 	if (ret < 0)
 		goto unsubscribe;
diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h
index 8b2fc83..51dfb3a 100644
--- a/drivers/net/wireless/cw1200/hwbus.h
+++ b/drivers/net/wireless/cw1200/hwbus.h
@@ -28,6 +28,7 @@ struct hwbus_ops {
 	void (*unlock)(struct hwbus_priv *self);
 	size_t (*align_size)(struct hwbus_priv *self, size_t size);
 	int (*power_mgmt)(struct hwbus_priv *self, bool suspend);
+	int (*irq_enable)(struct hwbus_priv *self, int enable);
 };
 
 #endif /* CW1200_HWBUS_H */
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
index ff230b7..41bd761 100644
--- a/drivers/net/wireless/cw1200/hwio.c
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -273,6 +273,21 @@ int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
 	u16 val16;
 	int ret;
 
+	/* We need to do this hack because the SPI layer can sleep on I/O
+	   and the general path involves I/O to the device in interrupt
+	   context.
+
+	   However, the initial enable call needs to go to the hardware.
+
+	   We don't worry about shutdown because we do a full reset which
+	   clears the interrupt enabled bits.
+	*/
+	if (priv->hwbus_ops->irq_enable) {
+		ret = priv->hwbus_ops->irq_enable(priv->hwbus_priv, enable);
+		if (ret || enable < 2)
+			return ret;
+	}
+
 	if (HIF_8601_SILICON == priv->hw_type) {
 		ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
 		if (ret < 0) {
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 95e6e61..88ce656 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -6659,19 +6659,20 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
 		     rt2800_init_registers(rt2x00dev)))
 		return -EIO;
 
+	if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev)))
+		return -EIO;
+
 	/*
 	 * Send signal to firmware during boot time.
 	 */
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-	if (rt2x00_is_usb(rt2x00dev)) {
+	if (rt2x00_is_usb(rt2x00dev))
 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
-		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
-	}
+	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
 	msleep(1);
 
-	if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
-		     rt2800_wait_bbp_ready(rt2x00dev)))
+	if (unlikely(rt2800_wait_bbp_ready(rt2x00dev)))
 		return -EIO;
 
 	rt2800_init_bbp(rt2x00dev);
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 841fb9d..9a6edb0 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
 		skb_queue_tail(&priv->rx_queue, skb);
 		usb_anchor_urb(entry, &priv->anchored);
 		ret = usb_submit_urb(entry, GFP_KERNEL);
+		usb_put_urb(entry);
 		if (ret) {
 			skb_unlink(skb, &priv->rx_queue);
 			usb_unanchor_urb(entry);
 			goto err;
 		}
-		usb_free_urb(entry);
 	}
 	return ret;
 
 err:
-	usb_free_urb(entry);
 	kfree_skb(skb);
 	usb_kill_anchored_urbs(&priv->anchored);
 	return ret;
@@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 				  (RETRY_COUNT << 8  /* short retry limit */) |
 				  (RETRY_COUNT << 0  /* long retry limit */) |
 				  (7 << 21 /* MAX TX DMA */));
-		rtl8187_init_urbs(dev);
-		rtl8187b_init_status_urb(dev);
+		ret = rtl8187_init_urbs(dev);
+		if (ret)
+			goto rtl8187_start_exit;
+		ret = rtl8187b_init_status_urb(dev);
+		if (ret)
+			usb_kill_anchored_urbs(&priv->anchored);
 		goto rtl8187_start_exit;
 	}
 
@@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 	rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
 	rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
 
-	rtl8187_init_urbs(dev);
+	ret = rtl8187_init_urbs(dev);
+	if (ret)
+		goto rtl8187_start_exit;
 
 	reg = RTL818X_RX_CONF_ONLYERLPKT |
 	      RTL818X_RX_CONF_RX_AUTORESETPHY |
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply related

* Re: [PATCH net] net: sctp: fix ipv6 ipsec encryption bug in sctp_v6_xmit
From: Daniel Borkmann @ 2013-09-10 19:08 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: davem, netdev, linux-sctp, adobriyan, Steffen Klassert,
	Hannes Frederic Sowa
In-Reply-To: <522F6BDD.3050309@gmail.com>

On 09/10/2013 08:58 PM, Vlad Yasevich wrote:
[...]
> I don't think this is actually the correct thing to do.
> 1) Every transmit has a possibility of changing np and thus changing
> the result of getsockname() and getpeername()
> 2) You will end up with a route lookup on every packet since np->dst_cookie is not set properly.
>
> I wonder if it would solve things if you simply pass the flowi cached in the transport to ip6_xmit().
>
> If not, then probably sctp_v6_get_dst() needs to be updated to find the
> correct route, so then it can be cached in the transport along with the
> flowi and used on output.

Ok, let me have a look at these alternatives tomorrow first thing in the
morning, and I'll respin.

Thanks,
Daniel

^ permalink raw reply

* Re: bonding: Make alb learning packet interval configurable
From: Neil Horman @ 2013-09-10 19:04 UTC (permalink / raw)
  To: Veaceslav Falico
  Cc: netdev, Neil Horman, Jay Vosburgh, Andy Gospodarek,
	David S. Miller
In-Reply-To: <20130910181149.GE8474@redhat.com>

On Tue, Sep 10, 2013 at 08:11:49PM +0200, Veaceslav Falico wrote:
> On Tue, Sep 10, 2013 at 10:14:50AM -0400, Neil Horman wrote:
> >From: Neil Horman <nhorman@redhat.com>
> >
> >running bonding in ALB mode requires that learning packets be sent periodically,
> >so that the switch knows where to send responding traffic.  However, depending
> >on switch configuration, there may not be any need to send traffic at the
> >default rate of 3 packets per second, which represents little more than wasted
> >data.  Allow the ALB learning packet interval to be made configurable via sysfs
> >
> >Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >CC: Jay Vosburgh <fubar@us.ibm.com>
> >CC: Andy Gospodarek <andy@greyhouse.net>
> >CC: "David S. Miller" <davem@davemloft.net>
> >
> >---
> >drivers/net/bonding/bond_alb.c   |  2 +-
> >drivers/net/bonding/bond_alb.h   |  8 ++++----
> >drivers/net/bonding/bond_main.c  |  1 +
> >drivers/net/bonding/bond_sysfs.c | 39 +++++++++++++++++++++++++++++++++++++++
> >drivers/net/bonding/bonding.h    |  1 +
> >5 files changed, 46 insertions(+), 5 deletions(-)
> 
> Maybe add some description about it to Documentation/networking/bonding.txt?
> 
Crap, yes, you're right of course.  Thanks.  I'll respin with that added.

Thanks
Neil

> Otherwise seems good.
> 
> >
> >diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
> >index 91f179d..f428ef57 100644
> >--- a/drivers/net/bonding/bond_alb.c
> >+++ b/drivers/net/bonding/bond_alb.c
> >@@ -1472,7 +1472,7 @@ void bond_alb_monitor(struct work_struct *work)
> >	bond_info->lp_counter++;
> >
> >	/* send learning packets */
> >-	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
> >+	if (bond_info->lp_counter >= BOND_ALB_LP_TICKS(bond)) {
> >		/* change of curr_active_slave involves swapping of mac addresses.
> >		 * in order to avoid this swapping from happening while
> >		 * sending the learning packets, the curr_slave_lock must be held for
> >diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
> >index 28d8e4c..e78fd9b 100644
> >--- a/drivers/net/bonding/bond_alb.h
> >+++ b/drivers/net/bonding/bond_alb.h
> >@@ -36,14 +36,14 @@ struct slave;
> >					 * Used for division - never set
> >					 * to zero !!!
> >					 */
> >-#define BOND_ALB_LP_INTERVAL	    1	/* In seconds, periodic send of
> >-					 * learning packets to the switch
> >-					 */
> >+#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval)	/* In seconds, periodic send of
> >+								 * learning packets to the switch
> >+								 */
> >
> >#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
> >				  * ALB_TIMER_TICKS_PER_SEC)
> >
> >-#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
> >+#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
> >			   * ALB_TIMER_TICKS_PER_SEC)
> >
> >#define TLB_HASH_TABLE_SIZE 256	/* The size of the clients hash table.
> >diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> >index 39e5b1c..b8c9ec3 100644
> >--- a/drivers/net/bonding/bond_main.c
> >+++ b/drivers/net/bonding/bond_main.c
> >@@ -4416,6 +4416,7 @@ static int bond_check_params(struct bond_params *params)
> >	params->all_slaves_active = all_slaves_active;
> >	params->resend_igmp = resend_igmp;
> >	params->min_links = min_links;
> >+	params->lp_interval = 1;
> >
> >	if (primary) {
> >		strncpy(params->primary, primary, IFNAMSIZ);
> >diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
> >index ce46776..4532259 100644
> >--- a/drivers/net/bonding/bond_sysfs.c
> >+++ b/drivers/net/bonding/bond_sysfs.c
> >@@ -1680,6 +1680,44 @@ out:
> >static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
> >		   bonding_show_resend_igmp, bonding_store_resend_igmp);
> >
> >+
> >+static ssize_t bonding_show_lp_interval(struct device *d,
> >+					struct device_attribute *attr,
> >+					char *buf)
> >+{
> >+	struct bonding *bond = to_bond(d);
> >+	return sprintf(buf, "%d\n", bond->params.lp_interval);
> >+}
> >+
> >+static ssize_t bonding_store_lp_interval(struct device *d,
> >+					 struct device_attribute *attr,
> >+					 const char *buf, size_t count)
> >+{
> >+	struct bonding *bond = to_bond(d);
> >+	int new_value, ret = count;
> >+
> >+	if (sscanf(buf, "%d", &new_value) != 1) {
> >+		pr_err("%s: no lp interval value specified.\n",
> >+			bond->dev->name);
> >+		ret = -EINVAL;
> >+		goto out;
> >+	}
> >+
> >+	if (new_value <= 0) {
> >+		pr_err ("%s: lp_interval must be between 1 and %d\n",
> >+			bond->dev->name, INT_MAX);
> >+		ret = -EINVAL;
> >+		goto out;
> >+	}
> >+
> >+	bond->params.lp_interval = new_value;
> >+out:
> >+	return ret;
> >+}
> >+
> >+static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
> >+		   bonding_show_lp_interval, bonding_store_lp_interval);
> >+
> >static struct attribute *per_bond_attrs[] = {
> >	&dev_attr_slaves.attr,
> >	&dev_attr_mode.attr,
> >@@ -1710,6 +1748,7 @@ static struct attribute *per_bond_attrs[] = {
> >	&dev_attr_all_slaves_active.attr,
> >	&dev_attr_resend_igmp.attr,
> >	&dev_attr_min_links.attr,
> >+	&dev_attr_lp_interval.attr,
> >	NULL,
> >};
> >
> >diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
> >index f7ab161..4bd9d5b 100644
> >--- a/drivers/net/bonding/bonding.h
> >+++ b/drivers/net/bonding/bonding.h
> >@@ -176,6 +176,7 @@ struct bond_params {
> >	int tx_queues;
> >	int all_slaves_active;
> >	int resend_igmp;
> >+	int lp_interval;
> >};
> >
> >struct bond_parm_tbl {
> 

^ permalink raw reply

* Re: [PATCH net] net: sctp: fix ipv6 ipsec encryption bug in sctp_v6_xmit
From: Vlad Yasevich @ 2013-09-10 18:58 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: davem, netdev, linux-sctp, adobriyan, Steffen Klassert,
	Hannes Frederic Sowa
In-Reply-To: <1378836316-17503-1-git-send-email-dborkman@redhat.com>

On 09/10/2013 02:05 PM, Daniel Borkmann wrote:
> Alan Chester reported an issue with IPv6 on SCTP that IPsec traffic is not
> being encrypted, whereas on IPv4 it is. Setting up an AH + ESP transport
> does not seem to have the desired effect:
>
> SCTP + IPv4:
>
>    22:14:20.809645 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 116)
>      192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x1): ESP(spi=0x00000044,seq=0x1), length 72
>    22:14:20.813270 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 340)
>      192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x1):
>
> SCTP + IPv6:
>
>    22:31:19.215029 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364)
>      fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp
>      1) [INIT ACK] [init tag: 747759530] [rwnd: 62464] [OS: 10] [MIS: 10]
>
> Moreover, Alan says:
>
>    This problem was seen with both Racoon and Racoon2. Other people have seen
>    this with OpenSwan. When IPsec is configured to encrypt all upper layer
>    protocols the SCTP connection does not initialize. After using Wireshark to
>    follow packets, this is because the SCTP packet leaves Box A unencrypted and
>    Box B believes all upper layer protocols are to be encrypted so it drops
>    this packet, causing the SCTP connection to fail to initialize. When IPsec
>    is configured to encrypt just SCTP, the SCTP packets are observed unencrypted.
>
> In fact, using `socat sctp6-listen:3333 -` on one end and transferring "plaintext"
> string on the other end, results in cleartext on the wire where SCTP eventually
> does not report any errors, thus in the latter case that Alan reports, the
> non-paranoid user might think he's communicating over an encrypted transport on
> SCTP although he's not (tcpdump ... -X):
>
>    ...
>    0x0030: 5d70 8e1a 0003 001a 177d eb6c 0000 0000  ]p.......}.l....
>    0x0040: 0000 0000 706c 6169 6e74 6578 740a 0000  ....plaintext...
>
> Only in /proc/net/xfrm_stat we can see XfrmInTmplMismatch increasing on the
> receiver side. Initial follow-up analysis from Alan's bug report was done by
> Alexey Dobriyan.
>
> SCTP has its own implementation of sctp_v6_xmit() not calling inet6_csk_xmit().
> This has the implication that it probably never really got updated along with
> changes in inet6_csk_xmit() and therefore does not seem to invoke xfrm handlers.
> SCTP's IPv4 xmit however, properly calls ip_queue_xmit() to do the work. Hence,
> lets do the same for IPv6 and invoke inet6_csk_xmit() [it does the same work
> for us we do here manually anyway]; result is that we do not have any
> XfrmInTmplMismatch increase plus on the wire with this patch it now looks like:
>
> SCTP + IPv6:
>
>    08:17:47.074080 IP6 2620:52:0:102f:7a2b:cbff:fe27:1b0a > 2620:52:0:102f:213:72ff:fe32:7eba:
>      AH(spi=0x00005fb4,seq=0x1): ESP(spi=0x00005fb5,seq=0x1), length 72
>    08:17:47.074264 IP6 2620:52:0:102f:213:72ff:fe32:7eba > 2620:52:0:102f:7a2b:cbff:fe27:1b0a:
>      AH(spi=0x00003d54,seq=0x1): ESP(spi=0x00003d55,seq=0x1), length 296
>
> This fixes Kernel Bugzilla 24412. This security issue seems to be present since
> 2.6.18 kernels. Lets just hope some big passive adversary in the wild didn't have
> its fun with that. lksctp-tools IPv6 regression test suite passes as well with
> this patch.
>
> Reported-by: Alan Chester <alan.chester@tekelec.com>
> Reported-by: Alexey Dobriyan <adobriyan@gmail.com>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Cc: Steffen Klassert <steffen.klassert@secunet.com>
> Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
> ---
>   net/sctp/ipv6.c | 34 ++++++++--------------------------
>   1 file changed, 8 insertions(+), 26 deletions(-)
>
> diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> index da613ce..74ba5ee 100644
> --- a/net/sctp/ipv6.c
> +++ b/net/sctp/ipv6.c
> @@ -69,6 +69,7 @@
>   #include <net/addrconf.h>
>   #include <net/ip6_route.h>
>   #include <net/inet_common.h>
> +#include <net/inet6_connection_sock.h>
>   #include <net/inet_ecn.h>
>   #include <net/sctp/sctp.h>
>
> @@ -209,39 +210,20 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
>   {
>   	struct sock *sk = skb->sk;
>   	struct ipv6_pinfo *np = inet6_sk(sk);
> -	struct flowi6 fl6;
>
> -	memset(&fl6, 0, sizeof(fl6));
> -
> -	fl6.flowi6_proto = sk->sk_protocol;
> -
> -	/* Fill in the dest address from the route entry passed with the skb
> -	 * and the source address from the transport.
> -	 */
> -	fl6.daddr = transport->ipaddr.v6.sin6_addr;
> -	fl6.saddr = transport->saddr.v6.sin6_addr;
> -
> -	fl6.flowlabel = np->flow_label;
> -	IP6_ECN_flow_xmit(sk, fl6.flowlabel);
> -	if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL)
> -		fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id;
> -	else
> -		fl6.flowi6_oif = sk->sk_bound_dev_if;
> -
> -	if (np->opt && np->opt->srcrt) {
> -		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
> -		fl6.daddr = *rt0->addr;
> -	}
> +	/* This needs to explicitly done as we can have different transports. */
> +	np->daddr = transport->ipaddr.v6.sin6_addr;
> +	np->saddr = transport->saddr.v6.sin6_addr;
>
>   	pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb,
> -		 skb->len, &fl6.saddr, &fl6.daddr);
> -
> -	SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS);
> +		 skb->len, &np->saddr, &np->daddr);
>
>   	if (!(transport->param_flags & SPP_PMTUD_ENABLE))
>   		skb->local_df = 1;
>
> -	return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
> +	SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS);
> +
> +	return inet6_csk_xmit(skb, NULL);
>   }
>
>   /* Returns the dst cache entry for the given source and destination ip
>


I don't think this is actually the correct thing to do.
1) Every transmit has a possibility of changing np and thus changing
the result of getsockname() and getpeername()
2) You will end up with a route lookup on every packet since 
np->dst_cookie is not set properly.

I wonder if it would solve things if you simply pass the flowi cached in 
the transport to ip6_xmit().

If not, then probably sctp_v6_get_dst() needs to be updated to find the
correct route, so then it can be cached in the transport along with the
flowi and used on output.

-vlad

-vlad

-vlad

^ permalink raw reply

* [net 1/2] igb: Add additional get_phy_id call for i354 devices
From: Jeff Kirsher @ 2013-09-10 18:57 UTC (permalink / raw)
  To: davem; +Cc: Carolyn Wyborny, netdev, gospo, sassmann, Jeff Kirsher

From: Carolyn Wyborny <carolyn.wyborny@intel.com>

This patch fixes a problem where some ports can fail to initialize on a
cold boot. This patch adds an additional call to read the PHY id for i354
devices in order workaround the hardware problem.

Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/e1000_82575.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 79b5835..47c2d10 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -719,6 +719,10 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
 	u32 ctrl_ext;
 	u32 mdic;
 
+	/* Extra read required for some PHY's on i354 */
+	if (hw->mac.type == e1000_i354)
+		igb_get_phy_id(hw);
+
 	/* For SGMII PHYs, we try the list of possible addresses until
 	 * we find one that works.  For non-SGMII PHYs
 	 * (e.g. integrated copper PHYs), an address of 1 should
-- 
1.8.3.1

^ permalink raw reply related

* [net 2/2] igb: Read flow control for i350 from correct EEPROM section
From: Jeff Kirsher @ 2013-09-10 18:57 UTC (permalink / raw)
  To: davem; +Cc: Fujinaka, Todd, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1378839437-10965-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: "Fujinaka, Todd" <todd.fujinaka@intel.com>

Flow control is defined in the four EEPROM sections but the driver only reads
from section 0.

Signed-off-by: Todd Fujinaka <todd.fujinaka@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/e1000_mac.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c
index f0dfd41..298f0ed 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -712,6 +712,7 @@ static s32 igb_set_fc_watermarks(struct e1000_hw *hw)
 static s32 igb_set_default_fc(struct e1000_hw *hw)
 {
 	s32 ret_val = 0;
+	u16 lan_offset;
 	u16 nvm_data;
 
 	/* Read and store word 0x0F of the EEPROM. This word contains bits
@@ -722,7 +723,14 @@ static s32 igb_set_default_fc(struct e1000_hw *hw)
 	 * control setting, then the variable hw->fc will
 	 * be initialized based on a value in the EEPROM.
 	 */
-	ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
+	if (hw->mac.type == e1000_i350) {
+		lan_offset = NVM_82580_LAN_FUNC_OFFSET(hw->bus.func);
+		ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG
+					   + lan_offset, 1, &nvm_data);
+	 } else {
+		ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG,
+					   1, &nvm_data);
+	 }
 
 	if (ret_val) {
 		hw_dbg("NVM Read Error\n");
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH][v3.2.y] inetpeer: Invalidate the inetpeer tree along with the routing cache
From: David Miller @ 2013-09-10 18:53 UTC (permalink / raw)
  To: ben
  Cc: netdev, stable, linux-kernel, joseph.salisbury, steffen.klassert,
	edumazet
In-Reply-To: <1377986658.21578.5.camel@deadeye.wl.decadent.org.uk>

From: Ben Hutchings <ben@decadent.org.uk>
Date: Sat, 31 Aug 2013 23:04:18 +0100

> On Tue, 2013-08-20 at 13:34 -0400, Joseph Salisbury wrote:
>> Hello,
>> 
>> Please consider including mainline commit 5faa5df in the next v3.2.y
>> release.  It was included in the mainline tree as of v3.3-rc7.  It has
>> been tested and confirmed to resolve
>> http://bugs.launchpad.net/bugs/1205741 .
>> 
>> 
>> commit 5faa5df1fa2024bd750089ff21dcc4191798263d
>> Author: Steffen Klassert <steffen.klassert@secunet.com>
>> Date:   Tue Mar 6 21:20:26 2012 +0000
>> 
>>     inetpeer: Invalidate the inetpeer tree along with the routing cache
>> 
>> 
>> Also note that commit 5faa5df introduced a race condition that is fixed
>> by mainline commit 55432d2, so that commit would also be required:
>> 
>> commit 55432d2b543a4b6dfae54f5c432a566877a85d90
>> Author: Eric Dumazet <edumazet@google.com>
>> Date:   Tue Jun 5 03:00:18 2012 +0000
>> 
>>     inetpeer: fix a race in inetpeer_gc_worker()
> 
> David, could you ack/nak these for 3.2 (maybe 3.0 as well?).

I'm queueing these two patches up for 3.2 only, the
inetpeer/metrics-cache situation in 3.0 has so many deeper problems
than can be reasonably dealt with using backports.  Just look at the
layout differences of struct inetpeer between 3.0 and 3.2, and the
reasons for that, for the tip of the iceberg.

^ permalink raw reply

* Re: [PATCH][v3.2.y] inetpeer: Invalidate the inetpeer tree along with the routing cache
From: David Miller @ 2013-09-10 18:49 UTC (permalink / raw)
  To: joseph.salisbury; +Cc: ben, netdev, stable, linux-kernel
In-Reply-To: <5213A8BB.5070309@canonical.com>

From: Joseph Salisbury <joseph.salisbury@canonical.com>
Date: Tue, 20 Aug 2013 13:34:51 -0400

> Please consider including mainline commit 5faa5df in the next v3.2.y
> release.  It was included in the mainline tree as of v3.3-rc7.  It has
> been tested and confirmed to resolve
> http://bugs.launchpad.net/bugs/1205741 .
> 
> commit 5faa5df1fa2024bd750089ff21dcc4191798263d
> Author: Steffen Klassert <steffen.klassert@secunet.com>
> Date:   Tue Mar 6 21:20:26 2012 +0000
> 
>     inetpeer: Invalidate the inetpeer tree along with the routing cache
> 
> 
> Also note that commit 5faa5df introduced a race condition that is fixed
> by mainline commit 55432d2, so that commit would also be required:
> 
> commit 55432d2b543a4b6dfae54f5c432a566877a85d90
> Author: Eric Dumazet <edumazet@google.com>
> Date:   Tue Jun 5 03:00:18 2012 +0000
> 
>     inetpeer: fix a race in inetpeer_gc_worker()

Queued up, thanks.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox