* Re: [PATCH 3/5] net/mlx4_en: Call netif_carrier_off() after register_netdev()
From: Ben Hutchings @ 2012-08-14 14:56 UTC (permalink / raw)
To: Sathya.Perla
Cc: shchepetkov, yevgenyp, davem, amirv, ogerlitz, alexg, netdev,
linux-kernel, ldv-project
In-Reply-To: <CF9D1877D81D214CB0CA0669EFAE020C066A09@CMEXMB1.ad.emulex.com>
On Tue, 2012-08-14 at 12:36 +0000, Sathya.Perla@Emulex.Com wrote:
> >-----Original Message-----
> >From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
> >Behalf Of Ilya Shchepetkov
> >
> >For carrier detection to work properly when binding the driver with a
> >cable unplugged, netif_carrier_off() should be called after
> >register_netdev(), not before.
> >
> >Calling netif_carrier_off() before register_netdev() was causing the
> >network interface to miss a linkwatch pending event leading to an
> >inconsistent state if the link is not up when interface is initialized.
>
> ndo_open() may be called as soon register_netdev() completes...
> When netif_carrier_off() is called *after* register_netdev(), isn't there
> a possibility of a ndo_open()->netif_carrier_on() call racing this call, causing
> incorrect results?
Yes, you should use something like:
rtnl_lock();
rc = register_netdevice(dev);
if (rc)
goto out_unlock;
netif_carrier_off(dev);
rtnl_unlock();
(Why do we even have register_netdev() when it's such an invitation to
races?)
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [patch net-next v2 00/15] net: introduce upper device lists and remove dev->master
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, edumazet-hpIqsD4AKlfQT0dZR+AlfA,
faisal.latif-ral2JQCrhuEAvxtiuMwx3w,
roland-DgEjT+Ai2ygdnm+yROfE0A, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
fubar-r/Jw6+rmf7HQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
divy-ut6Up61K2wZBDgjK7y7TUQ,
jitendra.kalsaria-h88ZbnxC6KDQT0dZR+AlfA,
sony.chacko-h88ZbnxC6KDQT0dZR+AlfA,
linux-driver-h88ZbnxC6KDQT0dZR+AlfA, kaber-dcUjhNyLwpNeoWH0uzbU5w,
ursula.braun-tA70FqPdS9bQT0dZR+AlfA,
blaschka-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
linux390-tA70FqPdS9bQT0dZR+AlfA,
shemminger-ZtmgI6mnKB3QT0dZR+AlfA,
bhutchings-s/n/eUQHGBpZroRs9YW3xA,
therbert-hpIqsD4AKlfQT0dZR+AlfA,
xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w, joe-6d6DIl74uiNBDgjK7y7TUQ,
gregory.v.rose-ral2JQCrhuEAvxtiuMwx3w,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-s390-u79uwXL29TY76Z2rM5mHXA,
bridge-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
fbl-H+wXaHxf7aLQT0dZR+AlfA
Hi all.
Recent discussion around
"[net-next] bonding: don't allow the master to become its slave"
forced me to think about upper<->lower device connections.
This patchset adds a possibility to record upper device linkage.
All upper<->lower devices are converted to use this mechanism right after.
That leads to dev->master removal because this info becomes redundant since
"unique links" have the same value.
After all changes, there is no longer possible to do:
"bond->someotherdevice->samebond"
Also I think that drivers like cxgb3, qlcnic, qeth would benefit by this
in future by being able to get more appropriate info about l3 addresses.
v1->v2:
- s/unique/master/ better naming + stays closer to the history
- fixed vlan err goto
- original patch 15 (WARN_ON change) is squashed into the first patch
- fixed netdev_unique_upper_dev_get_rcu() case of upper==NULL
Jiri Pirko (15):
net: introduce upper device lists
macvlan: add link to upper device
vlan: add link to upper device
rtnetlink: remove usage of dev->master
team: remove usage of netdev_set_master()
bridge: remove usage of netdev_set_master()
netpoll: remove usage of dev->master
cxgb3: remove usage of dev->master
qlcnic: guard __vlan_find_dev_deep() by rcu_read_lock
qeth: ensure that __vlan_find_dev_deep() is called with rcu_read_lock
vlan: remove usage of dev->master in __vlan_find_dev_deep()
nes: remove usage of dev->master
bonding: remove usage of dev->master
net: remove no longer used netdev_set_bond_master() and
netdev_set_master()
net: kill dev->master
drivers/infiniband/hw/nes/nes.c | 8 +-
drivers/infiniband/hw/nes/nes_cm.c | 2 +-
drivers/net/bonding/bond_3ad.c | 30 +--
drivers/net/bonding/bond_alb.c | 6 +-
drivers/net/bonding/bond_main.c | 94 ++++----
drivers/net/bonding/bonding.h | 14 +-
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 11 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +
drivers/net/macvlan.c | 9 +-
drivers/net/team/team.c | 13 +-
drivers/s390/net/qeth_l3_main.c | 21 +-
include/linux/netdevice.h | 22 +-
net/8021q/vlan.c | 10 +-
net/8021q/vlan_core.c | 18 +-
net/bridge/br_if.c | 6 +-
net/core/dev.c | 239 +++++++++++++++++---
net/core/netpoll.c | 8 +-
net/core/rtnetlink.c | 45 ++--
18 files changed, 391 insertions(+), 167 deletions(-)
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [patch net-next v2 01/15] net: introduce upper device lists
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
This lists are supposed to serve for storing pointers to all upper devices.
Eventually it will replace dev->master pointer which is used for
bonding, bridge, team but it cannot be used for vlan, macvlan where
there might be multiple upper present. In case the upper link is
replacement for dev->master, it is marked with "master" flag.
New upper device list resolves this limitation. Also, the information
stored in lists is used for preventing looping setups like
"bond->somethingelse->samebond"
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
include/linux/netdevice.h | 14 +++
net/core/dev.c | 236 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 246 insertions(+), 4 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a9db4f3..95345d4 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1173,6 +1173,8 @@ struct net_device {
* which this device is member of.
*/
+ struct list_head upper_dev_list; /* List of upper devices */
+
/* Interface address info used in eth_type_trans() */
unsigned char *dev_addr; /* hw address, (before bcast
because most packets are
@@ -2611,6 +2613,18 @@ extern int netdev_max_backlog;
extern int netdev_tstamp_prequeue;
extern int weight_p;
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_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,
+ struct net_device *upper_dev);
+extern int netdev_master_upper_dev_link(struct net_device *dev,
+ struct net_device *upper_dev);
+extern void netdev_upper_dev_unlink(struct net_device *dev,
+ struct net_device *upper_dev);
extern int netdev_set_master(struct net_device *dev, struct net_device *master);
extern int netdev_set_bond_master(struct net_device *dev,
struct net_device *master);
diff --git a/net/core/dev.c b/net/core/dev.c
index 1f06df8..d7fd235 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4425,6 +4425,229 @@ static int __init dev_proc_init(void)
#endif /* CONFIG_PROC_FS */
+struct netdev_upper {
+ struct net_device *dev;
+ bool master;
+ struct list_head list;
+ struct rcu_head rcu;
+};
+
+static bool __netdev_has_upper_dev(struct net_device *dev,
+ struct net_device *upper_dev,
+ bool deep)
+{
+ struct netdev_upper *upper;
+
+ list_for_each_entry(upper, &dev->upper_dev_list, list) {
+ if (upper->dev == upper_dev)
+ return true;
+ if (deep && __netdev_has_upper_dev(upper->dev, upper_dev, deep))
+ return true;
+ }
+ return false;
+}
+
+static struct netdev_upper *__netdev_find_upper(struct net_device *dev,
+ struct net_device *upper_dev)
+{
+ struct netdev_upper *upper;
+
+ list_for_each_entry(upper, &dev->upper_dev_list, list) {
+ if (upper->dev == upper_dev)
+ return upper;
+ }
+ return NULL;
+}
+
+/**
+ * netdev_has_upper_dev - Check if device is linked to an upper device
+ * @dev: device
+ * @upper_dev: upper device to check
+ *
+ * Find out if a device is linked to specified upper device and return true
+ * in case it is. The caller must hold the RTNL semaphore.
+ */
+bool netdev_has_upper_dev(struct net_device *dev,
+ struct net_device *upper_dev)
+{
+ ASSERT_RTNL();
+
+ return __netdev_has_upper_dev(dev, upper_dev, false);
+}
+EXPORT_SYMBOL(netdev_has_upper_dev);
+
+/**
+ * netdev_has_any_upper_dev - Check if device is linked to some device
+ * @dev: device
+ *
+ * Find out if a device is linked to an upper device and return true in case
+ * it is. The caller must hold the RTNL semaphore.
+ */
+bool netdev_has_any_upper_dev(struct net_device *dev)
+{
+ ASSERT_RTNL();
+
+ return !list_empty(&dev->upper_dev_list);
+}
+EXPORT_SYMBOL(netdev_has_any_upper_dev);
+
+/**
+ * netdev_master_upper_dev_get - Get master upper device
+ * @dev: device
+ *
+ * Find a master upper device and return pointer to it or NULL in case
+ * it's not there. The caller must hold the RTNL semaphore.
+ */
+struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
+{
+ struct netdev_upper *upper;
+
+ ASSERT_RTNL();
+
+ if (list_empty(&dev->upper_dev_list))
+ return NULL;
+
+ upper = list_first_entry(&dev->upper_dev_list,
+ struct netdev_upper, list);
+ if (likely(upper->master))
+ return upper->dev;
+ return NULL;
+}
+EXPORT_SYMBOL(netdev_master_upper_dev_get);
+
+/**
+ * netdev_master_upper_dev_get_rcu - Get master upper device
+ * @dev: device
+ *
+ * Find a master upper device and return pointer to it or NULL in case
+ * it's not there. The caller must hold the RCU read lock.
+ */
+struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev)
+{
+ struct netdev_upper *upper;
+
+ upper = list_first_or_null_rcu(&dev->upper_dev_list,
+ struct netdev_upper, list);
+ if (upper && likely(upper->master))
+ return upper->dev;
+ return NULL;
+}
+EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);
+
+static int __netdev_upper_dev_link(struct net_device *dev,
+ struct net_device *upper_dev, bool master)
+{
+ struct netdev_upper *upper;
+
+ ASSERT_RTNL();
+
+ if (dev == upper_dev)
+ return -EBUSY;
+ /*
+ * To prevent loops, check if dev is not upper device to upper_dev.
+ */
+ if (__netdev_has_upper_dev(upper_dev, dev, true))
+ return -EBUSY;
+
+ if (__netdev_find_upper(dev, upper_dev))
+ return -EEXIST;
+
+ if (master && netdev_master_upper_dev_get(dev))
+ return -EBUSY;
+
+ upper = kmalloc(sizeof(*upper), GFP_KERNEL);
+ if (!upper)
+ return -ENOMEM;
+
+ upper->dev = upper_dev;
+ upper->master = master;
+
+ /*
+ * Ensure that master upper link is always the first item in the list.
+ */
+ if (master)
+ list_add_rcu(&upper->list, &dev->upper_dev_list);
+ else
+ list_add_tail_rcu(&upper->list, &dev->upper_dev_list);
+ dev_hold(upper_dev);
+
+ return 0;
+}
+/**
+ * netdev_upper_dev_link - Add a link to the upper device
+ * @dev: device
+ * @upper_dev: new upper device
+ *
+ * Adds a link to device which is upper to this one. The caller must hold
+ * the RTNL semaphore. On a failure a negative errno code is returned.
+ * On success the reference counts are adjusted and the function
+ * returns zero.
+ */
+int netdev_upper_dev_link(struct net_device *dev,
+ struct net_device *upper_dev)
+{
+ return __netdev_upper_dev_link(dev, upper_dev, false);
+}
+EXPORT_SYMBOL(netdev_upper_dev_link);
+
+/**
+ * netdev_master_upper_dev_link - Add a master link to the upper device
+ * @dev: device
+ * @upper_dev: new upper device
+ *
+ * Adds a link to device which is upper to this one. In this case, only
+ * one master upper device can be linked, although other non-master devices
+ * might be linked as well. The caller must hold the RTNL semaphore.
+ * On a failure a negative errno code is returned. On success the reference
+ * counts are adjusted and the function returns zero.
+ */
+int netdev_master_upper_dev_link(struct net_device *dev,
+ struct net_device *upper_dev)
+{
+ return __netdev_upper_dev_link(dev, upper_dev, true);
+}
+EXPORT_SYMBOL(netdev_master_upper_dev_link);
+
+/**
+ * netdev_upper_free_rcu - Frees a upper device list item via the RCU pointer
+ * @entry: the entry's RCU field
+ *
+ * This function is designed to be used as a callback to the call_rcu()
+ * function so that the memory allocated to the netdev upper device list item
+ * can be released safely.
+ */
+static void netdev_upper_free_rcu(struct rcu_head *entry)
+{
+ struct netdev_upper *upper;
+
+ upper = container_of(entry, struct netdev_upper, rcu);
+ kfree(upper);
+}
+
+/**
+ * netdev_upper_dev_unlink - Removes a link to upper device
+ * @dev: device
+ * @upper_dev: new upper device
+ *
+ * Removes a link to device which is upper to this one. The caller must hold
+ * the RTNL semaphore.
+ */
+void netdev_upper_dev_unlink(struct net_device *dev,
+ struct net_device *upper_dev)
+{
+ struct netdev_upper *upper;
+
+ ASSERT_RTNL();
+
+ upper = __netdev_find_upper(dev, upper_dev);
+ if (!upper)
+ return;
+ list_del_rcu(&upper->list);
+ dev_put(upper_dev);
+ call_rcu(&upper->rcu, netdev_upper_free_rcu);
+}
+EXPORT_SYMBOL(netdev_upper_dev_unlink);
+
/**
* netdev_set_master - set up master pointer
* @slave: slave device
@@ -4438,19 +4661,23 @@ static int __init dev_proc_init(void)
int netdev_set_master(struct net_device *slave, struct net_device *master)
{
struct net_device *old = slave->master;
+ int err;
ASSERT_RTNL();
if (master) {
if (old)
return -EBUSY;
- dev_hold(master);
+ err = netdev_master_upper_dev_link(slave, master);
+ if (err)
+ return err;
}
slave->master = master;
if (old)
- dev_put(old);
+ netdev_upper_dev_unlink(slave, master);
+
return 0;
}
EXPORT_SYMBOL(netdev_set_master);
@@ -5297,8 +5524,8 @@ static void rollback_registered_many(struct list_head *head)
if (dev->netdev_ops->ndo_uninit)
dev->netdev_ops->ndo_uninit(dev);
- /* Notifier chain MUST detach us from master device. */
- WARN_ON(dev->master);
+ /* Notifier chain MUST detach us all upper devices. */
+ WARN_ON(netdev_has_any_upper_dev(dev));
/* Remove entries from kobject tree */
netdev_unregister_kobject(dev);
@@ -5999,6 +6226,7 @@ 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);
dev->priv_flags = IFF_XMIT_DST_RELEASE;
setup(dev);
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 02/15] macvlan: add link to upper device
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/macvlan.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 66a9bfe..f5bd8a2 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -765,16 +765,22 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN);
}
+ err = netdev_upper_dev_link(lowerdev, dev);
+ if (err)
+ goto destroy_port;
+
port->count += 1;
err = register_netdevice(dev);
if (err < 0)
- goto destroy_port;
+ goto upper_dev_unlink;
list_add_tail(&vlan->list, &port->vlans);
netif_stacked_transfer_operstate(lowerdev, dev);
return 0;
+upper_dev_unlink:
+ netdev_upper_dev_unlink(lowerdev, dev);
destroy_port:
port->count -= 1;
if (!port->count)
@@ -798,6 +804,7 @@ void macvlan_dellink(struct net_device *dev, struct list_head *head)
list_del(&vlan->list);
unregister_netdevice_queue(dev, head);
+ netdev_upper_dev_unlink(vlan->lowerdev, dev);
}
EXPORT_SYMBOL_GPL(macvlan_dellink);
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 05/15] team: remove usage of netdev_set_master()
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/team/team.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index ba10c46..dabddc5 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1040,10 +1040,11 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
}
}
- err = netdev_set_master(port_dev, dev);
+ err = netdev_master_upper_dev_link(port_dev, dev);
if (err) {
- netdev_err(dev, "Device %s failed to set master\n", portname);
- goto err_set_master;
+ netdev_err(dev, "Device %s failed to set upper link\n",
+ portname);
+ goto err_set_upper_link;
}
err = netdev_rx_handler_register(port_dev, team_handle_frame,
@@ -1076,9 +1077,9 @@ err_option_port_add:
netdev_rx_handler_unregister(port_dev);
err_handler_register:
- netdev_set_master(port_dev, NULL);
+ netdev_upper_dev_unlink(port_dev, dev);
-err_set_master:
+err_set_upper_link:
team_port_disable_netpoll(port);
err_enable_netpoll:
@@ -1121,7 +1122,7 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
team_port_disable(team, port);
list_del_rcu(&port->list);
netdev_rx_handler_unregister(port_dev);
- netdev_set_master(port_dev, NULL);
+ netdev_upper_dev_unlink(port_dev, dev);
team_port_disable_netpoll(port);
vlan_vids_del_by_dev(port_dev, dev);
dev_close(port_dev);
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 06/15] bridge: remove usage of netdev_set_master()
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/bridge/br_if.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index e1144e1..8bea645 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -148,7 +148,7 @@ static void del_nbp(struct net_bridge_port *p)
netdev_rx_handler_unregister(dev);
synchronize_net();
- netdev_set_master(dev, NULL);
+ netdev_upper_dev_unlink(dev, br->dev);
br_multicast_del_port(p);
@@ -364,7 +364,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
if (br_netpoll_info(br) && ((err = br_netpoll_enable(p))))
goto err3;
- err = netdev_set_master(dev, br->dev);
+ err = netdev_master_upper_dev_link(dev, br->dev);
if (err)
goto err3;
@@ -403,7 +403,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
return 0;
err4:
- netdev_set_master(dev, NULL);
+ netdev_upper_dev_unlink(dev, br->dev);
err3:
sysfs_remove_link(br->ifobj, p->dev->name);
err2:
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 07/15] netpoll: remove usage of dev->master
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/core/netpoll.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b4c90e4..1f457a6 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -207,12 +207,16 @@ static void netpoll_poll_dev(struct net_device *dev)
if (dev->flags & IFF_SLAVE) {
if (dev->npinfo) {
- struct net_device *bond_dev = dev->master;
+ struct net_device *bond_dev;
struct sk_buff *skb;
+
+ rcu_read_lock();
+ bond_dev = netdev_master_upper_dev_get_rcu(dev);
while ((skb = skb_dequeue(&dev->npinfo->arp_tx))) {
skb->dev = bond_dev;
skb_queue_tail(&bond_dev->npinfo->arp_tx, skb);
}
+ rcu_read_unlock();
}
}
@@ -795,7 +799,7 @@ int netpoll_setup(struct netpoll *np)
return -ENODEV;
}
- if (ndev->master) {
+ if (netdev_master_upper_dev_get(ndev)) {
np_err(np, "%s is a slave device, aborting\n", np->dev_name);
err = -EBUSY;
goto put;
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 08/15] cxgb3: remove usage of dev->master
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 2dbbcbb..720425d 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -182,14 +182,17 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter,
struct net_device *dev = adapter->port[i];
if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) {
+ rcu_read_lock();
if (vlan && vlan != VLAN_VID_MASK) {
- rcu_read_lock();
dev = __vlan_find_dev_deep(dev, vlan);
- rcu_read_unlock();
} else if (netif_is_bond_slave(dev)) {
- while (dev->master)
- dev = dev->master;
+ struct net_device *upper_dev;
+
+ while ((upper_dev =
+ netdev_master_upper_dev_get_rcu(dev)))
+ dev = upper_dev;
}
+ rcu_read_unlock();
return dev;
}
}
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 09/15] qlcnic: guard __vlan_find_dev_deep() by rcu_read_lock
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
rcu_read_lock was missing here
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 212c121..9eadf17 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -4425,12 +4425,14 @@ qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event)
qlcnic_config_indev_addr(adapter, netdev, event);
+ rcu_read_lock();
for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) {
dev = __vlan_find_dev_deep(netdev, vid);
if (!dev)
continue;
qlcnic_config_indev_addr(adapter, dev, event);
}
+ rcu_read_unlock();
}
static int qlcnic_netdev_event(struct notifier_block *this,
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 10/15] qeth: ensure that __vlan_find_dev_deep() is called with rcu_read_lock
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Also benefit from rcu_read_lock held and use __in_dev_get_rcu() in ipv4 case.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/s390/net/qeth_l3_main.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index c5f03fa..6b3988b 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1638,6 +1638,7 @@ static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev)
}
}
+/* called with rcu_read_lock */
static void qeth_l3_add_vlan_mc(struct qeth_card *card)
{
struct in_device *in_dev;
@@ -1650,19 +1651,14 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card)
for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) {
struct net_device *netdev;
- rcu_read_lock();
netdev = __vlan_find_dev_deep(card->dev, vid);
- rcu_read_unlock();
if (netdev == NULL ||
!(netdev->flags & IFF_UP))
continue;
- in_dev = in_dev_get(netdev);
+ in_dev = __in_dev_get_rcu(netdev);
if (!in_dev)
continue;
- rcu_read_lock();
qeth_l3_add_mc(card, in_dev);
- rcu_read_unlock();
- in_dev_put(in_dev);
}
}
@@ -1671,14 +1667,14 @@ static void qeth_l3_add_multicast_ipv4(struct qeth_card *card)
struct in_device *in4_dev;
QETH_CARD_TEXT(card, 4, "chkmcv4");
- in4_dev = in_dev_get(card->dev);
- if (in4_dev == NULL)
- return;
rcu_read_lock();
+ in4_dev = __in_dev_get_rcu(card->dev);
+ if (in4_dev == NULL)
+ goto unlock;
qeth_l3_add_mc(card, in4_dev);
qeth_l3_add_vlan_mc(card);
+unlock:
rcu_read_unlock();
- in_dev_put(in4_dev);
}
#ifdef CONFIG_QETH_IPV6
@@ -1703,6 +1699,7 @@ static void qeth_l3_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
}
}
+/* called with rcu_read_lock */
static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
{
struct inet6_dev *in_dev;
@@ -1739,10 +1736,12 @@ static void qeth_l3_add_multicast_ipv6(struct qeth_card *card)
in6_dev = in6_dev_get(card->dev);
if (in6_dev == NULL)
return;
+ rcu_read_lock();
read_lock_bh(&in6_dev->lock);
qeth_l3_add_mc6(card, in6_dev);
qeth_l3_add_vlan_mc6(card);
read_unlock_bh(&in6_dev->lock);
+ rcu_read_unlock();
in6_dev_put(in6_dev);
}
#endif /* CONFIG_QETH_IPV6 */
@@ -1811,8 +1810,10 @@ static void qeth_l3_free_vlan_addresses6(struct qeth_card *card,
static void qeth_l3_free_vlan_addresses(struct qeth_card *card,
unsigned short vid)
{
+ rcu_read_lock();
qeth_l3_free_vlan_addresses4(card, vid);
qeth_l3_free_vlan_addresses6(card, vid);
+ rcu_read_unlock();
}
static int qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 11/15] vlan: remove usage of dev->master in __vlan_find_dev_deep()
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, edumazet-hpIqsD4AKlfQT0dZR+AlfA,
faisal.latif-ral2JQCrhuEAvxtiuMwx3w,
roland-DgEjT+Ai2ygdnm+yROfE0A, sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
fubar-r/Jw6+rmf7HQT0dZR+AlfA, andy-QlMahl40kYEqcZcGjlUOXw,
divy-ut6Up61K2wZBDgjK7y7TUQ,
jitendra.kalsaria-h88ZbnxC6KDQT0dZR+AlfA,
sony.chacko-h88ZbnxC6KDQT0dZR+AlfA,
linux-driver-h88ZbnxC6KDQT0dZR+AlfA, kaber-dcUjhNyLwpNeoWH0uzbU5w,
ursula.braun-tA70FqPdS9bQT0dZR+AlfA,
blaschka-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
linux390-tA70FqPdS9bQT0dZR+AlfA,
shemminger-ZtmgI6mnKB3QT0dZR+AlfA,
bhutchings-s/n/eUQHGBpZroRs9YW3xA,
therbert-hpIqsD4AKlfQT0dZR+AlfA,
xiyou.wangcong-Re5JQEeQqe8AvxtiuMwx3w, joe-6d6DIl74uiNBDgjK7y7TUQ,
gregory.v.rose-ral2JQCrhuEAvxtiuMwx3w,
john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-s390-u79uwXL29TY76Z2rM5mHXA,
bridge-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
fbl-H+wXaHxf7aLQT0dZR+AlfA
In-Reply-To: <1344956748-2099-1-git-send-email-jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
Also, since all users call __vlan_find_dev_deep() with rcu_read_lock,
make no possibility to call this with rtnl mutex held only.
Signed-off-by: Jiri Pirko <jiri-rHqAuBHg3fBzbRFIqnYvSA@public.gmane.org>
---
net/8021q/vlan_core.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 8ca533c..d4babc6 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -66,21 +66,25 @@ bool vlan_do_receive(struct sk_buff **skbp, bool last_handler)
return true;
}
-/* Must be invoked with rcu_read_lock or with RTNL. */
-struct net_device *__vlan_find_dev_deep(struct net_device *real_dev,
+/* Must be invoked with rcu_read_lock. */
+struct net_device *__vlan_find_dev_deep(struct net_device *dev,
u16 vlan_id)
{
- struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info);
+ struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info);
if (vlan_info) {
return vlan_group_get_device(&vlan_info->grp, vlan_id);
} else {
/*
- * Bonding slaves do not have grp assigned to themselves.
- * Grp is assigned to bonding master instead.
+ * Lower devices of master uppers (bonding, team) do not have
+ * grp assigned to themselves. Grp is assigned to upper device
+ * instead.
*/
- if (netif_is_bond_slave(real_dev))
- return __vlan_find_dev_deep(real_dev->master, vlan_id);
+ struct net_device *upper_dev;
+
+ upper_dev = netdev_master_upper_dev_get_rcu(dev);
+ if (upper_dev)
+ return __vlan_find_dev_deep(upper_dev, vlan_id);
}
return NULL;
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [patch net-next v2 12/15] nes: remove usage of dev->master
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/infiniband/hw/nes/nes.c | 8 +++++---
drivers/infiniband/hw/nes/nes_cm.c | 2 +-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 7140199..6686251 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -140,6 +140,7 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
struct net_device *event_netdev = ifa->ifa_dev->dev;
struct nes_device *nesdev;
struct net_device *netdev;
+ struct net_device *upper_dev;
struct nes_vnic *nesvnic;
unsigned int is_bonded;
@@ -150,8 +151,9 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
nesdev, nesdev->netdev[0]->name);
netdev = nesdev->netdev[0];
nesvnic = netdev_priv(netdev);
+ upper_dev = netdev_master_upper_dev_get(netdev);
is_bonded = netif_is_bond_slave(netdev) &&
- (netdev->master == event_netdev);
+ (upper_dev == event_netdev);
if ((netdev == event_netdev) || is_bonded) {
if (nesvnic->rdma_enabled == 0) {
nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since"
@@ -184,9 +186,9 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
/* fall through */
case NETDEV_CHANGEADDR:
/* Add the address to the IP table */
- if (netdev->master)
+ if (upper_dev)
nesvnic->local_ipaddr =
- ((struct in_device *)netdev->master->ip_ptr)->ifa_list->ifa_address;
+ ((struct in_device *)upper_dev->ip_ptr)->ifa_list->ifa_address;
else
nesvnic->local_ipaddr = ifa->ifa_address;
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 020e95c..15e6340 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1352,7 +1352,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
}
if (netif_is_bond_slave(nesvnic->netdev))
- netdev = nesvnic->netdev->master;
+ netdev = netdev_unique_upper_dev_get(nesvnic->netdev);
else
netdev = nesvnic->netdev;
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 13/15] bonding: remove usage of dev->master
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Benefit from new upper dev list and free bonding from dev->master usage.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/bonding/bond_3ad.c | 30 ++++++-------
drivers/net/bonding/bond_alb.c | 6 +--
drivers/net/bonding/bond_main.c | 94 +++++++++++++++++++++++----------------
drivers/net/bonding/bonding.h | 14 +++---
net/core/rtnetlink.c | 1 +
5 files changed, 81 insertions(+), 64 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index a030e63..84fabd6 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1127,7 +1127,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
// INFO_RECEIVED_LOOPBACK_FRAMES
pr_err("%s: An illegal loopback occurred on adapter (%s).\n"
"Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
- port->slave->dev->master->name, port->slave->dev->name);
+ port->slave->bond->dev->name, port->slave->dev->name);
return;
}
__update_selected(lacpdu, port);
@@ -1306,7 +1306,7 @@ static void ad_port_selection_logic(struct port *port)
}
if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n",
- port->slave->dev->master->name,
+ port->slave->bond->dev->name,
port->actor_port_number,
port->slave->dev->name,
port->aggregator->aggregator_identifier);
@@ -1386,7 +1386,7 @@ static void ad_port_selection_logic(struct port *port)
port->aggregator->aggregator_identifier);
} else {
pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n",
- port->slave->dev->master->name,
+ port->slave->bond->dev->name,
port->actor_port_number, port->slave->dev->name);
}
}
@@ -1463,7 +1463,7 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best,
default:
pr_warning("%s: Impossible agg select mode %d\n",
- curr->slave->dev->master->name,
+ curr->slave->bond->dev->name,
__get_agg_selection_mode(curr->lag_ports));
break;
}
@@ -1571,7 +1571,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
// check if any partner replys
if (best->is_individual) {
pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n",
- best->slave ? best->slave->dev->master->name : "NULL");
+ best->slave ? best->slave->bond->dev->name : "NULL");
}
best->is_active = 1;
@@ -1898,7 +1898,7 @@ int bond_3ad_bind_slave(struct slave *slave)
if (bond == NULL) {
pr_err("%s: The slave %s is not attached to its bond\n",
- slave->dev->master->name, slave->dev->name);
+ slave->bond->dev->name, slave->dev->name);
return -1;
}
@@ -1973,7 +1973,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
// if slave is null, the whole port is not initialized
if (!port->slave) {
pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ slave->bond->dev->name, slave->dev->name);
return;
}
@@ -2009,7 +2009,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
pr_info("%s: Removing an active aggregator\n",
- aggregator->slave->dev->master->name);
+ aggregator->slave->bond->dev->name);
// select new active aggregator
select_new_active_agg = 1;
}
@@ -2040,7 +2040,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
ad_agg_selection_logic(__get_first_agg(port));
} else {
pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n",
- slave->dev->master->name);
+ slave->bond->dev->name);
}
} else { // in case that the only port related to this aggregator is the one we want to remove
select_new_active_agg = aggregator->is_active;
@@ -2048,7 +2048,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
ad_clear_agg(aggregator);
if (select_new_active_agg) {
pr_info("%s: Removing an active aggregator\n",
- slave->dev->master->name);
+ slave->bond->dev->name);
// select new active aggregator
ad_agg_selection_logic(__get_first_agg(port));
}
@@ -2076,7 +2076,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
ad_clear_agg(temp_aggregator);
if (select_new_active_agg) {
pr_info("%s: Removing an active aggregator\n",
- slave->dev->master->name);
+ slave->bond->dev->name);
// select new active aggregator
ad_agg_selection_logic(__get_first_agg(port));
}
@@ -2184,7 +2184,7 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1
if (!port->slave) {
pr_warning("%s: Warning: port of slave %s is uninitialized\n",
- slave->dev->name, slave->dev->master->name);
+ slave->dev->name, slave->bond->dev->name);
return ret;
}
@@ -2240,7 +2240,7 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
// if slave is null, the whole port is not initialized
if (!port->slave) {
pr_warning("Warning: %s: speed changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ slave->bond->dev->name, slave->dev->name);
return;
}
@@ -2268,7 +2268,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
// if slave is null, the whole port is not initialized
if (!port->slave) {
pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ slave->bond->dev->name, slave->dev->name);
return;
}
@@ -2297,7 +2297,7 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
// if slave is null, the whole port is not initialized
if (!port->slave) {
pr_warning("Warning: %s: link status changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ slave->bond->dev->name, slave->dev->name);
return;
}
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index e15cc11..6dc3625 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -491,7 +491,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
client_info->mac_dst);
if (!skb) {
pr_err("%s: Error: failed to create an ARP packet\n",
- client_info->slave->dev->master->name);
+ client_info->slave->bond->dev->name);
continue;
}
@@ -501,7 +501,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
skb = vlan_put_tag(skb, client_info->vlan_id);
if (!skb) {
pr_err("%s: Error: failed to insert VLAN tag\n",
- client_info->slave->dev->master->name);
+ client_info->slave->bond->dev->name);
continue;
}
}
@@ -914,7 +914,7 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
if (dev_set_mac_address(dev, &s_addr)) {
pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n"
"ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n",
- dev->master->name, dev->name);
+ slave->bond->dev->name, dev->name);
return -EOPNOTSUPP;
}
return 0;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6fae5f3..ed6a266 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -752,11 +752,9 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
{
struct in_device *in_dev;
- rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
if (in_dev)
ip_mc_rejoin_groups(in_dev);
- rcu_read_unlock();
}
/*
@@ -766,9 +764,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
*/
static void bond_resend_igmp_join_requests(struct bonding *bond)
{
- struct net_device *bond_dev, *vlan_dev, *master_dev;
+ struct net_device *bond_dev, *vlan_dev, *upper_dev;
struct vlan_entry *vlan;
+ rcu_read_lock();
read_lock(&bond->lock);
bond_dev = bond->dev;
@@ -780,18 +779,14 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
* if bond is enslaved to a bridge,
* then rejoin all groups on its master
*/
- master_dev = bond_dev->master;
- if (master_dev)
- if ((master_dev->priv_flags & IFF_EBRIDGE)
- && (bond_dev->priv_flags & IFF_BRIDGE_PORT))
- __bond_resend_igmp_join_requests(master_dev);
+ upper_dev = netdev_master_upper_dev_get_rcu(bond_dev);
+ if (upper_dev && upper_dev->priv_flags & IFF_EBRIDGE)
+ __bond_resend_igmp_join_requests(upper_dev);
/* rejoin all groups on vlan devices */
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- rcu_read_lock();
vlan_dev = __vlan_find_dev_deep(bond_dev,
vlan->vlan_id);
- rcu_read_unlock();
if (vlan_dev)
__bond_resend_igmp_join_requests(vlan_dev);
}
@@ -800,13 +795,16 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
read_unlock(&bond->lock);
+ rcu_read_unlock();
}
static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
mcast_work.work);
+ rcu_read_lock();
bond_resend_igmp_join_requests(bond);
+ rcu_read_unlock();
}
/*
@@ -1494,6 +1492,27 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
return ret;
}
+static int bond_master_upper_dev_link(struct net_device *bond_dev,
+ struct net_device *slave_dev)
+{
+ int err;
+
+ err = netdev_master_upper_dev_link(slave_dev, bond_dev);
+ if (err)
+ return err;
+ slave_dev->flags |= IFF_SLAVE;
+ rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE);
+ return 0;
+}
+
+static void bond_upper_dev_unlink(struct net_device *bond_dev,
+ struct net_device *slave_dev)
+{
+ netdev_upper_dev_unlink(slave_dev, bond_dev);
+ slave_dev->flags &= ~IFF_SLAVE;
+ rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE);
+}
+
/* enslave device <slave> to bond device <master> */
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
{
@@ -1655,9 +1674,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
}
}
- res = netdev_set_bond_master(slave_dev, bond_dev);
+ res = bond_master_upper_dev_link(bond_dev, slave_dev);
if (res) {
- pr_debug("Error %d calling netdev_set_bond_master\n", res);
+ pr_debug("Error %d calling bond_master_upper_dev_link\n", res);
goto err_restore_mac;
}
@@ -1891,7 +1910,7 @@ err_close:
dev_close(slave_dev);
err_unset_master:
- netdev_set_bond_master(slave_dev, NULL);
+ bond_upper_dev_unlink(bond_dev, slave_dev);
err_restore_mac:
if (!bond->params.fail_over_mac) {
@@ -1936,7 +1955,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
/* slave is not a slave or master is not master of this slave */
if (!(slave_dev->flags & IFF_SLAVE) ||
- (slave_dev->master != bond_dev)) {
+ !netdev_has_upper_dev(slave_dev, bond_dev)) {
pr_err("%s: Error: cannot release %s.\n",
bond_dev->name, slave_dev->name);
return -EINVAL;
@@ -2080,7 +2099,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
netif_addr_unlock_bh(bond_dev);
}
- netdev_set_bond_master(slave_dev, NULL);
+ bond_upper_dev_unlink(bond_dev, slave_dev);
slave_disable_netpoll(slave);
@@ -2195,7 +2214,7 @@ static int bond_release_all(struct net_device *bond_dev)
netif_addr_unlock_bh(bond_dev);
}
- netdev_set_bond_master(slave_dev, NULL);
+ bond_upper_dev_unlink(bond_dev, slave_dev);
slave_disable_netpoll(slave);
@@ -2259,8 +2278,9 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
if (!USES_PRIMARY(bond->params.mode))
return -EINVAL;
- /* Verify that master_dev is indeed the master of slave_dev */
- if (!(slave_dev->flags & IFF_SLAVE) || (slave_dev->master != bond_dev))
+ /* Verify that bond_dev is indeed the master of slave_dev */
+ if (!(slave_dev->flags & IFF_SLAVE) ||
+ !netdev_has_upper_dev(slave_dev, bond_dev))
return -EINVAL;
read_lock(&bond->lock);
@@ -3249,36 +3269,32 @@ static int bond_master_netdev_event(unsigned long event,
static int bond_slave_netdev_event(unsigned long event,
struct net_device *slave_dev)
{
- struct net_device *bond_dev = slave_dev->master;
- struct bonding *bond = netdev_priv(bond_dev);
- struct slave *slave = NULL;
+ struct slave *slave = bond_slave_get_rtnl(slave_dev);
+ struct bonding *bond = slave->bond;
+ struct net_device *bond_dev = slave->bond->dev;
+ u32 old_speed;
+ u8 old_duplex;
switch (event) {
case NETDEV_UNREGISTER:
- if (bond_dev) {
- if (bond->setup_by_slave)
- bond_release_and_destroy(bond_dev, slave_dev);
- else
- bond_release(bond_dev, slave_dev);
- }
+ if (bond->setup_by_slave)
+ bond_release_and_destroy(bond_dev, slave_dev);
+ else
+ bond_release(bond_dev, slave_dev);
break;
case NETDEV_UP:
case NETDEV_CHANGE:
- slave = bond_get_slave_by_dev(bond, slave_dev);
- if (slave) {
- u32 old_speed = slave->speed;
- u8 old_duplex = slave->duplex;
+ old_speed = slave->speed;
+ old_duplex = slave->duplex;
- bond_update_speed_duplex(slave);
+ bond_update_speed_duplex(slave);
- if (bond->params.mode == BOND_MODE_8023AD) {
- if (old_speed != slave->speed)
- bond_3ad_adapter_speed_changed(slave);
- if (old_duplex != slave->duplex)
- bond_3ad_adapter_duplex_changed(slave);
- }
+ if (bond->params.mode == BOND_MODE_8023AD) {
+ if (old_speed != slave->speed)
+ bond_3ad_adapter_speed_changed(slave);
+ if (old_duplex != slave->duplex)
+ bond_3ad_adapter_duplex_changed(slave);
}
-
break;
case NETDEV_DOWN:
/*
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index f8af2fc..c9cd1c0 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -257,6 +257,9 @@ static inline bool bond_vlan_used(struct bonding *bond)
#define bond_slave_get_rcu(dev) \
((struct slave *) rcu_dereference(dev->rx_handler_data))
+#define bond_slave_get_rtnl(dev) \
+ ((struct slave *) rtnl_dereference(dev->rx_handler_data))
+
/**
* Returns NULL if the net_device does not belong to any of the bond's slaves
*
@@ -279,11 +282,9 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,
static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
{
- if (!slave || !slave->dev->master) {
+ if (!slave || !slave->bond)
return NULL;
- }
-
- return netdev_priv(slave->dev->master);
+ return slave->bond;
}
static inline bool bond_is_lb(const struct bonding *bond)
@@ -359,10 +360,9 @@ static inline void bond_netpoll_send_skb(const struct slave *slave,
static inline void bond_set_slave_inactive_flags(struct slave *slave)
{
- struct bonding *bond = netdev_priv(slave->dev->master);
- if (!bond_is_lb(bond))
+ if (!bond_is_lb(slave->bond))
bond_set_backup_slave(slave);
- if (!bond->params.all_slaves_active)
+ if (!slave->bond->params.all_slaves_active)
slave->inactive = 1;
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4d41682..f05e56f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1989,6 +1989,7 @@ errout:
if (err < 0)
rtnl_set_sk_err(net, RTNLGRP_LINK, err);
}
+EXPORT_SYMBOL(rtmsg_ifinfo);
static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
struct net_device *dev,
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 14/15] net: remove no longer used netdev_set_bond_master() and netdev_set_master()
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
include/linux/netdevice.h | 6 +----
net/core/dev.c | 63 ---------------------------------------------
2 files changed, 1 insertion(+), 68 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 95345d4..c689593 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -886,8 +886,7 @@ struct netdev_fcoe_hbainfo {
* flow_id is a flow ID to be passed to rps_may_expire_flow() later.
* Return the filter ID on success, or a negative error code.
*
- * Slave management functions (for bridge, bonding, etc). User should
- * call netdev_set_master() to set dev->master properly.
+ * Slave management functions (for bridge, bonding, etc).
* int (*ndo_add_slave)(struct net_device *dev, struct net_device *slave_dev);
* Called to make another netdev an underling.
*
@@ -2625,9 +2624,6 @@ extern int netdev_master_upper_dev_link(struct net_device *dev,
struct net_device *upper_dev);
extern void netdev_upper_dev_unlink(struct net_device *dev,
struct net_device *upper_dev);
-extern int netdev_set_master(struct net_device *dev, struct net_device *master);
-extern int netdev_set_bond_master(struct net_device *dev,
- struct net_device *master);
extern int skb_checksum_help(struct sk_buff *skb);
extern struct sk_buff *skb_gso_segment(struct sk_buff *skb,
netdev_features_t features);
diff --git a/net/core/dev.c b/net/core/dev.c
index d7fd235..e22107c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4648,69 +4648,6 @@ void netdev_upper_dev_unlink(struct net_device *dev,
}
EXPORT_SYMBOL(netdev_upper_dev_unlink);
-/**
- * netdev_set_master - set up master pointer
- * @slave: slave device
- * @master: new master device
- *
- * Changes the master device of the slave. Pass %NULL to break the
- * bonding. The caller must hold the RTNL semaphore. On a failure
- * a negative errno code is returned. On success the reference counts
- * are adjusted and the function returns zero.
- */
-int netdev_set_master(struct net_device *slave, struct net_device *master)
-{
- struct net_device *old = slave->master;
- int err;
-
- ASSERT_RTNL();
-
- if (master) {
- if (old)
- return -EBUSY;
- err = netdev_master_upper_dev_link(slave, master);
- if (err)
- return err;
- }
-
- slave->master = master;
-
- if (old)
- netdev_upper_dev_unlink(slave, master);
-
- return 0;
-}
-EXPORT_SYMBOL(netdev_set_master);
-
-/**
- * netdev_set_bond_master - set up bonding master/slave pair
- * @slave: slave device
- * @master: new master device
- *
- * Changes the master device of the slave. Pass %NULL to break the
- * bonding. The caller must hold the RTNL semaphore. On a failure
- * a negative errno code is returned. On success %RTM_NEWLINK is sent
- * to the routing socket and the function returns zero.
- */
-int netdev_set_bond_master(struct net_device *slave, struct net_device *master)
-{
- int err;
-
- ASSERT_RTNL();
-
- err = netdev_set_master(slave, master);
- if (err)
- return err;
- if (master)
- slave->flags |= IFF_SLAVE;
- else
- slave->flags &= ~IFF_SLAVE;
-
- rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE);
- return 0;
-}
-EXPORT_SYMBOL(netdev_set_bond_master);
-
static void dev_change_rx_flags(struct net_device *dev, int flags)
{
const struct net_device_ops *ops = dev->netdev_ops;
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 15/15] net: kill dev->master
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Nobody uses this now. Remove it.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
include/linux/netdevice.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c689593..8459f72 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1168,10 +1168,6 @@ struct net_device {
* avoid dirtying this cache line.
*/
- struct net_device *master; /* Pointer to master device of a group,
- * which this device is member of.
- */
-
struct list_head upper_dev_list; /* List of upper devices */
/* Interface address info used in eth_type_trans() */
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 03/15] vlan: add link to upper device
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/8021q/vlan.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 9096bcb..2dca0fa 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -105,6 +105,8 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
*/
unregister_netdevice_queue(dev, head);
+ netdev_upper_dev_unlink(real_dev, dev);
+
if (grp->nr_vlan_devs == 0)
vlan_gvrp_uninit_applicant(real_dev);
@@ -162,9 +164,13 @@ int register_vlan_dev(struct net_device *dev)
if (err < 0)
goto out_uninit_applicant;
+ err = netdev_upper_dev_link(real_dev, dev);
+ if (err)
+ goto out_uninit_applicant;
+
err = register_netdevice(dev);
if (err < 0)
- goto out_uninit_applicant;
+ goto out_upper_dev_unlink;
/* Account for reference in struct vlan_dev_priv */
dev_hold(real_dev);
@@ -180,6 +186,8 @@ int register_vlan_dev(struct net_device *dev)
return 0;
+out_upper_dev_unlink:
+ netdev_upper_dev_unlink(real_dev, dev);
out_uninit_applicant:
if (grp->nr_vlan_devs == 0)
vlan_gvrp_uninit_applicant(real_dev);
--
1.7.10.4
^ permalink raw reply related
* [patch net-next v2 04/15] rtnetlink: remove usage of dev->master
From: Jiri Pirko @ 2012-08-14 15:05 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, faisal.latif, roland, sean.hefty, hal.rosenstock,
fubar, andy, divy, jitendra.kalsaria, sony.chacko, linux-driver,
kaber, ursula.braun, blaschka, linux390, shemminger, bhutchings,
therbert, xiyou.wangcong, joe, gregory.v.rose, john.r.fastabend,
linux-rdma, linux-kernel, linux-s390, bridge, fbl
In-Reply-To: <1344956748-2099-1-git-send-email-jiri@resnulli.us>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/core/rtnetlink.c | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 34d975b..4d41682 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -879,6 +879,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
const struct rtnl_link_stats64 *stats;
struct nlattr *attr, *af_spec;
struct rtnl_af_ops *af_ops;
+ struct net_device *upper_dev = netdev_master_upper_dev_get(dev);
ASSERT_RTNL();
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
@@ -907,8 +908,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
#endif
(dev->ifindex != dev->iflink &&
nla_put_u32(skb, IFLA_LINK, dev->iflink)) ||
- (dev->master &&
- nla_put_u32(skb, IFLA_MASTER, dev->master->ifindex)) ||
+ (upper_dev &&
+ nla_put_u32(skb, IFLA_MASTER, upper_dev->ifindex)) ||
(dev->qdisc &&
nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
(dev->ifalias &&
@@ -1270,16 +1271,16 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
static int do_set_master(struct net_device *dev, int ifindex)
{
- struct net_device *master_dev;
+ struct net_device *upper_dev = netdev_master_upper_dev_get(dev);
const struct net_device_ops *ops;
int err;
- if (dev->master) {
- if (dev->master->ifindex == ifindex)
+ if (upper_dev) {
+ if (upper_dev->ifindex == ifindex)
return 0;
- ops = dev->master->netdev_ops;
+ ops = upper_dev->netdev_ops;
if (ops->ndo_del_slave) {
- err = ops->ndo_del_slave(dev->master, dev);
+ err = ops->ndo_del_slave(upper_dev, dev);
if (err)
return err;
} else {
@@ -1288,12 +1289,12 @@ static int do_set_master(struct net_device *dev, int ifindex)
}
if (ifindex) {
- master_dev = __dev_get_by_index(dev_net(dev), ifindex);
- if (!master_dev)
+ upper_dev = __dev_get_by_index(dev_net(dev), ifindex);
+ if (!upper_dev)
return -EINVAL;
- ops = master_dev->netdev_ops;
+ ops = upper_dev->netdev_ops;
if (ops->ndo_add_slave) {
- err = ops->ndo_add_slave(master_dev, dev);
+ err = ops->ndo_add_slave(upper_dev, dev);
if (err)
return err;
} else {
@@ -2050,7 +2051,6 @@ errout:
static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
struct net *net = sock_net(skb->sk);
- struct net_device *master = NULL;
struct ndmsg *ndm;
struct nlattr *tb[NDA_MAX+1];
struct net_device *dev;
@@ -2089,9 +2089,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
/* Support fdb on master device the net/bridge default case */
if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
(dev->priv_flags & IFF_BRIDGE_PORT)) {
- master = dev->master;
- err = master->netdev_ops->ndo_fdb_add(ndm, dev, addr,
- nlh->nlmsg_flags);
+ struct net_device *br_dev = netdev_master_upper_dev_get(dev);
+ const struct net_device_ops *ops = br_dev->netdev_ops;
+
+ err = ops->ndo_fdb_add(ndm, dev, addr, nlh->nlmsg_flags);
if (err)
goto out;
else
@@ -2148,10 +2149,11 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
/* Support fdb on master device the net/bridge default case */
if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
(dev->priv_flags & IFF_BRIDGE_PORT)) {
- struct net_device *master = dev->master;
+ struct net_device *br_dev = netdev_master_upper_dev_get(dev);
+ const struct net_device_ops *ops = br_dev->netdev_ops;
- if (master->netdev_ops->ndo_fdb_del)
- err = master->netdev_ops->ndo_fdb_del(ndm, dev, addr);
+ if (ops->ndo_fdb_del)
+ err = ops->ndo_fdb_del(ndm, dev, addr);
if (err)
goto out;
@@ -2234,9 +2236,11 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
rcu_read_lock();
for_each_netdev_rcu(net, dev) {
if (dev->priv_flags & IFF_BRIDGE_PORT) {
- struct net_device *master = dev->master;
- const struct net_device_ops *ops = master->netdev_ops;
+ struct net_device *br_dev;
+ const struct net_device_ops *ops;
+ br_dev = netdev_master_upper_dev_get(dev);
+ ops = br_dev->netdev_ops;
if (ops->ndo_fdb_dump)
idx = ops->ndo_fdb_dump(skb, cb, dev, idx);
}
--
1.7.10.4
^ permalink raw reply related
* RE: [PATCH 5/5] net/hyperv: Call netif_carrier_off() after register_netdev()
From: Haiyang Zhang @ 2012-08-14 15:32 UTC (permalink / raw)
To: Ilya Shchepetkov, KY Srinivasan
Cc: David S. Miller, devel@linuxdriverproject.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
ldv-project@ispras.ru
In-Reply-To: <1344940135-17079-6-git-send-email-shchepetkov@ispras.ru>
> -----Original Message-----
> From: Ilya Shchepetkov [mailto:shchepetkov@ispras.ru]
> Sent: Tuesday, August 14, 2012 6:29 AM
> To: KY Srinivasan
> Cc: Ilya Shchepetkov; Haiyang Zhang; David S. Miller;
> devel@linuxdriverproject.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; ldv-project@ispras.ru
> Subject: [PATCH 5/5] net/hyperv: Call netif_carrier_off() after
> register_netdev()
>
> For carrier detection to work properly when binding the driver with a
> cable unplugged, netif_carrier_off() should be called after
> register_netdev(), not before.
>
> Calling netif_carrier_off() before register_netdev() was causing the
> network interface to miss a linkwatch pending event leading to an
> inconsistent state if the link is not up when interface is initialized.
>
> Found by Linux Driver Verification project (linuxtesting.org).
>
> Signed-off-by: Ilya Shchepetkov <shchepetkov@ispras.ru>
> ---
> drivers/net/hyperv/netvsc_drv.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/hyperv/netvsc_drv.c
> b/drivers/net/hyperv/netvsc_drv.c
> index 8c5a1c4..5734ad0 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -416,9 +416,6 @@ static int netvsc_probe(struct hv_device *dev,
> if (!net)
> return -ENOMEM;
>
> - /* Set initial state */
> - netif_carrier_off(net);
> -
> net_device_ctx = netdev_priv(net);
> net_device_ctx->device_ctx = dev;
> hv_set_drvdata(dev, net);
> @@ -441,6 +438,9 @@ static int netvsc_probe(struct hv_device *dev,
> goto out;
> }
>
> + /* Set initial state */
> + netif_carrier_off(net);
> +
> /* Notify the netvsc driver of the new device */
> device_info.ring_size = ring_size;
> ret = rndis_filter_device_add(dev, &device_info);
Thanks.
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
^ permalink raw reply
* Re: [PATCH v3 0/6] cgroup cls & netprio 'cleanups'
From: Neil Horman @ 2012-08-14 15:37 UTC (permalink / raw)
To: Daniel Wagner
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Daniel Wagner, David S. Miller, Al Viro, Andrew Morton,
Eric Dumazet, Gao feng, Glauber Costa, Jamal Hadi Salim,
John Fastabend, Kamezawa Hiroyuki, Li Zefan, Tejun Heo, Tim Chen
In-Reply-To: <502A56C9.8070701-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
On Tue, Aug 14, 2012 at 03:46:49PM +0200, Daniel Wagner wrote:
> Hi Neil,
>
> On 14.08.2012 15:30, Neil Horman wrote:
> > On Tue, Aug 14, 2012 at 03:25:50PM +0200, Daniel Wagner wrote:
> >> On 14.08.2012 15:10, Neil Horman wrote:
> >>> On Tue, Aug 14, 2012 at 03:02:16PM +0200, Daniel Wagner wrote:
> >>>> From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
> >>>>
> >>>> Hi,
> >>>>
> >>>> Sorry for the delay on updating this series. The usual
> >>>> excuse apply here.
> >>>>
> >>>> I saw that John is busy improving net_prio so I took the
> >>>> liberty to port his changes to net_cls (#1-3). Patch #3 will
> >>>> collide with John's unapplied patches. I am happy
> >>>> to rebase this series if needed.
> >>>>
> >>>> Patch #4 and #5 improve the readability with using
> >>>> IS_MODULE/BUILTIN macros. This patches prepare the last
> >>>> patch.
> >>>>
> >>>> Patch #6 removes support for assigning subsystem IDs during
> >>>> runtime. As it turns out this is not really needed. By doing
> >>>> so we are able to free some unused memory.
> >>>>
> >>>> The patches are against net-next.
> >>>>
> >>>> cheers,
> >>>> daniel
> >>>>
> >>> These aren't so much 'cleanups' as feature enhancements and fixes for the first
> >>> pass of those enhancements (at least in the case of the net_prio cgroup).
> >>
> >> Sorry about that. I wanted to keep the series title, so that someone
> >> looking up older versions find it.
> >>
> > That makes sense, but it would be best until we acked the the version going into
> > net_prio, otherwise we maybe tracking regressions in two places rather than one.
>
> I agree, let's wait until net_prio gets stable.
>
> >>> I've nothing against them, but since we're still going through some churn on the
> >>> net_prio variant, it may be best to wait until thats settled before moving them
> >>> over to net_cls.
> >>
> >> Sure, I can update this series when the net_prio controller changes
> >> have settled down.
> >>
> > Thank you, I think thats a good idea.
> >
> >> I just wonder if it wouldn't make sense to merge them together.
> >> Obviously, that will break the user space which is not a good thing
> >> but having a controller per socket option is not good either.
> >>
> > This has been discussed (although perhaps not on list) before. I don't think
> > we're going to see lots of cgroups for socket options. most of them have proc
> > tunables, priroity and classification dont.
>
> Well, I'll would like to able to set SO_MARK via a controller [1][2]. The use
> case is that I'd like to set the routing table per application. As it turns
> out the kernel has almost all bits and pieces to get this working. The only
> missing thing is setting SO_MARK without touching the application. For which
> the net cgroup controllers seem to be the perfect match.
>
Ok, I stand corrected, there are other things that might be good for using with
cgroups in the networking space.
> > We could merge the two controllers,
> > but as you said it breaks users space which is a non-starter. It also doesn't
> > really buy us anything, as people want to be able to set priority and
> > classification independently, so we either use two controllers, or one
> > controller with twice as many cgroup instances (one for each combination of
> > priroity/class that an admin wants).
>
> Okay, I see your point. What is your standpoint concerning SO_MARK? Following
> your logic, we would need another controller for this which is what I rather
> have avoided. But I am more than happy to send patches for this :)
>
Others may well have differing opinions, but my feeling is separate controllers
for separate functions. As noted, while you could merge all the controllers, it
doesn't buy you much, and convolutes the meaning of a particular cgroup instance
(i.e. with a merged controller, a given cgroup instance owuld enforce
clasification A, priority B and mark value C, while another could enforce class
D priority B and mark C. With separate controllers, admins can independently
select which class/priority and mark value to apply orthogonally.
So I'd vote for separate controllers.
> > I'll ping you when the net_prio stuff settles out.
>
> Great, thanks.
>
> cheers,
> daniel
>
> [1] http://lists.connman.net/pipermail/connman/2012-August/010716.html
> [2] http://lists.connman.net/pipermail/connman/2012-August/010715.html
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH 4/5] drivers/net/ethernet/ti/davinci_cpdma.c: Remove potential NULL dereference
From: Julia Lawall @ 2012-08-14 15:49 UTC (permalink / raw)
To: netdev; +Cc: kernel-janitors, linux-kernel
In-Reply-To: <1344959388-19719-1-git-send-email-Julia.Lawall@lip6.fr>
From: Julia Lawall <Julia.Lawall@lip6.fr>
If the NULL test is necessary, the initialization involving a dereference of
the tested value should be moved after the NULL test.
The sematic patch that fixes this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
type T;
expression E;
identifier i,fld;
statement S;
@@
- T i = E->fld;
+ T i;
... when != E
when != i
if (E == NULL) S
+ i = E->fld;
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/net/ethernet/ti/davinci_cpdma.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c
index 3b5c457..d15c888 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -538,11 +538,12 @@ EXPORT_SYMBOL_GPL(cpdma_chan_create);
int cpdma_chan_destroy(struct cpdma_chan *chan)
{
- struct cpdma_ctlr *ctlr = chan->ctlr;
+ struct cpdma_ctlr *ctlr;
unsigned long flags;
if (!chan)
return -EINVAL;
+ ctlr = chan->ctlr;
spin_lock_irqsave(&ctlr->lock, flags);
if (chan->state != CPDMA_STATE_IDLE)
^ permalink raw reply related
* Re: [RFC net-next 4/4] gianfar: Use separate NAPIs for Tx and Rx processing
From: Claudiu Manoil @ 2012-08-14 16:08 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: netdev, David S. Miller, Pankaj Chauhan, Eric Dumazet
In-Reply-To: <20120814005114.GA29337@windriver.com>
On 08/14/2012 03:51 AM, Paul Gortmaker wrote:
> [[RFC net-next 4/4] gianfar: Use separate NAPIs for Tx and Rx processing] On 08/08/2012 (Wed 15:26) Claudiu Manoil wrote:
>
>> Add a separate napi poll routine for Tx cleanup, to be triggerred by Tx
>> confirmation interrupts only. Existing poll function is modified to handle
>> only the Rx path processing. This allows parallel processing of Rx and Tx
>> confirmation paths on a smp machine (2 cores).
>> The split also results in simpler/cleaner napi poll function implementations,
>> where each processing path has its own budget, thus improving the fairness b/w
>> the processing paths at the same time.
>>
>> Signed-off-by: Pankaj Chauhan <pankaj.chauhan@freescale.com>
>> Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
>> ---
>> drivers/net/ethernet/freescale/gianfar.c | 154 +++++++++++++++++++++++-------
>> drivers/net/ethernet/freescale/gianfar.h | 16 +++-
>> 2 files changed, 130 insertions(+), 40 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
>> index 919acb3..2774961 100644
>> --- a/drivers/net/ethernet/freescale/gianfar.c
>> +++ b/drivers/net/ethernet/freescale/gianfar.c
>> @@ -128,12 +128,14 @@ static void free_skb_resources(struct gfar_private *priv);
>> static void gfar_set_multi(struct net_device *dev);
>> static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
>> static void gfar_configure_serdes(struct net_device *dev);
>> -static int gfar_poll(struct napi_struct *napi, int budget);
>> +static int gfar_poll_rx(struct napi_struct *napi, int budget);
>> +static int gfar_poll_tx(struct napi_struct *napi, int budget);
>> #ifdef CONFIG_NET_POLL_CONTROLLER
>> static void gfar_netpoll(struct net_device *dev);
>> #endif
>> int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
>> -static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
>> +static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue,
>> + int tx_work_limit);
> I'm looking at this in a bit more detail now (was on vacation last wk).
> With the above, you push a work limit down into the clean_tx_ring.
> I'm wondering if the above is implicitly involved in the performance
> difference you see, since...
>
>> static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
>> int amount_pull, struct napi_struct *napi);
>> void gfar_halt(struct net_device *dev);
>> @@ -543,16 +545,20 @@ static void disable_napi(struct gfar_private *priv)
>> {
>> int i;
>>
>> - for (i = 0; i < priv->num_grps; i++)
>> - napi_disable(&priv->gfargrp[i].napi);
>> + for (i = 0; i < priv->num_grps; i++) {
>> + napi_disable(&priv->gfargrp[i].napi_rx);
>> + napi_disable(&priv->gfargrp[i].napi_tx);
>> + }
>> }
>>
>> static void enable_napi(struct gfar_private *priv)
>> {
>> int i;
>>
>> - for (i = 0; i < priv->num_grps; i++)
>> - napi_enable(&priv->gfargrp[i].napi);
>> + for (i = 0; i < priv->num_grps; i++) {
>> + napi_enable(&priv->gfargrp[i].napi_rx);
>> + napi_enable(&priv->gfargrp[i].napi_tx);
>> + }
>> }
>>
>> static int gfar_parse_group(struct device_node *np,
>> @@ -1028,9 +1034,12 @@ static int gfar_probe(struct platform_device *ofdev)
>> dev->ethtool_ops = &gfar_ethtool_ops;
>>
>> /* Register for napi ...We are registering NAPI for each grp */
>> - for (i = 0; i < priv->num_grps; i++)
>> - netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
>> - GFAR_DEV_WEIGHT);
>> + for (i = 0; i < priv->num_grps; i++) {
>> + netif_napi_add(dev, &priv->gfargrp[i].napi_rx, gfar_poll_rx,
>> + GFAR_DEV_RX_WEIGHT);
>> + netif_napi_add(dev, &priv->gfargrp[i].napi_tx, gfar_poll_tx,
>> + GFAR_DEV_TX_WEIGHT);
>> + }
>>
>> if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
>> dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
>> @@ -2465,7 +2474,8 @@ static void gfar_align_skb(struct sk_buff *skb)
>> }
>>
>> /* Interrupt Handler for Transmit complete */
>> -static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
>> +static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue,
>> + int tx_work_limit)
>> {
>> struct net_device *dev = tx_queue->dev;
>> struct netdev_queue *txq;
>> @@ -2490,7 +2500,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
>> bdp = tx_queue->dirty_tx;
>> skb_dirtytx = tx_queue->skb_dirtytx;
>>
>> - while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) {
>> + while ((skb = tx_queue->tx_skbuff[skb_dirtytx]) && tx_work_limit--) {
> ...code like this provides a new exit point that did not exist before,
> for the case of a massive transmit blast. Do you have any data on how
> often the work limit is hit? The old Don Becker ether drivers which
> originally introduced the idea of work limits (on IRQs) used to printk a
> message when they hit it, since ideally it shouldn't be happening all
> the time.
>
> In any case, it might be worth while to split this change out into a
> separate commit; something like:
>
> gianfar: push transmit cleanup work limit down to clean_tx_ring
>
> The advantage being (1) we can test this change in isolation, and
> (2) it makes your remaining rx/tx separate thread patch smaller and
> easier to review.
Sounds interesting, I think I'll give it a try.
Thanks,
Claudiu
^ permalink raw reply
* Re: [RFC net-next 0/4] gianfar: Use separate NAPI for Tx confirmation processing
From: Claudiu Manoil @ 2012-08-14 16:08 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: Tomas Hruby, Eric Dumazet, netdev, David S. Miller
In-Reply-To: <20120814011526.GB29337@windriver.com>
On 08/14/2012 04:15 AM, Paul Gortmaker wrote:
> This is a lot lower variation than what you reported earlier (20
> versus 200, I think). It was the variation that raised a red flag for
> me...
Hi Paul,
The earlier variation, which is much bigger (indeed ~200), was observed
on a p1020 (slow, 2 cores, MQ_MG_MODE).
I did not collect however as detailed measurement results for that
board, as I did for p1010 (previous email).
The most important performance improvement I've noticed however was on
the p1020 platform.
>> By changing the coalescing settings from default* (rx coalescing off,
>> tx-usecs: 10, tx-frames: 16) to:
>> "ethtool -C eth1 rx-frames 22 tx-frames 22 rx-usecs 32 tx-usecs 32"
>> we get a throughput of ~710 Mbps.
>>
>> For *Image 2)*, using the default tcp_limit_output_bytes value
>> (131072) - I've noticed
>> that "tweaking" tcp_limit_output_bytes does not improve the
>> throughput -, we get the
>> following performance numbers:
>> * default coalescing settings: ~650 Mbps
>> * rx-frames tx-frames 22 rx-usecs 32 tx-usecs 32: ~860-880 Mbps
>>
>> For *Image 3)*, by disabling BQL (CONFIG_BQL = n), there's *no*
>> relevant performance
>> improvement compared to Image 1).
>> (note:
>> For all the measurements, rx and tx BD ring sizes have been set to
>> 64, for best performance.)
>>
>> So, I really tend to believe that the performance degradation comes
>> primarily from the driver,
>> and the napi poll processing turns out to be an important source for
>> that. The proposed patches
> This would make sense, if the CPU was slammed at 100% load in dealing
> with the tx processing, and the change made the driver considerably more
> efficient. But is that really the case? Is the p1010 really going flat
> out just to handle the Tx processing? Have you done any sort of
> profiling to confirm/deny where the CPU is spending its time?
The current gfar_poll implementation processes first the tx confirmation
path exhaustively, without a budget/ work limit,
and only then proceeds with the rx processing within the allotted
budget. An this happens for both Rx and Tx confirmation
interrupts. I find this unfair and out of balance. Maybe by letting rx
processing to be triggered by rx interrupts only, and
the tx conf path processing to be triggered by tx confirmation
interrupts only, and, on top of that, by imposing a work limit
on the tx confirmation path too, we get a more responsive driver that
performs better. Indeed some profiling data to
confirm this would be great, but I don't have it.
There's another issues that seems to be solved by this patchset, and
I've noticed it only on p1020rdb (this time).
And that is excessive Rx busy interrupts occurrence. Solving this issue
may be another factor for the performance
improvement on p1020. But maybe this is another discussion.
>
>> show substantial improvement, especially for SMP systems where Tx
>> and Rx processing may be
>> done in parallel.
>> What do you think?
>> Is it ok to proceed by re-spinning the patches? Do you recommend
>> additional measurements?
> Unfortunately Eric is out this week, so we will be without his input for
> a while. However, we are only at 3.6-rc1 -- meaning net-next will be
> open for quite some time, hence no need to rush to try and jam stuff in.
>
> Also, I have two targets I'm interested in testing your patches on. The
> 1st is a 500MHz mpc8349 board -- which should replicate what you see on
> your p1010 (slow, single core). The other is an 8641D, which is
> interesting since it will give us the SMP tx/rx as separate threads, but
> without the MQ_MG_MODE support (is that a correct assumption?)
>
> I don't have any fundamental problem with your patches (although 4/4
> might be better as two patches) -- the above targets/tests are only
> of interest, since I'm not convinced we yet understand _why_ your
> changes give a performance boost, and there might be something
> interesting hiding in there.
>
> So, while Eric is out, let me see if I can collect some more data on
> those two targets sometime this week.
Great, I don't mean to rush. The more data we get on this the better.
It would be great if you could do some measurements on your platforms too.
8641D is indeed a dual core with etsec 1.x (so without the MQ_MG_MODE),
but I did run some tests on a p2020, which has the same features. However
I'm eager to see your results.
Thanks for helping.
Regards,
Claudiu
^ permalink raw reply
* Re: [PATCH v2] net-tcp: TCP/IP stack bypass for loopback connections
From: Bruce Curtis @ 2012-08-14 16:19 UTC (permalink / raw)
To: Bill Fink; +Cc: David S. Miller, Eric Dumazet, netdev
In-Reply-To: <20120814023155.ffe9c01d.billfink@mindspring.com>
Re-sending due to vger.kernel.org rejecting HTML
On Mon, Aug 13, 2012 at 11:31 PM, Bill Fink <billfink@mindspring.com> wrote:
>
> On Thu, 9 Aug 2012, Bruce "Brutus" Curtis wrote:
>
> > From: "Bruce \"Brutus\" Curtis" <brutus@google.com>
> >
> > TCP/IP loopback socket pair stack bypass, based on an idea by, and
> > rough upstream patch from, David Miller <davem@davemloft.net> called
> > "friends", the data structure modifcations and connection scheme are
> > reused with extensive data-path changes.
> >
> > A new sysctl, net.ipv4.tcp_friends, is added:
> > 0: disable friends and use the stock data path.
> > 1: enable friends and bypass the stack data path, the default.
>
> The following is from a user perspective, since I am not
> intimately familiar with the internals of the TCP stack.
>
> I think tcp_friends is a poor name from a user POV.
> Something like tcp_bypass would be much better.
>
> I also believe it should be disabled by default, as that is
> the current behavior, and those who would gain an advantage
> from using it can easily enable it.
>
> Changing the behavior would violate the principle of least
> surprise. Loopback TCP testing of an application or system
> is often a useful first step in evaluating its behavior and
> performance. If the TCP stack is bypassed, it will give a
> very false impression when such tests are performed.
>
> Does it preserve all TCP semantics for applications, including
> things like urgent data, ancillary data, and TCP socket options
> and ioctls. If it doesn't, it shouldn't be the default, and it
> should be documented what features do and don't work when
> tcp_bypass is enabled. If all TCP semantics are unchanged,
> that would also be good to know and document.
>
> And there's the already mentioned issue of breaking tcpdump
> and related tools.
>
> While this could be a very useful feature in some environments,
> it seems to me it would be safest to have it disabled by default.
>
> -Bill
>
1) tcp_friends vs tcp_bypass, the average user will not need to know
about this tunable so if there's consensus that it needs to be
changed, change it?
2) this is a throughput/latency advantage for most (all?) so it
benefits most (all?) production environments
3) as for breaking tcpdump and ... Again, it does maintain the
connection establishment and finish packet flow so for most TCP
connection related interpose uses this should work and be documented
but if your trying to debug TCP's protocol state-machine, network
emulation, ... then Yes a user would need to disable but IMHO this is
the exception
4) all TCP socket semantics are maintained and if not it's a bug and
needs to be fixed
> > Note, when friends is enabled any loopback interpose, e.g. tcpdump,
> > will only see the TCP/IP packets during connection establishment and
> > finish, all data bypasses the stack and instead is delivered to the
> > destination socket directly.
> >
> > Testing done on a 4 socket 2.2GHz "Quad-Core AMD Opteron(tm) Processor
> > 8354 CPU" based system, netperf results for a single connection show
> > increased TCP_STREAM throughput, increased TCP_RR and TCP_CRR
> > transaction
> > rate for most message sizes vs baseline and comparable to AF_UNIX.
> >
> > Significant increase (up to 4.88x) in aggregate throughput for multiple
> > netperf runs (STREAM 32KB I/O x N) is seen.
^ permalink raw reply
* [PATCH] vmxnet3: Fix race between dev_open() and register_netdev()
From: Steve Hodgson @ 2012-08-14 16:13 UTC (permalink / raw)
To: Shreyas Bhatewara, pv-drivers, netdev, David S. Miller; +Cc: Steve Hodgson
dev_open() can complete before register_netdev() returns.
Fix vmxnet3_probe_device() to support this.
Signed-off-by: Steve Hodgson <steve@purestorage.com>
---
drivers/net/vmxnet3/vmxnet3_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 93e0cfb..ce9d4f2 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -3019,6 +3019,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
netdev->watchdog_timeo = 5 * HZ;
INIT_WORK(&adapter->work, vmxnet3_reset_work);
+ set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
if (adapter->intr.type == VMXNET3_IT_MSIX) {
int i;
@@ -3043,7 +3044,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
goto err_register;
}
- set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
vmxnet3_check_link(adapter, false);
atomic_inc(&devices_found);
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 00/16] generic hashtable implementation
From: Sasha Levin @ 2012-08-14 16:24 UTC (permalink / raw)
To: torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b
Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
bfields-uC3wQj2KruNg9hUCZPvPmw,
paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
josh-iaAMLnmF4UmaiuxdJuQwMA, rostedt-nx8X9YLhiw1AfugRpC6u6w,
lw-BthXqXjhjHXQFUHtdCDX3A,
mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w, Sasha Levin,
axboe-tSWWG44O7X1aa/9Udqfwiw, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
edumazet-hpIqsD4AKlfQT0dZR+AlfA, linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w, tj-DgEjT+Ai2ygdnm+yROfE0A,
teigland-H+wXaHxf7aLQT0dZR+AlfA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
There are quite a few places in the kernel which implement a hashtable
in a very similar way. Instead of having implementations of a hashtable
all over the kernel, we can re-use the code.
New changes since the RFC:
- Addressed last comments about previous patches.
- RCU support.
- Simplified the case where the hashtable is allocated statically, which is
the common case.
- A lot more places converted to use the new hashtable.
Sasha Levin (16):
hashtable: introduce a small and naive hashtable
user_ns: use new hashtable implementation
mm,ksm: use new hashtable implementation
workqueue: use new hashtable implementation
mm/huge_memory: use new hashtable implementation
tracepoint: use new hashtable implementation
net,9p: use new hashtable implementation
block,elevator: use new hashtable implementation
SUNRPC/cache: use new hashtable implementation
dlm: use new hashtable implementation
net,l2tp: use new hashtable implementation
dm: use new hashtable implementation
lockd: use new hashtable implementation
net,rds: use new hashtable implementation
openvswitch: use new hashtable implementation
tracing output: use new hashtable implementation
block/blk.h | 2 +-
block/elevator.c | 23 +--
drivers/md/dm-snap.c | 24 +--
drivers/md/persistent-data/dm-block-manager.c | 1 -
.../persistent-data/dm-persistent-data-internal.h | 19 --
.../md/persistent-data/dm-transaction-manager.c | 30 +--
fs/dlm/lowcomms.c | 47 +---
fs/lockd/svcsubs.c | 58 ++--
include/linux/elevator.h | 5 +-
include/linux/hashtable.h | 284 ++++++++++++++++++++
kernel/trace/trace_output.c | 20 +-
kernel/tracepoint.c | 27 +--
kernel/user.c | 33 +--
kernel/workqueue.c | 86 +-----
mm/huge_memory.c | 57 +---
mm/ksm.c | 33 +--
net/9p/error.c | 21 +-
net/l2tp/l2tp_core.c | 132 ++++------
net/l2tp/l2tp_core.h | 8 +-
net/l2tp/l2tp_debugfs.c | 19 +-
net/openvswitch/vport.c | 30 +--
net/rds/bind.c | 20 +-
net/rds/connection.c | 102 +++----
net/sunrpc/cache.c | 20 +-
24 files changed, 573 insertions(+), 528 deletions(-)
delete mode 100644 drivers/md/persistent-data/dm-persistent-data-internal.h
create mode 100644 include/linux/hashtable.h
--
1.7.8.6
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox