Skip to content

Commit 8a8efa2

Browse files
Amerigo Wangdavem330
authored andcommitted
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 <[email protected]> Acked-by: Neil Horman <[email protected]> Cc: Herbert Xu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 70919e2 commit 8a8efa2

File tree

2 files changed

+118
-57
lines changed

2 files changed

+118
-57
lines changed

drivers/net/bonding/bond_main.c

Lines changed: 98 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
#include <linux/uaccess.h>
6060
#include <linux/errno.h>
6161
#include <linux/netdevice.h>
62-
#include <linux/netpoll.h>
6362
#include <linux/inetdevice.h>
6463
#include <linux/igmp.h>
6564
#include <linux/etherdevice.h>
@@ -424,15 +423,11 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
424423
{
425424
skb->dev = slave_dev;
426425
skb->priority = 1;
427-
#ifdef CONFIG_NET_POLL_CONTROLLER
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;
426+
if (unlikely(netpoll_tx_running(slave_dev))) {
431427
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);
433429
slave_dev->priv_flags &= ~IFF_IN_NETPOLL;
434430
} else
435-
#endif
436431
dev_queue_xmit(skb);
437432

438433
return 0;
@@ -1288,63 +1283,113 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
12881283
}
12891284

12901285
#ifdef CONFIG_NET_POLL_CONTROLLER
1291-
/*
1292-
* You must hold read lock on bond->lock before calling this.
1293-
*/
1294-
static bool slaves_support_netpoll(struct net_device *bond_dev)
1286+
static inline int slave_enable_netpoll(struct slave *slave)
12951287
{
1296-
struct bonding *bond = netdev_priv(bond_dev);
1297-
struct slave *slave;
1298-
int i = 0;
1299-
bool ret = true;
1288+
struct netpoll *np;
1289+
int err = 0;
13001290

1301-
bond_for_each_slave(bond, slave, i) {
1302-
if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL) ||
1303-
!slave->dev->netdev_ops->ndo_poll_controller)
1304-
ret = false;
1291+
np = kzalloc(sizeof(*np), GFP_KERNEL);
1292+
err = -ENOMEM;
1293+
if (!np)
1294+
goto out;
1295+
1296+
np->dev = slave->dev;
1297+
err = __netpoll_setup(np);
1298+
if (err) {
1299+
kfree(np);
1300+
goto out;
13051301
}
1306-
return i != 0 && ret;
1302+
slave->np = np;
1303+
out:
1304+
return err;
1305+
}
1306+
static 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+
}
1318+
static 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;
13071325
}
13081326

13091327
static void bond_poll_controller(struct net_device *bond_dev)
13101328
{
1311-
struct bonding *bond = netdev_priv(bond_dev);
1329+
}
1330+
1331+
static void __bond_netpoll_cleanup(struct bonding *bond)
1332+
{
13121333
struct slave *slave;
13131334
int i;
13141335

1315-
bond_for_each_slave(bond, slave, i) {
1316-
if (slave->dev && IS_UP(slave->dev))
1317-
netpoll_poll_dev(slave->dev);
1318-
}
1336+
bond_for_each_slave(bond, slave, i)
1337+
if (IS_UP(slave->dev))
1338+
slave_disable_netpoll(slave);
13191339
}
1320-
13211340
static void bond_netpoll_cleanup(struct net_device *bond_dev)
13221341
{
13231342
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+
1349+
static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
1350+
{
1351+
struct bonding *bond = netdev_priv(dev);
13241352
struct slave *slave;
1325-
const struct net_device_ops *ops;
1326-
int i;
1353+
int i, err = 0;
13271354

13281355
read_lock(&bond->lock);
1329-
bond_dev->npinfo = NULL;
13301356
bond_for_each_slave(bond, slave, i) {
1331-
if (slave->dev) {
1332-
ops = slave->dev->netdev_ops;
1333-
if (ops->ndo_netpoll_cleanup)
1334-
ops->ndo_netpoll_cleanup(slave->dev);
1335-
else
1336-
slave->dev->npinfo = NULL;
1357+
if (!IS_UP(slave->dev))
1358+
continue;
1359+
err = slave_enable_netpoll(slave);
1360+
if (err) {
1361+
__bond_netpoll_cleanup(bond);
1362+
break;
13371363
}
13381364
}
13391365
read_unlock(&bond->lock);
1366+
return err;
13401367
}
13411368

1342-
#else
1369+
static struct netpoll_info *bond_netpoll_info(struct bonding *bond)
1370+
{
1371+
return bond->dev->npinfo;
1372+
}
13431373

1374+
#else
1375+
static inline int slave_enable_netpoll(struct slave *slave)
1376+
{
1377+
return 0;
1378+
}
1379+
static inline void slave_disable_netpoll(struct slave *slave)
1380+
{
1381+
}
13441382
static void bond_netpoll_cleanup(struct net_device *bond_dev)
13451383
{
13461384
}
1347-
1385+
static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
1386+
{
1387+
return 0;
1388+
}
1389+
static struct netpoll_info *bond_netpoll_info(struct bonding *bond)
1390+
{
1391+
return NULL;
1392+
}
13481393
#endif
13491394

13501395
/*---------------------------------- IOCTL ----------------------------------*/
@@ -1782,17 +1827,19 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
17821827
bond_set_carrier(bond);
17831828

17841829
#ifdef CONFIG_NET_POLL_CONTROLLER
1785-
if (slaves_support_netpoll(bond_dev)) {
1786-
bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
1787-
if (bond_dev->npinfo)
1788-
slave_dev->npinfo = bond_dev->npinfo;
1789-
} else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) {
1790-
bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
1791-
pr_info("New slave device %s does not support netpoll\n",
1792-
slave_dev->name);
1793-
pr_info("Disabling netpoll support for %s\n", bond_dev->name);
1830+
slave_dev->npinfo = bond_netpoll_info(bond);
1831+
if (slave_dev->npinfo) {
1832+
if (slave_enable_netpoll(new_slave)) {
1833+
read_unlock(&bond->lock);
1834+
pr_info("Error, %s: master_dev is using netpoll, "
1835+
"but new slave device does not support netpoll.\n",
1836+
bond_dev->name);
1837+
res = -EBUSY;
1838+
goto err_close;
1839+
}
17941840
}
17951841
#endif
1842+
17961843
read_unlock(&bond->lock);
17971844

17981845
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)
19942041

19952042
netdev_set_bond_master(slave_dev, NULL);
19962043

1997-
#ifdef CONFIG_NET_POLL_CONTROLLER
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
2044+
slave_disable_netpoll(slave);
20082045

20092046
/* close slave before restoring its mac address */
20102047
dev_close(slave_dev);
@@ -2039,6 +2076,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev,
20392076

20402077
ret = bond_release(bond_dev, slave_dev);
20412078
if ((ret == 0) && (bond->slave_cnt == 0)) {
2079+
bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
20422080
pr_info("%s: destroying bond %s.\n",
20432081
bond_dev->name, bond_dev->name);
20442082
unregister_netdevice(bond_dev);
@@ -2116,6 +2154,8 @@ static int bond_release_all(struct net_device *bond_dev)
21162154

21172155
netdev_set_bond_master(slave_dev, NULL);
21182156

2157+
slave_disable_netpoll(slave);
2158+
21192159
/* close slave before restoring its mac address */
21202160
dev_close(slave_dev);
21212161

@@ -4654,6 +4694,7 @@ static const struct net_device_ops bond_netdev_ops = {
46544694
.ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
46554695
.ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
46564696
#ifdef CONFIG_NET_POLL_CONTROLLER
4697+
.ndo_netpoll_setup = bond_netpoll_setup,
46574698
.ndo_netpoll_cleanup = bond_netpoll_cleanup,
46584699
.ndo_poll_controller = bond_poll_controller,
46594700
#endif

drivers/net/bonding/bonding.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/if_bonding.h>
2121
#include <linux/cpumask.h>
2222
#include <linux/in6.h>
23+
#include <linux/netpoll.h>
2324
#include "bond_3ad.h"
2425
#include "bond_alb.h"
2526

@@ -198,6 +199,9 @@ struct slave {
198199
u16 queue_id;
199200
struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
200201
struct tlb_slave_info tlb_info;
202+
#ifdef CONFIG_NET_POLL_CONTROLLER
203+
struct netpoll *np;
204+
#endif
201205
};
202206

203207
/*
@@ -323,6 +327,22 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
323327
return slave->dev->last_rx;
324328
}
325329

330+
#ifdef CONFIG_NET_POLL_CONTROLLER
331+
static 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
340+
static inline void bond_netpoll_send_skb(const struct slave *slave,
341+
struct sk_buff *skb)
342+
{
343+
}
344+
#endif
345+
326346
static inline void bond_set_slave_inactive_flags(struct slave *slave)
327347
{
328348
struct bonding *bond = netdev_priv(slave->dev->master);

0 commit comments

Comments
 (0)