aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAmerigo Wang <amwang@redhat.com>2011-02-17 18:43:32 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-27 19:11:50 -0500
commit8a8efa22f51b3c3f879d272914e3dbbc2041bf91 (patch)
treedc4fd5df150bec7a54b92dd70f8a1f64c0ce5b26 /drivers
parent70919e23ac35c9c244dfd73f97312894cae7d65f (diff)
bonding: sync netpoll code with bridge
V4: rebase to net-next-2.6 V3: remove an useless #ifdef. This patch unifies the netpoll code in bonding with netpoll code in bridge, thanks to Herbert that code is much cleaner now. Signed-off-by: WANG Cong <amwang@redhat.com> Acked-by: Neil Horman <nhorman@tuxdriver.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_main.c155
-rw-r--r--drivers/net/bonding/bonding.h20
2 files changed, 118 insertions, 57 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 77e3c6a7176a..2ed662464cac 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -59,7 +59,6 @@
59#include <linux/uaccess.h> 59#include <linux/uaccess.h>
60#include <linux/errno.h> 60#include <linux/errno.h>
61#include <linux/netdevice.h> 61#include <linux/netdevice.h>
62#include <linux/netpoll.h>
63#include <linux/inetdevice.h> 62#include <linux/inetdevice.h>
64#include <linux/igmp.h> 63#include <linux/igmp.h>
65#include <linux/etherdevice.h> 64#include <linux/etherdevice.h>
@@ -424,15 +423,11 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
424{ 423{
425 skb->dev = slave_dev; 424 skb->dev = slave_dev;
426 skb->priority = 1; 425 skb->priority = 1;
427#ifdef CONFIG_NET_POLL_CONTROLLER 426 if (unlikely(netpoll_tx_running(slave_dev))) {
428 if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
429 struct netpoll *np = bond->dev->npinfo->netpoll;
430 slave_dev->npinfo = bond->dev->npinfo;
431 slave_dev->priv_flags |= IFF_IN_NETPOLL; 427 slave_dev->priv_flags |= IFF_IN_NETPOLL;
432 netpoll_send_skb_on_dev(np, skb, slave_dev); 428 bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
433 slave_dev->priv_flags &= ~IFF_IN_NETPOLL; 429 slave_dev->priv_flags &= ~IFF_IN_NETPOLL;
434 } else 430 } else
435#endif
436 dev_queue_xmit(skb); 431 dev_queue_xmit(skb);
437 432
438 return 0; 433 return 0;
@@ -1288,63 +1283,113 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
1288} 1283}
1289 1284
1290#ifdef CONFIG_NET_POLL_CONTROLLER 1285#ifdef CONFIG_NET_POLL_CONTROLLER
1291/* 1286static inline int slave_enable_netpoll(struct slave *slave)
1292 * You must hold read lock on bond->lock before calling this.
1293 */
1294static bool slaves_support_netpoll(struct net_device *bond_dev)
1295{ 1287{
1296 struct bonding *bond = netdev_priv(bond_dev); 1288 struct netpoll *np;
1297 struct slave *slave; 1289 int err = 0;
1298 int i = 0;
1299 bool ret = true;
1300 1290
1301 bond_for_each_slave(bond, slave, i) { 1291 np = kzalloc(sizeof(*np), GFP_KERNEL);
1302 if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL) || 1292 err = -ENOMEM;
1303 !slave->dev->netdev_ops->ndo_poll_controller) 1293 if (!np)
1304 ret = false; 1294 goto out;
1295
1296 np->dev = slave->dev;
1297 err = __netpoll_setup(np);
1298 if (err) {
1299 kfree(np);
1300 goto out;
1305 } 1301 }
1306 return i != 0 && ret; 1302 slave->np = np;
1303out:
1304 return err;
1305}
1306static inline void slave_disable_netpoll(struct slave *slave)
1307{
1308 struct netpoll *np = slave->np;
1309
1310 if (!np)
1311 return;
1312
1313 slave->np = NULL;
1314 synchronize_rcu_bh();
1315 __netpoll_cleanup(np);
1316 kfree(np);
1317}
1318static inline bool slave_dev_support_netpoll(struct net_device *slave_dev)
1319{
1320 if (slave_dev->priv_flags & IFF_DISABLE_NETPOLL)
1321 return false;
1322 if (!slave_dev->netdev_ops->ndo_poll_controller)
1323 return false;
1324 return true;
1307} 1325}
1308 1326
1309static void bond_poll_controller(struct net_device *bond_dev) 1327static void bond_poll_controller(struct net_device *bond_dev)
1310{ 1328{
1311 struct bonding *bond = netdev_priv(bond_dev); 1329}
1330
1331static void __bond_netpoll_cleanup(struct bonding *bond)
1332{
1312 struct slave *slave; 1333 struct slave *slave;
1313 int i; 1334 int i;
1314 1335
1315 bond_for_each_slave(bond, slave, i) { 1336 bond_for_each_slave(bond, slave, i)
1316 if (slave->dev && IS_UP(slave->dev)) 1337 if (IS_UP(slave->dev))
1317 netpoll_poll_dev(slave->dev); 1338 slave_disable_netpoll(slave);
1318 }
1319} 1339}
1320
1321static void bond_netpoll_cleanup(struct net_device *bond_dev) 1340static void bond_netpoll_cleanup(struct net_device *bond_dev)
1322{ 1341{
1323 struct bonding *bond = netdev_priv(bond_dev); 1342 struct bonding *bond = netdev_priv(bond_dev);
1343
1344 read_lock(&bond->lock);
1345 __bond_netpoll_cleanup(bond);
1346 read_unlock(&bond->lock);
1347}
1348
1349static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
1350{
1351 struct bonding *bond = netdev_priv(dev);
1324 struct slave *slave; 1352 struct slave *slave;
1325 const struct net_device_ops *ops; 1353 int i, err = 0;
1326 int i;
1327 1354
1328 read_lock(&bond->lock); 1355 read_lock(&bond->lock);
1329 bond_dev->npinfo = NULL;
1330 bond_for_each_slave(bond, slave, i) { 1356 bond_for_each_slave(bond, slave, i) {
1331 if (slave->dev) { 1357 if (!IS_UP(slave->dev))
1332 ops = slave->dev->netdev_ops; 1358 continue;
1333 if (ops->ndo_netpoll_cleanup) 1359 err = slave_enable_netpoll(slave);
1334 ops->ndo_netpoll_cleanup(slave->dev); 1360 if (err) {
1335 else 1361 __bond_netpoll_cleanup(bond);
1336 slave->dev->npinfo = NULL; 1362 break;
1337 } 1363 }
1338 } 1364 }
1339 read_unlock(&bond->lock); 1365 read_unlock(&bond->lock);
1366 return err;
1340} 1367}
1341 1368
1342#else 1369static struct netpoll_info *bond_netpoll_info(struct bonding *bond)
1370{
1371 return bond->dev->npinfo;
1372}
1343 1373
1374#else
1375static inline int slave_enable_netpoll(struct slave *slave)
1376{
1377 return 0;
1378}
1379static inline void slave_disable_netpoll(struct slave *slave)
1380{
1381}
1344static void bond_netpoll_cleanup(struct net_device *bond_dev) 1382static void bond_netpoll_cleanup(struct net_device *bond_dev)
1345{ 1383{
1346} 1384}
1347 1385static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
1386{
1387 return 0;
1388}
1389static struct netpoll_info *bond_netpoll_info(struct bonding *bond)
1390{
1391 return NULL;
1392}
1348#endif 1393#endif
1349 1394
1350/*---------------------------------- IOCTL ----------------------------------*/ 1395/*---------------------------------- IOCTL ----------------------------------*/
@@ -1782,17 +1827,19 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1782 bond_set_carrier(bond); 1827 bond_set_carrier(bond);
1783 1828
1784#ifdef CONFIG_NET_POLL_CONTROLLER 1829#ifdef CONFIG_NET_POLL_CONTROLLER
1785 if (slaves_support_netpoll(bond_dev)) { 1830 slave_dev->npinfo = bond_netpoll_info(bond);
1786 bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; 1831 if (slave_dev->npinfo) {
1787 if (bond_dev->npinfo) 1832 if (slave_enable_netpoll(new_slave)) {
1788 slave_dev->npinfo = bond_dev->npinfo; 1833 read_unlock(&bond->lock);
1789 } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { 1834 pr_info("Error, %s: master_dev is using netpoll, "
1790 bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; 1835 "but new slave device does not support netpoll.\n",
1791 pr_info("New slave device %s does not support netpoll\n", 1836 bond_dev->name);
1792 slave_dev->name); 1837 res = -EBUSY;
1793 pr_info("Disabling netpoll support for %s\n", bond_dev->name); 1838 goto err_close;
1839 }
1794 } 1840 }
1795#endif 1841#endif
1842
1796 read_unlock(&bond->lock); 1843 read_unlock(&bond->lock);
1797 1844
1798 res = bond_create_slave_symlinks(bond_dev, slave_dev); 1845 res = bond_create_slave_symlinks(bond_dev, slave_dev);
@@ -1994,17 +2041,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1994 2041
1995 netdev_set_bond_master(slave_dev, NULL); 2042 netdev_set_bond_master(slave_dev, NULL);
1996 2043
1997#ifdef CONFIG_NET_POLL_CONTROLLER 2044 slave_disable_netpoll(slave);
1998 read_lock_bh(&bond->lock);
1999
2000 if (slaves_support_netpoll(bond_dev))
2001 bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
2002 read_unlock_bh(&bond->lock);
2003 if (slave_dev->netdev_ops->ndo_netpoll_cleanup)
2004 slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev);
2005 else
2006 slave_dev->npinfo = NULL;
2007#endif
2008 2045
2009 /* close slave before restoring its mac address */ 2046 /* close slave before restoring its mac address */
2010 dev_close(slave_dev); 2047 dev_close(slave_dev);
@@ -2039,6 +2076,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev,
2039 2076
2040 ret = bond_release(bond_dev, slave_dev); 2077 ret = bond_release(bond_dev, slave_dev);
2041 if ((ret == 0) && (bond->slave_cnt == 0)) { 2078 if ((ret == 0) && (bond->slave_cnt == 0)) {
2079 bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
2042 pr_info("%s: destroying bond %s.\n", 2080 pr_info("%s: destroying bond %s.\n",
2043 bond_dev->name, bond_dev->name); 2081 bond_dev->name, bond_dev->name);
2044 unregister_netdevice(bond_dev); 2082 unregister_netdevice(bond_dev);
@@ -2116,6 +2154,8 @@ static int bond_release_all(struct net_device *bond_dev)
2116 2154
2117 netdev_set_bond_master(slave_dev, NULL); 2155 netdev_set_bond_master(slave_dev, NULL);
2118 2156
2157 slave_disable_netpoll(slave);
2158
2119 /* close slave before restoring its mac address */ 2159 /* close slave before restoring its mac address */
2120 dev_close(slave_dev); 2160 dev_close(slave_dev);
2121 2161
@@ -4654,6 +4694,7 @@ static const struct net_device_ops bond_netdev_ops = {
4654 .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, 4694 .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
4655 .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, 4695 .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
4656#ifdef CONFIG_NET_POLL_CONTROLLER 4696#ifdef CONFIG_NET_POLL_CONTROLLER
4697 .ndo_netpoll_setup = bond_netpoll_setup,
4657 .ndo_netpoll_cleanup = bond_netpoll_cleanup, 4698 .ndo_netpoll_cleanup = bond_netpoll_cleanup,
4658 .ndo_poll_controller = bond_poll_controller, 4699 .ndo_poll_controller = bond_poll_controller,
4659#endif 4700#endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 31fe980e4e28..0a3e00b220b7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -20,6 +20,7 @@
20#include <linux/if_bonding.h> 20#include <linux/if_bonding.h>
21#include <linux/cpumask.h> 21#include <linux/cpumask.h>
22#include <linux/in6.h> 22#include <linux/in6.h>
23#include <linux/netpoll.h>
23#include "bond_3ad.h" 24#include "bond_3ad.h"
24#include "bond_alb.h" 25#include "bond_alb.h"
25 26
@@ -198,6 +199,9 @@ struct slave {
198 u16 queue_id; 199 u16 queue_id;
199 struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ 200 struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
200 struct tlb_slave_info tlb_info; 201 struct tlb_slave_info tlb_info;
202#ifdef CONFIG_NET_POLL_CONTROLLER
203 struct netpoll *np;
204#endif
201}; 205};
202 206
203/* 207/*
@@ -323,6 +327,22 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
323 return slave->dev->last_rx; 327 return slave->dev->last_rx;
324} 328}
325 329
330#ifdef CONFIG_NET_POLL_CONTROLLER
331static inline void bond_netpoll_send_skb(const struct slave *slave,
332 struct sk_buff *skb)
333{
334 struct netpoll *np = slave->np;
335
336 if (np)
337 netpoll_send_skb(np, skb);
338}
339#else
340static inline void bond_netpoll_send_skb(const struct slave *slave,
341 struct sk_buff *skb)
342{
343}
344#endif
345
326static inline void bond_set_slave_inactive_flags(struct slave *slave) 346static inline void bond_set_slave_inactive_flags(struct slave *slave)
327{ 347{
328 struct bonding *bond = netdev_priv(slave->dev->master); 348 struct bonding *bond = netdev_priv(slave->dev->master);