* [PATCH net-next 0/8] bonding: remove vlan special handling
@ 2013-08-26 16:28 Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 1/8] net: move netdev_upper to netdevice.h Veaceslav Falico
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev
Cc: Jay Vosburgh, Andy Gospodarek, David S. Miller, Eric Dumazet,
Jiri Pirko, Alexander Duyck, Cong Wang, Veaceslav Falico
The aim of this patchset is to remove bondings' own vlan handling as much
as possible and replace it with the netdev upper device functionality.
This is achieved by exporting the netdev_upper structure and thus permiting
bonding to work directly with its upper devices. The only non-bonding
change is the exporting of netdev_upper, and the only special treatment of
vlans left is in the rlb mode.
This patchset solves several issues with bonding, simplifies it overall,
RCUify further and exports netdev_upper for any other users which might
also want to get rid of its own vlan_lists.
I'm testing it continuously currently, no issues found, will update on
anything.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
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>
---
drivers/net/bonding/bond_alb.c | 74 ++++++------
drivers/net/bonding/bond_alb.h | 2 -
drivers/net/bonding/bond_main.c | 243 ++++++++-------------------------------
drivers/net/bonding/bonding.h | 20 ++-
include/linux/netdevice.h | 8 ++
net/core/dev.c | 8 --
6 files changed, 103 insertions(+), 252 deletions(-)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH net-next 1/8] net: move netdev_upper to netdevice.h
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 16:41 ` Jiri Pirko
2013-08-26 16:28 ` [PATCH net-next 2/8] bonding: use netdev_upper list in bond_vlan_used Veaceslav Falico
` (7 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev
Cc: Veaceslav Falico, David S. Miller, Eric Dumazet, Jiri Pirko,
Alexander Duyck, Cong Wang
So that any device can work with it to see its upper/master devices. It is
rcu'd and rtnl_lock protected, so one should either hold the rtnl_lock() or
to use the _rcu() functions for it.
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>
---
include/linux/netdevice.h | 8 ++++++++
net/core/dev.c | 8 --------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 077363d..8cc7f43 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2764,6 +2764,14 @@ extern int netdev_tstamp_prequeue;
extern int weight_p;
extern int bpf_jit_enable;
+struct netdev_upper {
+ struct net_device *dev;
+ bool master;
+ struct list_head list;
+ struct rcu_head rcu;
+ struct list_head search_list;
+};
+
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);
diff --git a/net/core/dev.c b/net/core/dev.c
index 1ed2b66..f58e82a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4367,14 +4367,6 @@ softnet_break:
goto out;
}
-struct netdev_upper {
- struct net_device *dev;
- bool master;
- struct list_head list;
- struct rcu_head rcu;
- struct list_head search_list;
-};
-
static void __append_search_uppers(struct list_head *search_list,
struct net_device *dev)
{
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next 2/8] bonding: use netdev_upper list in bond_vlan_used
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 1/8] net: move netdev_upper to netdevice.h Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 3/8] bonding: make bond_arp_send_all use upper device list Veaceslav Falico
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
Convert bond_vlan_used() to traverse the upper device list to see if we
have any vlans above us. It's protected by rcu, and in case we are holding
rtnl_lock we should call vlan_uses_dev() instead - it's faster.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
drivers/net/bonding/bonding.h | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 4bf52d5..5ebb3d8 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -267,9 +267,21 @@ struct bonding {
#endif /* CONFIG_DEBUG_FS */
};
+/* if we hold rtnl_lock() - call vlan_uses_dev() */
static inline bool bond_vlan_used(struct bonding *bond)
{
- return !list_empty(&bond->vlan_list);
+ struct netdev_upper *upper;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(upper, &bond->dev->upper_dev_list, list) {
+ if (upper->dev->priv_flags & IFF_802_1Q_VLAN) {
+ rcu_read_unlock();
+ return true;
+ }
+ }
+ rcu_read_unlock();
+
+ return false;
}
#define bond_slave_get_rcu(dev) \
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next 3/8] bonding: make bond_arp_send_all use upper device list
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 1/8] net: move netdev_upper to netdevice.h Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 2/8] bonding: use netdev_upper list in bond_vlan_used Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 4/8] bonding: convert bond_has_this_ip() to use upper devices Veaceslav Falico
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
Currently, bond_arp_send_all() is aware only of vlans, which breaks
configurations like bond <- bridge (or any other 'upper' device) with IP
(which is quite a common scenario for virt setups).
To fix this we convert the bond_arp_send_all() to first verify if the rt
device is the bond itself, and if not - to go through its list of upper
devices to see if any of them match the route device for the target. If the
match is a vlan device - we also save its vlan_id and tag it in
bond_arp_send().
Also, clean the function a bit to be more readable.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
drivers/net/bonding/bond_main.c | 84 ++++++++++++++------------------------
1 files changed, 31 insertions(+), 53 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 7407e65..f8927b3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2444,30 +2444,15 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
{
- int i, vlan_id;
- __be32 *targets = bond->params.arp_targets;
- struct vlan_entry *vlan;
- struct net_device *vlan_dev = NULL;
+ struct netdev_upper *upper;
struct rtable *rt;
+ __be32 *targets = bond->params.arp_targets, addr;
+ int i, vlan_id;
- for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
- __be32 addr;
- if (!targets[i])
- break;
+ for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) {
pr_debug("basa: target %pI4\n", &targets[i]);
- if (!bond_vlan_used(bond)) {
- pr_debug("basa: empty vlan: arp_send\n");
- addr = bond_confirm_addr(bond->dev, targets[i], 0);
- bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
- addr, 0);
- continue;
- }
- /*
- * If VLANs are configured, we do a route lookup to
- * determine which VLAN interface would be used, so we
- * can tag the ARP with the proper VLAN tag.
- */
+ /* Find out through which dev should the packet go */
rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
RTO_ONLINK, 0);
if (IS_ERR(rt)) {
@@ -2478,47 +2463,40 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
continue;
}
- /*
- * This target is not on a VLAN
- */
- if (rt->dst.dev == bond->dev) {
- ip_rt_put(rt);
- pr_debug("basa: rtdev == bond->dev: arp_send\n");
- addr = bond_confirm_addr(bond->dev, targets[i], 0);
- bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
- addr, 0);
- continue;
- }
-
vlan_id = 0;
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- rcu_read_lock();
- vlan_dev = __vlan_find_dev_deep(bond->dev,
- htons(ETH_P_8021Q),
- vlan->vlan_id);
- rcu_read_unlock();
- if (vlan_dev == rt->dst.dev) {
- vlan_id = vlan->vlan_id;
- pr_debug("basa: vlan match on %s %d\n",
- vlan_dev->name, vlan_id);
- break;
- }
- }
- if (vlan_id && vlan_dev) {
- ip_rt_put(rt);
- addr = bond_confirm_addr(vlan_dev, targets[i], 0);
- bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
- addr, vlan_id);
- continue;
+ /* bond device itself */
+ if (rt->dst.dev == bond->dev)
+ goto found;
+
+ /* search for upper device, like vlan/bridge/team/etc */
+ rcu_read_lock();
+ list_for_each_entry_rcu(upper, &bond->dev->upper_dev_list,
+ list) {
+ if (upper->dev == rt->dst.dev) {
+ /* if it's a vlan - get its VID */
+ if (is_vlan_dev(rt->dst.dev))
+ vlan_id = vlan_dev_vlan_id(rt->dst.dev);
+
+ rcu_read_unlock();
+ goto found;
+ }
}
+ rcu_read_unlock();
- if (net_ratelimit()) {
+ /* Not our device - skip */
+ if (net_ratelimit())
pr_warning("%s: no path to arp_ip_target %pI4 via rt.dev %s\n",
bond->dev->name, &targets[i],
rt->dst.dev ? rt->dst.dev->name : "NULL");
- }
ip_rt_put(rt);
+ continue;
+
+found:
+ addr = bond_confirm_addr(rt->dst.dev, targets[i], 0);
+ ip_rt_put(rt);
+ bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
+ addr, vlan_id);
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next 4/8] bonding: convert bond_has_this_ip() to use upper devices
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
` (2 preceding siblings ...)
2013-08-26 16:28 ` [PATCH net-next 3/8] bonding: make bond_arp_send_all use upper device list Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 5/8] bonding: use vlan_uses_dev() in __bond_release_one() Veaceslav Falico
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
Currently, bond_has_this_ip() is aware only of vlan upper devices, and thus
will return false if the address is associated with the upper bridge or any
other device, and thus will break the arp logic.
Fix this by using the upper device list. For every upper device we verify
if the address associated with it is our address, and if yes - return true.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
drivers/net/bonding/bond_main.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f8927b3..f3787a2 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2392,24 +2392,24 @@ re_arm:
}
}
-static int bond_has_this_ip(struct bonding *bond, __be32 ip)
+static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
{
- struct vlan_entry *vlan;
- struct net_device *vlan_dev;
+ struct netdev_upper *upper;
+ bool ret = false;
if (ip == bond_confirm_addr(bond->dev, 0, ip))
- return 1;
+ return true;
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- rcu_read_lock();
- vlan_dev = __vlan_find_dev_deep(bond->dev, htons(ETH_P_8021Q),
- vlan->vlan_id);
- rcu_read_unlock();
- if (vlan_dev && ip == bond_confirm_addr(vlan_dev, 0, ip))
- return 1;
+ rcu_read_lock();
+ list_for_each_entry_rcu(upper, &bond->dev->upper_dev_list, list) {
+ if (ip == bond_confirm_addr(upper->dev, 0, ip)) {
+ ret = true;
+ break;
+ }
}
+ rcu_read_unlock();
- return 0;
+ return ret;
}
/*
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next 5/8] bonding: use vlan_uses_dev() in __bond_release_one()
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
` (3 preceding siblings ...)
2013-08-26 16:28 ` [PATCH net-next 4/8] bonding: convert bond_has_this_ip() to use upper devices Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 6/8] bonding: split alb_send_learning_packets() Veaceslav Falico
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
We always hold the rtnl_lock() in __bond_release_one(), so use
vlan_uses_dev() instead of bond_vlan_used().
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
drivers/net/bonding/bond_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f3787a2..9af37e6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1954,7 +1954,7 @@ static int __bond_release_one(struct net_device *bond_dev,
bond_set_carrier(bond);
eth_hw_addr_random(bond_dev);
- if (bond_vlan_used(bond)) {
+ if (vlan_uses_dev(bond_dev)) {
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
bond_dev->name, bond_dev->name);
pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next 6/8] bonding: split alb_send_learning_packets()
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
` (4 preceding siblings ...)
2013-08-26 16:28 ` [PATCH net-next 5/8] bonding: use vlan_uses_dev() in __bond_release_one() Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 7/8] bonding: make alb_send_learning_packets() use upper dev list Veaceslav Falico
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
Create alb_send_lp_vid(), which will handle the skb/lp creation, vlan
tagging and sending, and use it in alb_send_learning_packets().
This way all the logic remains in alb_send_learning_packets(), which
becomes a lot more cleaner and easier to understand.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
drivers/net/bonding/bond_alb.c | 59 +++++++++++++++++++++++----------------
1 files changed, 35 insertions(+), 24 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 3a5db7b..3ca3c85 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -971,35 +971,53 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
/*********************** tlb/rlb shared functions *********************/
-static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
+static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[],
+ u16 vid)
{
- struct bonding *bond = bond_get_bond_by_slave(slave);
struct learning_pkt pkt;
+ struct sk_buff *skb;
int size = sizeof(struct learning_pkt);
- int i;
+ char *data;
memset(&pkt, 0, size);
memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
pkt.type = cpu_to_be16(ETH_P_LOOP);
- for (i = 0; i < MAX_LP_BURST; i++) {
- struct sk_buff *skb;
- char *data;
+ skb = dev_alloc_skb(size);
+ if (!skb)
+ return;
- skb = dev_alloc_skb(size);
+ data = skb_put(skb, size);
+ memcpy(data, &pkt, size);
+
+ skb_reset_mac_header(skb);
+ skb->network_header = skb->mac_header + ETH_HLEN;
+ skb->protocol = pkt.type;
+ skb->priority = TC_PRIO_CONTROL;
+ skb->dev = slave->dev;
+
+ if (vid) {
+ skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vid);
if (!skb) {
+ pr_err("%s: Error: failed to insert VLAN tag\n",
+ slave->bond->dev->name);
return;
}
+ }
- data = skb_put(skb, size);
- memcpy(data, &pkt, size);
+ dev_queue_xmit(skb);
+}
- skb_reset_mac_header(skb);
- skb->network_header = skb->mac_header + ETH_HLEN;
- skb->protocol = pkt.type;
- skb->priority = TC_PRIO_CONTROL;
- skb->dev = slave->dev;
+
+static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
+{
+ struct bonding *bond = bond_get_bond_by_slave(slave);
+ u16 vlan_id;
+ int i;
+
+ for (i = 0; i < MAX_LP_BURST; i++) {
+ vlan_id = 0;
if (bond_vlan_used(bond)) {
struct vlan_entry *vlan;
@@ -1008,20 +1026,13 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
bond->alb_info.current_alb_vlan);
bond->alb_info.current_alb_vlan = vlan;
- if (!vlan) {
- kfree_skb(skb);
+ if (!vlan)
continue;
- }
- skb = vlan_put_tag(skb, htons(ETH_P_8021Q), vlan->vlan_id);
- if (!skb) {
- pr_err("%s: Error: failed to insert VLAN tag\n",
- bond->dev->name);
- continue;
- }
+ vlan_id = vlan->vlan_id;
}
- dev_queue_xmit(skb);
+ alb_send_lp_vid(slave, mac_addr, vlan_id);
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next 7/8] bonding: make alb_send_learning_packets() use upper dev list
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
` (5 preceding siblings ...)
2013-08-26 16:28 ` [PATCH net-next 6/8] bonding: split alb_send_learning_packets() Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 8/8] bonding: remove vlan_list/current_alb_vlan Veaceslav Falico
2013-08-26 20:33 ` [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
Currently, if there are vlans on top of bond, alb_send_learning_packets()
will never send LPs from the bond itself (i.e. untagged), which might leave
untagged clients unupdated.
Also, the 'circular vlan' logic (i.e. update only MAX_LP_BURST vlans at a
time, and save the last vlan for the next update) is really suboptimal - in
case of lots of vlans it will take a lot of time to update every vlan. It
is also never called in any hot path and sends only a few small packets -
thus the optimization by itself is useless.
So remove the whole current_alb_vlan/MAX_LP_BURST logic from
alb_send_learning_packets(). Instead, we'll first send a packet untagged
and then traverse the upper dev list, sending a tagged packet for each vlan
found. Also, remove the MAX_LP_BURST define - we already don't need it.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
drivers/net/bonding/bond_alb.c | 28 ++++++++++------------------
drivers/net/bonding/bond_alb.h | 1 -
2 files changed, 10 insertions(+), 19 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 3ca3c85..7b654a0 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1013,27 +1013,19 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[],
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
{
struct bonding *bond = bond_get_bond_by_slave(slave);
- u16 vlan_id;
- int i;
-
- for (i = 0; i < MAX_LP_BURST; i++) {
- vlan_id = 0;
-
- if (bond_vlan_used(bond)) {
- struct vlan_entry *vlan;
+ struct netdev_upper *upper;
- vlan = bond_next_vlan(bond,
- bond->alb_info.current_alb_vlan);
-
- bond->alb_info.current_alb_vlan = vlan;
- if (!vlan)
- continue;
-
- vlan_id = vlan->vlan_id;
- }
+ /* send untagged */
+ alb_send_lp_vid(slave, mac_addr, 0);
- alb_send_lp_vid(slave, mac_addr, vlan_id);
+ /* loop through vlans and send one packet for each */
+ rcu_read_lock();
+ list_for_each_entry_rcu(upper, &bond->dev->upper_dev_list, list) {
+ if (upper->dev->priv_flags & IFF_802_1Q_VLAN)
+ alb_send_lp_vid(slave, mac_addr,
+ vlan_dev_vlan_id(upper->dev));
}
+ rcu_read_unlock();
}
static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index e7a5b8b..e139172 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -53,7 +53,6 @@ struct slave;
#define TLB_NULL_INDEX 0xffffffff
-#define MAX_LP_BURST 3
/* rlb defs */
#define RLB_HASH_TABLE_SIZE 256
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH net-next 8/8] bonding: remove vlan_list/current_alb_vlan
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
` (6 preceding siblings ...)
2013-08-26 16:28 ` [PATCH net-next 7/8] bonding: make alb_send_learning_packets() use upper dev list Veaceslav Falico
@ 2013-08-26 16:28 ` Veaceslav Falico
2013-08-26 20:33 ` [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:28 UTC (permalink / raw)
To: netdev; +Cc: Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
Currently there are no real users of vlan_list/current_alb_vlan, only the
helpers which maintain them, so remove them.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
drivers/net/bonding/bond_alb.c | 5 --
drivers/net/bonding/bond_alb.h | 1 -
drivers/net/bonding/bond_main.c | 133 +--------------------------------------
drivers/net/bonding/bonding.h | 6 --
4 files changed, 2 insertions(+), 143 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 7b654a0..98bb7fc 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1762,11 +1762,6 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
{
- if (bond->alb_info.current_alb_vlan &&
- (bond->alb_info.current_alb_vlan->vlan_id == vlan_id)) {
- bond->alb_info.current_alb_vlan = NULL;
- }
-
if (bond->alb_info.rlb_enabled) {
rlb_clear_vlan(bond, vlan_id);
}
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index e139172..e02c9c5 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -169,7 +169,6 @@ struct alb_bond_info {
* rx traffic should be
* rebalanced
*/
- struct vlan_entry *current_alb_vlan;
};
int bond_alb_initialize(struct bonding *bond, int rlb_enabled);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 9af37e6..4c9ec08 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -283,116 +283,6 @@ const char *bond_mode_name(int mode)
/*---------------------------------- VLAN -----------------------------------*/
/**
- * bond_add_vlan - add a new vlan id on bond
- * @bond: bond that got the notification
- * @vlan_id: the vlan id to add
- *
- * Returns -ENOMEM if allocation failed.
- */
-static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
-{
- struct vlan_entry *vlan;
-
- pr_debug("bond: %s, vlan id %d\n",
- (bond ? bond->dev->name : "None"), vlan_id);
-
- vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL);
- if (!vlan)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&vlan->vlan_list);
- vlan->vlan_id = vlan_id;
-
- write_lock_bh(&bond->lock);
-
- list_add_tail(&vlan->vlan_list, &bond->vlan_list);
-
- write_unlock_bh(&bond->lock);
-
- pr_debug("added VLAN ID %d on bond %s\n", vlan_id, bond->dev->name);
-
- return 0;
-}
-
-/**
- * bond_del_vlan - delete a vlan id from bond
- * @bond: bond that got the notification
- * @vlan_id: the vlan id to delete
- *
- * returns -ENODEV if @vlan_id was not found in @bond.
- */
-static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
-{
- struct vlan_entry *vlan;
- int res = -ENODEV;
-
- pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id);
-
- block_netpoll_tx();
- write_lock_bh(&bond->lock);
-
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- if (vlan->vlan_id == vlan_id) {
- list_del(&vlan->vlan_list);
-
- if (bond_is_lb(bond))
- bond_alb_clear_vlan(bond, vlan_id);
-
- pr_debug("removed VLAN ID %d from bond %s\n",
- vlan_id, bond->dev->name);
-
- kfree(vlan);
-
- res = 0;
- goto out;
- }
- }
-
- pr_debug("couldn't find VLAN ID %d in bond %s\n",
- vlan_id, bond->dev->name);
-
-out:
- write_unlock_bh(&bond->lock);
- unblock_netpoll_tx();
- return res;
-}
-
-/**
- * bond_next_vlan - safely skip to the next item in the vlans list.
- * @bond: the bond we're working on
- * @curr: item we're advancing from
- *
- * Returns %NULL if list is empty, bond->next_vlan if @curr is %NULL,
- * or @curr->next otherwise (even if it is @curr itself again).
- *
- * Caller must hold bond->lock
- */
-struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
-{
- struct vlan_entry *next, *last;
-
- if (list_empty(&bond->vlan_list))
- return NULL;
-
- if (!curr) {
- next = list_entry(bond->vlan_list.next,
- struct vlan_entry, vlan_list);
- } else {
- last = list_entry(bond->vlan_list.prev,
- struct vlan_entry, vlan_list);
- if (last == curr) {
- next = list_entry(bond->vlan_list.next,
- struct vlan_entry, vlan_list);
- } else {
- next = list_entry(curr->vlan_list.next,
- struct vlan_entry, vlan_list);
- }
- }
-
- return next;
-}
-
-/**
* bond_dev_queue_xmit - Prepare skb for xmit.
*
* @bond: bond device that got this skb for tx.
@@ -451,13 +341,6 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev,
goto unwind;
}
- res = bond_add_vlan(bond, vid);
- if (res) {
- pr_err("%s: Error: Failed to add vlan id %d\n",
- bond_dev->name, vid);
- goto unwind;
- }
-
return 0;
unwind:
@@ -478,17 +361,12 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave;
- int res;
bond_for_each_slave(bond, slave)
vlan_vid_del(slave->dev, proto, vid);
- res = bond_del_vlan(bond, vid);
- if (res) {
- pr_err("%s: Error: Failed to remove vlan id %d\n",
- bond_dev->name, vid);
- return res;
- }
+ if (bond_is_lb(bond))
+ bond_alb_clear_vlan(bond, vid);
return 0;
}
@@ -4120,7 +3998,6 @@ static void bond_setup(struct net_device *bond_dev)
/* Initialize pointers */
bond->dev = bond_dev;
- INIT_LIST_HEAD(&bond->vlan_list);
/* Initialize the device entry points */
ether_setup(bond_dev);
@@ -4173,7 +4050,6 @@ static void bond_uninit(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *tmp_slave;
- struct vlan_entry *vlan, *tmp;
bond_netpoll_cleanup(bond_dev);
@@ -4185,11 +4061,6 @@ static void bond_uninit(struct net_device *bond_dev)
list_del(&bond->bond_list);
bond_debug_unregister(bond);
-
- list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) {
- list_del(&vlan->vlan_list);
- kfree(vlan);
- }
}
/*------------------------- Module initialization ---------------------------*/
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 5ebb3d8..1675440 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -185,11 +185,6 @@ struct bond_parm_tbl {
#define BOND_MAX_MODENAME_LEN 20
-struct vlan_entry {
- struct list_head vlan_list;
- unsigned short vlan_id;
-};
-
struct slave {
struct net_device *dev; /* first - useful for panic debug */
struct list_head list;
@@ -254,7 +249,6 @@ struct bonding {
struct ad_bond_info ad_info;
struct alb_bond_info alb_info;
struct bond_params params;
- struct list_head vlan_list;
struct workqueue_struct *wq;
struct delayed_work mii_work;
struct delayed_work arp_work;
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH net-next 1/8] net: move netdev_upper to netdevice.h
2013-08-26 16:28 ` [PATCH net-next 1/8] net: move netdev_upper to netdevice.h Veaceslav Falico
@ 2013-08-26 16:41 ` Jiri Pirko
2013-08-26 16:55 ` Veaceslav Falico
0 siblings, 1 reply; 14+ messages in thread
From: Jiri Pirko @ 2013-08-26 16:41 UTC (permalink / raw)
To: Veaceslav Falico
Cc: netdev, David S. Miller, Eric Dumazet, Alexander Duyck, Cong Wang
Mon, Aug 26, 2013 at 06:28:46PM CEST, vfalico@redhat.com wrote:
>So that any device can work with it to see its upper/master devices. It is
>rcu'd and rtnl_lock protected, so one should either hold the rtnl_lock() or
>to use the _rcu() functions for it.
>
>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>
>---
> include/linux/netdevice.h | 8 ++++++++
> net/core/dev.c | 8 --------
> 2 files changed, 8 insertions(+), 8 deletions(-)
>
>diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>index 077363d..8cc7f43 100644
>--- a/include/linux/netdevice.h
>+++ b/include/linux/netdevice.h
>@@ -2764,6 +2764,14 @@ extern int netdev_tstamp_prequeue;
> extern int weight_p;
> extern int bpf_jit_enable;
>
>+struct netdev_upper {
>+ struct net_device *dev;
>+ bool master;
>+ struct list_head list;
>+ struct rcu_head rcu;
>+ struct list_head search_list;
>+};
>+
I like your patchset. However I'm not entirely comfortable with exposing
this struct. I would love to have it "under control" in net/core/dev.c
I'm thinking of some getter/iterator for this use. It can work by
type as well so you would be able to remove the checks from bonding
code.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next 1/8] net: move netdev_upper to netdevice.h
2013-08-26 16:41 ` Jiri Pirko
@ 2013-08-26 16:55 ` Veaceslav Falico
2013-08-26 17:38 ` Jiri Pirko
0 siblings, 1 reply; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 16:55 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, David S. Miller, Eric Dumazet, Alexander Duyck, Cong Wang
On Mon, Aug 26, 2013 at 06:41:15PM +0200, Jiri Pirko wrote:
>Mon, Aug 26, 2013 at 06:28:46PM CEST, vfalico@redhat.com wrote:
...snip...
>>+struct netdev_upper {
>>+ struct net_device *dev;
>>+ bool master;
>>+ struct list_head list;
>>+ struct rcu_head rcu;
>>+ struct list_head search_list;
>>+};
>>+
>
>
>I like your patchset. However I'm not entirely comfortable with exposing
>this struct. I would love to have it "under control" in net/core/dev.c
I've taken this approach first, however the change to non-bonding stuff
became a bit too big to justify the (only) bonding use.
bonding only reads from it, and there are already primitives in dev.c to
modify it, so if they will be used for it it's still the dev.c who controls
it (if someone writes directly to it - it's a bug, and can be NAKed).
>
>I'm thinking of some getter/iterator for this use. It can work by
>type as well so you would be able to remove the checks from bonding
>code.
There are 3 checks in bonding - looking for vlan devs, for a specific dev
and for a specific ip address. list_for_each_entry() fits here perfectly
for each case, otherwise the best way to do this would be to
while ((next_dev = netdev_upper_get_next_dev(dev, next_dev)))
or something like that, which adds quite a bit of overhead (looking for the
previous dev and then returning the next one on each iteration), and looks
ugly.
So, given that it's a plain list actually, and any modification to this
list can (and should be) done via functions from dev.c, while reading can
be done with standard list_for_each_entry(_rcu)(), I think it's better to
expose it this way.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next 1/8] net: move netdev_upper to netdevice.h
2013-08-26 16:55 ` Veaceslav Falico
@ 2013-08-26 17:38 ` Jiri Pirko
2013-08-26 18:10 ` Veaceslav Falico
0 siblings, 1 reply; 14+ messages in thread
From: Jiri Pirko @ 2013-08-26 17:38 UTC (permalink / raw)
To: Veaceslav Falico
Cc: netdev, David S. Miller, Eric Dumazet, Alexander Duyck, Cong Wang
Mon, Aug 26, 2013 at 06:55:35PM CEST, vfalico@redhat.com wrote:
>On Mon, Aug 26, 2013 at 06:41:15PM +0200, Jiri Pirko wrote:
>>Mon, Aug 26, 2013 at 06:28:46PM CEST, vfalico@redhat.com wrote:
>...snip...
>>>+struct netdev_upper {
>>>+ struct net_device *dev;
>>>+ bool master;
>>>+ struct list_head list;
>>>+ struct rcu_head rcu;
>>>+ struct list_head search_list;
>>>+};
>>>+
>>
>>
>>I like your patchset. However I'm not entirely comfortable with exposing
>>this struct. I would love to have it "under control" in net/core/dev.c
>
>I've taken this approach first, however the change to non-bonding stuff
>became a bit too big to justify the (only) bonding use.
>
>bonding only reads from it, and there are already primitives in dev.c to
>modify it, so if they will be used for it it's still the dev.c who controls
>it (if someone writes directly to it - it's a bug, and can be NAKed).
>
>>
>>I'm thinking of some getter/iterator for this use. It can work by
>>type as well so you would be able to remove the checks from bonding
>>code.
>
>There are 3 checks in bonding - looking for vlan devs, for a specific dev
>and for a specific ip address. list_for_each_entry() fits here perfectly
>for each case, otherwise the best way to do this would be to
>
>while ((next_dev = netdev_upper_get_next_dev(dev, next_dev)))
I was imagine something like:
struct list_head *iter;
struct net_device *dev, *upper;
netdev_for_each_upper_dev(dev, upper, iter) {
}
This macro can be easily implented using netdev_upper_get_next_dev()
from dev.c
Not much of added overhead other than netdev_upper_get_next_dev calls
(without any search when using list_head iter).
>
>or something like that, which adds quite a bit of overhead (looking for the
>previous dev and then returning the next one on each iteration), and looks
>ugly.
>
>So, given that it's a plain list actually, and any modification to this
>list can (and should be) done via functions from dev.c, while reading can
>be done with standard list_for_each_entry(_rcu)(), I think it's better to
>expose it this way.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next 1/8] net: move netdev_upper to netdevice.h
2013-08-26 17:38 ` Jiri Pirko
@ 2013-08-26 18:10 ` Veaceslav Falico
0 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 18:10 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, David S. Miller, Eric Dumazet, Alexander Duyck, Cong Wang
On Mon, Aug 26, 2013 at 07:38:44PM +0200, Jiri Pirko wrote:
>I was imagine something like:
>
>struct list_head *iter;
>struct net_device *dev, *upper;
>
>netdev_for_each_upper_dev(dev, upper, iter) {
>
>}
>
>This macro can be easily implented using netdev_upper_get_next_dev()
>from dev.c
>
>Not much of added overhead other than netdev_upper_get_next_dev calls
>(without any search when using list_head iter).
Great idea, didn't think of it.
Thanks a lot, will try implement it and send v2.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH net-next 0/8] bonding: remove vlan special handling
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
` (7 preceding siblings ...)
2013-08-26 16:28 ` [PATCH net-next 8/8] bonding: remove vlan_list/current_alb_vlan Veaceslav Falico
@ 2013-08-26 20:33 ` Veaceslav Falico
8 siblings, 0 replies; 14+ messages in thread
From: Veaceslav Falico @ 2013-08-26 20:33 UTC (permalink / raw)
To: netdev
Cc: Jay Vosburgh, Andy Gospodarek, David S. Miller, Eric Dumazet,
Jiri Pirko, Alexander Duyck, Cong Wang
On Mon, Aug 26, 2013 at 06:28:45PM +0200, Veaceslav Falico wrote:
>The aim of this patchset is to remove bondings' own vlan handling as much
>as possible and replace it with the netdev upper device functionality.
>
>This is achieved by exporting the netdev_upper structure and thus permiting
>bonding to work directly with its upper devices. The only non-bonding
>change is the exporting of netdev_upper, and the only special treatment of
>vlans left is in the rlb mode.
>
>This patchset solves several issues with bonding, simplifies it overall,
>RCUify further and exports netdev_upper for any other users which might
>also want to get rid of its own vlan_lists.
>
>I'm testing it continuously currently, no issues found, will update on
>anything.
Self-NAK on the whole series, changed the upper device management approach,
as suggested by Jiri, and sent the new version.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-08-26 20:35 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-26 16:28 [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 1/8] net: move netdev_upper to netdevice.h Veaceslav Falico
2013-08-26 16:41 ` Jiri Pirko
2013-08-26 16:55 ` Veaceslav Falico
2013-08-26 17:38 ` Jiri Pirko
2013-08-26 18:10 ` Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 2/8] bonding: use netdev_upper list in bond_vlan_used Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 3/8] bonding: make bond_arp_send_all use upper device list Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 4/8] bonding: convert bond_has_this_ip() to use upper devices Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 5/8] bonding: use vlan_uses_dev() in __bond_release_one() Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 6/8] bonding: split alb_send_learning_packets() Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 7/8] bonding: make alb_send_learning_packets() use upper dev list Veaceslav Falico
2013-08-26 16:28 ` [PATCH net-next 8/8] bonding: remove vlan_list/current_alb_vlan Veaceslav Falico
2013-08-26 20:33 ` [PATCH net-next 0/8] bonding: remove vlan special handling Veaceslav Falico
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).