* [v4 Patch 2/3] bridge: make bridge support netpoll
2010-04-27 7:55 [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices Amerigo Wang
@ 2010-04-27 7:55 ` Amerigo Wang
2010-04-27 22:23 ` David Miller
2010-04-27 7:56 ` [v4 Patch 3/3] bonding: make bonding " Amerigo Wang
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Amerigo Wang @ 2010-04-27 7:55 UTC (permalink / raw)
To: linux-kernel
Cc: Stephen Hemminger, netdev, bridge, Andy Gospodarek, Neil Horman,
Amerigo Wang, Jeff Moyer, Matt Mackall, bonding-devel,
Jay Vosburgh, David Miller
Based on the previous patch, make bridge support netpoll by:
1) implement the 2 methods to support netpoll for bridge;
2) modify netpoll during forwarding packets via bridge;
3) disable netpoll support of bridge when a netpoll-unabled device
is added to bridge;
4) enable netpoll support when all underlying devices support netpoll.
Cc: David Miller <davem@davemloft.net>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Stephen Hemminger <shemminger@linux-foundation.org>
Cc: Matt Mackall <mpm@selenic.com>
Signed-off-by: WANG Cong <amwang@redhat.com>
---
Index: linux-2.6/net/bridge/br_device.c
===================================================================
--- linux-2.6.orig/net/bridge/br_device.c
+++ linux-2.6/net/bridge/br_device.c
@@ -13,8 +13,10 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/netpoll.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
+#include <linux/list.h>
#include <asm/uaccess.h>
#include "br_private.h"
@@ -162,6 +164,59 @@ static int br_set_tx_csum(struct net_dev
return 0;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+bool br_devices_support_netpoll(struct net_bridge *br)
+{
+ struct net_bridge_port *p;
+ bool ret = true;
+ int count = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&br->lock, flags);
+ list_for_each_entry(p, &br->port_list, list) {
+ count++;
+ if (p->dev->priv_flags & IFF_DISABLE_NETPOLL
+ || !p->dev->netdev_ops->ndo_poll_controller)
+ ret = false;
+ }
+ spin_unlock_irqrestore(&br->lock, flags);
+ return count != 0 && ret;
+}
+
+static void br_poll_controller(struct net_device *br_dev)
+{
+ struct netpoll *np = br_dev->npinfo->netpoll;
+
+ if (np->real_dev != br_dev)
+ netpoll_poll_dev(np->real_dev);
+}
+
+void br_netpoll_cleanup(struct net_device *br_dev)
+{
+ struct net_bridge *br = netdev_priv(br_dev);
+ struct net_bridge_port *p, *n;
+ const struct net_device_ops *ops;
+
+ br->dev->npinfo = NULL;
+ list_for_each_entry_safe(p, n, &br->port_list, list) {
+ if (p->dev) {
+ ops = p->dev->netdev_ops;
+ if (ops->ndo_netpoll_cleanup)
+ ops->ndo_netpoll_cleanup(p->dev);
+ else
+ p->dev->npinfo = NULL;
+ }
+ }
+}
+
+#else
+
+void br_netpoll_cleanup(struct net_device *br_dev)
+{
+}
+
+#endif
+
static const struct ethtool_ops br_ethtool_ops = {
.get_drvinfo = br_getinfo,
.get_link = ethtool_op_get_link,
@@ -184,6 +239,10 @@ static const struct net_device_ops br_ne
.ndo_set_multicast_list = br_dev_set_multicast_list,
.ndo_change_mtu = br_change_mtu,
.ndo_do_ioctl = br_dev_ioctl,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_netpoll_cleanup = br_netpoll_cleanup,
+ .ndo_poll_controller = br_poll_controller,
+#endif
};
void br_dev_setup(struct net_device *dev)
Index: linux-2.6/net/bridge/br_forward.c
===================================================================
--- linux-2.6.orig/net/bridge/br_forward.c
+++ linux-2.6/net/bridge/br_forward.c
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/netpoll.h>
#include <linux/skbuff.h>
#include <linux/if_vlan.h>
#include <linux/netfilter_bridge.h>
@@ -50,7 +51,13 @@ int br_dev_queue_push_xmit(struct sk_buf
else {
skb_push(skb, ETH_HLEN);
- dev_queue_xmit(skb);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (unlikely(skb->dev->priv_flags & IFF_IN_NETPOLL)) {
+ netpoll_send_skb(skb->dev->npinfo->netpoll, skb);
+ skb->dev->priv_flags &= ~IFF_IN_NETPOLL;
+ } else
+#endif
+ dev_queue_xmit(skb);
}
}
@@ -66,9 +73,23 @@ int br_forward_finish(struct sk_buff *sk
static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
{
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ struct net_bridge *br = to->br;
+ if (unlikely(br->dev->priv_flags & IFF_IN_NETPOLL)) {
+ struct netpoll *np;
+ to->dev->npinfo = skb->dev->npinfo;
+ np = skb->dev->npinfo->netpoll;
+ np->real_dev = np->dev = to->dev;
+ to->dev->priv_flags |= IFF_IN_NETPOLL;
+ }
+#endif
skb->dev = to->dev;
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
br_forward_finish);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (skb->dev->npinfo)
+ skb->dev->npinfo->netpoll->dev = br->dev;
+#endif
}
static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
Index: linux-2.6/net/bridge/br_if.c
===================================================================
--- linux-2.6.orig/net/bridge/br_if.c
+++ linux-2.6/net/bridge/br_if.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
+#include <linux/netpoll.h>
#include <linux/ethtool.h>
#include <linux/if_arp.h>
#include <linux/module.h>
@@ -153,6 +154,14 @@ static void del_nbp(struct net_bridge_po
kobject_uevent(&p->kobj, KOBJ_REMOVE);
kobject_del(&p->kobj);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (br_devices_support_netpoll(br))
+ br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ if (dev->netdev_ops->ndo_netpoll_cleanup)
+ dev->netdev_ops->ndo_netpoll_cleanup(dev);
+ else
+ dev->npinfo = NULL;
+#endif
call_rcu(&p->rcu, destroy_nbp_rcu);
}
@@ -165,6 +174,8 @@ static void del_br(struct net_bridge *br
del_nbp(p);
}
+ br_netpoll_cleanup(br->dev);
+
del_timer_sync(&br->gc_timer);
br_sysfs_delbr(br->dev);
@@ -438,6 +449,20 @@ int br_add_if(struct net_bridge *br, str
kobject_uevent(&p->kobj, KOBJ_ADD);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (br_devices_support_netpoll(br)) {
+ br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ if (br->dev->npinfo)
+ dev->npinfo = br->dev->npinfo;
+ } else if (!(br->dev->priv_flags & IFF_DISABLE_NETPOLL)) {
+ br->dev->priv_flags |= IFF_DISABLE_NETPOLL;
+ printk(KERN_INFO "New device %s does not support netpoll\n",
+ dev->name);
+ printk(KERN_INFO "Disabling netpoll for %s\n",
+ br->dev->name);
+ }
+#endif
+
return 0;
err2:
br_fdb_delete_by_port(br, p, 1);
Index: linux-2.6/net/bridge/br_private.h
===================================================================
--- linux-2.6.orig/net/bridge/br_private.h
+++ linux-2.6/net/bridge/br_private.h
@@ -233,6 +233,8 @@ static inline int br_is_root_bridge(cons
extern void br_dev_setup(struct net_device *dev);
extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
struct net_device *dev);
+extern bool br_devices_support_netpoll(struct net_bridge *br);
+extern void br_netpoll_cleanup(struct net_device *br_dev);
/* br_fdb.c */
extern int br_fdb_init(void);
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [v4 Patch 2/3] bridge: make bridge support netpoll
2010-04-27 7:55 ` [v4 Patch 2/3] bridge: make bridge support netpoll Amerigo Wang
@ 2010-04-27 22:23 ` David Miller
0 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2010-04-27 22:23 UTC (permalink / raw)
To: amwang
Cc: linux-kernel, shemminger, netdev, bridge, gospo, nhorman, jmoyer,
mpm, bonding-devel, fubar
From: Amerigo Wang <amwang@redhat.com>
Date: Tue, 27 Apr 2010 03:55:56 -0400
> + if (p->dev->priv_flags & IFF_DISABLE_NETPOLL
> + || !p->dev->netdev_ops->ndo_poll_controller)
"||" goes on first line, and indentation on second line is incorrect.
See my comments from patch #1.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [v4 Patch 3/3] bonding: make bonding support netpoll
2010-04-27 7:55 [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices Amerigo Wang
2010-04-27 7:55 ` [v4 Patch 2/3] bridge: make bridge support netpoll Amerigo Wang
@ 2010-04-27 7:56 ` Amerigo Wang
2010-04-27 22:24 ` David Miller
2010-04-27 22:22 ` [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices David Miller
2010-04-28 4:02 ` Dongdong Deng
3 siblings, 1 reply; 9+ messages in thread
From: Amerigo Wang @ 2010-04-27 7:56 UTC (permalink / raw)
To: linux-kernel
Cc: Matt Mackall, netdev, bridge, Andy Gospodarek, Neil Horman,
Amerigo Wang, Jeff Moyer, Stephen Hemminger, bonding-devel,
Jay Vosburgh, David Miller
Based on Andy's work, but I modified a lot.
Similar to the patch for bridge, this patch does:
1) implement the 2 methods to support netpoll for bonding;
2) modify netpoll during forwarding packets via bonding;
3) disable netpoll support of bonding when a netpoll-unabled device
is added to bonding;
4) enable netpoll support when all underlying devices support netpoll.
Cc: Andy Gospodarek <gospo@redhat.com>
Cc: Jeff Moyer <jmoyer@redhat.com>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Jay Vosburgh <fubar@us.ibm.com>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: WANG Cong <amwang@redhat.com>
---
Index: linux-2.6/drivers/net/bonding/bond_main.c
===================================================================
--- linux-2.6.orig/drivers/net/bonding/bond_main.c
+++ linux-2.6/drivers/net/bonding/bond_main.c
@@ -59,6 +59,7 @@
#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
+#include <linux/netpoll.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/etherdevice.h>
@@ -430,7 +431,18 @@ int bond_dev_queue_xmit(struct bonding *
}
skb->priority = 1;
- dev_queue_xmit(skb);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
+ struct netpoll *np = bond->dev->npinfo->netpoll;
+ slave_dev->npinfo = bond->dev->npinfo;
+ np->real_dev = np->dev = skb->dev;
+ slave_dev->priv_flags |= IFF_IN_NETPOLL;
+ netpoll_send_skb(np, skb);
+ slave_dev->priv_flags &= ~IFF_IN_NETPOLL;
+ np->dev = bond->dev;
+ } else
+#endif
+ dev_queue_xmit(skb);
return 0;
}
@@ -1329,6 +1341,61 @@ static void bond_detach_slave(struct bon
bond->slave_cnt--;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * You must hold read lock on bond->lock before calling this.
+ */
+static bool slaves_support_netpoll(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
+ int i = 0;
+ bool ret = true;
+
+ bond_for_each_slave(bond, slave, i) {
+ if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL)
+ || !slave->dev->netdev_ops->ndo_poll_controller)
+ ret = false;
+ }
+ return i != 0 && ret;
+}
+
+static void bond_poll_controller(struct net_device *bond_dev)
+{
+ struct net_device *dev = bond_dev->npinfo->netpoll->real_dev;
+ if (dev != bond_dev)
+ netpoll_poll_dev(dev);
+}
+
+static void bond_netpoll_cleanup(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
+ const struct net_device_ops *ops;
+ int i;
+
+ read_lock(&bond->lock);
+ bond_dev->npinfo = NULL;
+ bond_for_each_slave(bond, slave, i) {
+ if (slave->dev) {
+ ops = slave->dev->netdev_ops;
+ if (ops->ndo_netpoll_cleanup)
+ ops->ndo_netpoll_cleanup(slave->dev);
+ else
+ slave->dev->npinfo = NULL;
+ }
+ }
+ read_unlock(&bond->lock);
+}
+
+#else
+
+static void bond_netpoll_cleanup(struct net_device *bond_dev)
+{
+}
+
+#endif
+
/*---------------------------------- IOCTL ----------------------------------*/
static int bond_sethwaddr(struct net_device *bond_dev,
@@ -1735,6 +1802,18 @@ int bond_enslave(struct net_device *bond
bond_set_carrier(bond);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ if (slaves_support_netpoll(bond_dev)) {
+ bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ if (bond_dev->npinfo)
+ slave_dev->npinfo = bond_dev->npinfo;
+ } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) {
+ bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
+ pr_info("New slave device %s does not support netpoll\n",
+ slave_dev->name);
+ pr_info("Disabling netpoll support for %s\n", bond_dev->name);
+ }
+#endif
read_unlock(&bond->lock);
res = bond_create_slave_symlinks(bond_dev, slave_dev);
@@ -1801,6 +1880,7 @@ int bond_release(struct net_device *bond
return -EINVAL;
}
+ netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE);
write_lock_bh(&bond->lock);
slave = bond_get_slave_by_dev(bond, slave_dev);
@@ -1929,6 +2009,17 @@ int bond_release(struct net_device *bond
netdev_set_master(slave_dev, NULL);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ read_lock_bh(&bond->lock);
+ if (slaves_support_netpoll(bond_dev))
+ bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL;
+ read_unlock_bh(&bond->lock);
+ if (slave_dev->netdev_ops->ndo_netpoll_cleanup)
+ slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev);
+ else
+ slave_dev->npinfo = NULL;
+#endif
+
/* close slave before restoring its mac address */
dev_close(slave_dev);
@@ -4448,6 +4539,10 @@ static const struct net_device_ops bond_
.ndo_vlan_rx_register = bond_vlan_rx_register,
.ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_netpoll_cleanup = bond_netpoll_cleanup,
+ .ndo_poll_controller = bond_poll_controller,
+#endif
};
static void bond_destructor(struct net_device *bond_dev)
@@ -4541,6 +4636,8 @@ static void bond_uninit(struct net_devic
{
struct bonding *bond = netdev_priv(bond_dev);
+ bond_netpoll_cleanup(bond_dev);
+
/* Release the bonded slaves */
bond_release_all(bond_dev);
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [v4 Patch 3/3] bonding: make bonding support netpoll
2010-04-27 7:56 ` [v4 Patch 3/3] bonding: make bonding " Amerigo Wang
@ 2010-04-27 22:24 ` David Miller
2010-04-28 2:08 ` Cong Wang
0 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2010-04-27 22:24 UTC (permalink / raw)
To: amwang
Cc: linux-kernel, mpm, netdev, bridge, gospo, nhorman, jmoyer,
shemminger, bonding-devel, fubar
From: Amerigo Wang <amwang@redhat.com>
Date: Tue, 27 Apr 2010 03:56:09 -0400
> + if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL)
> + || !slave->dev->netdev_ops->ndo_poll_controller)
"|| on first line please, plus fix second line's indentation as per
comments given in patch #1 and #2
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [v4 Patch 3/3] bonding: make bonding support netpoll
2010-04-27 22:24 ` David Miller
@ 2010-04-28 2:08 ` Cong Wang
0 siblings, 0 replies; 9+ messages in thread
From: Cong Wang @ 2010-04-28 2:08 UTC (permalink / raw)
To: David Miller
Cc: linux-kernel, mpm, netdev, bridge, gospo, nhorman, jmoyer,
shemminger, bonding-devel, fubar
David Miller wrote:
> From: Amerigo Wang <amwang@redhat.com>
> Date: Tue, 27 Apr 2010 03:56:09 -0400
>
>> + if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL)
>> + || !slave->dev->netdev_ops->ndo_poll_controller)
>
> "|| on first line please, plus fix second line's indentation as per
> comments given in patch #1 and #2
Thanks, David!
I will fix all of this style problem.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices
2010-04-27 7:55 [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices Amerigo Wang
2010-04-27 7:55 ` [v4 Patch 2/3] bridge: make bridge support netpoll Amerigo Wang
2010-04-27 7:56 ` [v4 Patch 3/3] bonding: make bonding " Amerigo Wang
@ 2010-04-27 22:22 ` David Miller
2010-04-28 4:02 ` Dongdong Deng
3 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2010-04-27 22:22 UTC (permalink / raw)
To: amwang
Cc: linux-kernel, mpm, netdev, bridge, gospo, nhorman, jmoyer,
shemminger, bonding-devel, fubar
From: Amerigo Wang <amwang@redhat.com>
Date: Tue, 27 Apr 2010 03:55:41 -0400
> + if (ndev->priv_flags & IFF_DISABLE_NETPOLL
> + || !ndev->netdev_ops->ndo_poll_controller) {
" ||" goes on first line, not second, and second line needs to be indented
properly so that "!ndev->..." matches up with "ndev->priv_flags ..." on
the previous line.
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices
2010-04-27 7:55 [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices Amerigo Wang
` (2 preceding siblings ...)
2010-04-27 22:22 ` [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices David Miller
@ 2010-04-28 4:02 ` Dongdong Deng
2010-04-28 9:59 ` Cong Wang
3 siblings, 1 reply; 9+ messages in thread
From: Dongdong Deng @ 2010-04-28 4:02 UTC (permalink / raw)
To: Amerigo Wang
Cc: linux-kernel, Matt Mackall, netdev, bridge, Andy Gospodarek,
Neil Horman, Jeff Moyer, Stephen Hemminger, bonding-devel,
Jay Vosburgh, David Miller
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 12016 bytes --]
On Tue, Apr 27, 2010 at 3:55 PM, Amerigo Wang <amwang@redhat.com> wrote:> V4:> Use "unlikely" to mark netpoll call path, suggested by Stephen.> Handle NETDEV_GOING_DOWN case.>> V3:> Update to latest Linus' tree.> Fix deadlocks when releasing slaves of bonding devices.> Thanks to Andy.>> V2:> Fix some bugs of previous version.> Remove ->netpoll_setup and ->netpoll_xmit, they are not necessary.> Don't poll all underlying devices, poll ->real_dev in struct netpoll.> Thanks to David for suggesting above.>> ------------>>> This whole patchset is for adding netpoll support to bridge and bonding> devices. I already tested it for bridge, bonding, bridge over bonding,> and bonding over bridge. It looks fine now.>>> To make bridge and bonding support netpoll, we need to adjust> some netpoll generic code. This patch does the following things:>> 1) introduce two new priv_flags for struct net_device:>  IFF_IN_NETPOLL which identifies we are processing a netpoll;>  IFF_DISABLE_NETPOLL is used to disable netpoll support for a device>  at run-time;>> 2) introduce one new method for netdev_ops:>  ->ndo_netpoll_cleanup() is used to clean up netpoll when a device is>   removed.>> 3) introduce netpoll_poll_dev() which takes a struct net_device * parameter;>  export netpoll_send_skb() and netpoll_poll_dev() which will be used later;>> 4) hide a pointer to struct netpoll in struct netpoll_info, ditto.>> 5) introduce ->real_dev for struct netpoll.>> 6) introduce a new status NETDEV_BONDING_DESLAE, which is used to disable>  netconsole before releasing a slave, to avoid deadlocks.>> Cc: David Miller <davem@davemloft.net>> Cc: Neil Horman <nhorman@tuxdriver.com>> Signed-off-by: WANG Cong <amwang@redhat.com>>> --->> Index: linux-2.6/include/linux/if.h> ===================================================================> --- linux-2.6.orig/include/linux/if.h> +++ linux-2.6/include/linux/if.h> @@ -71,6 +71,8 @@>                     * release skb->dst>                     */>  #define IFF_DONT_BRIDGE 0x800      /* disallow bridging this ether dev */> +#define IFF_IN_NETPOLL 0x1000      /* whether we are processing netpoll */> +#define IFF_DISABLE_NETPOLL   0x2000  /* disable netpoll at run-time */>>  #define IF_GET_IFACE  0x0001      /* for querying only */>  #define IF_GET_PROTO  0x0002> Index: linux-2.6/include/linux/netdevice.h> ===================================================================> --- linux-2.6.orig/include/linux/netdevice.h> +++ linux-2.6/include/linux/netdevice.h> @@ -667,6 +667,7 @@ struct net_device_ops {>                             unsigned short vid);>  #ifdef CONFIG_NET_POLL_CONTROLLER>     void           (*ndo_poll_controller)(struct net_device *dev);> +    void           (*ndo_netpoll_cleanup)(struct net_device *dev);>  #endif>     int           (*ndo_set_vf_mac)(struct net_device *dev,>                          int queue, u8 *mac);> Index: linux-2.6/include/linux/netpoll.h> ===================================================================> --- linux-2.6.orig/include/linux/netpoll.h> +++ linux-2.6/include/linux/netpoll.h> @@ -14,6 +14,7 @@>>  struct netpoll {>     struct net_device *dev;> +    struct net_device *real_dev;>     char dev_name[IFNAMSIZ];>     const char *name;>     void (*rx_hook)(struct netpoll *, int, char *, int);> @@ -36,8 +37,11 @@ struct netpoll_info {>     struct sk_buff_head txq;>>     struct delayed_work tx_work;> +> +    struct netpoll *netpoll;>  };>> +void netpoll_poll_dev(struct net_device *dev);>  void netpoll_poll(struct netpoll *np);>  void netpoll_send_udp(struct netpoll *np, const char *msg, int len);>  void netpoll_print_options(struct netpoll *np);> @@ -47,6 +51,7 @@ int netpoll_trap(void);>  void netpoll_set_trap(int trap);>  void netpoll_cleanup(struct netpoll *np);>  int __netpoll_rx(struct sk_buff *skb);> +void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);>>>  #ifdef CONFIG_NETPOLL> Index: linux-2.6/net/core/netpoll.c> ===================================================================> --- linux-2.6.orig/net/core/netpoll.c> +++ linux-2.6/net/core/netpoll.c> @@ -179,9 +179,8 @@ static void service_arp_queue(struct net>     }>  }>> -void netpoll_poll(struct netpoll *np)> +void netpoll_poll_dev(struct net_device *dev)>  {> -    struct net_device *dev = np->dev;>     const struct net_device_ops *ops;>>     if (!dev || !netif_running(dev))> @@ -201,6 +200,11 @@ void netpoll_poll(struct netpoll *np)>     zap_completion_queue();>  }>> +void netpoll_poll(struct netpoll *np)> +{> +    netpoll_poll_dev(np->dev);> +}> +>  static void refill_skbs(void)>  {>     struct sk_buff *skb;> @@ -282,7 +286,7 @@ static int netpoll_owner_active(struct n>     return 0;>  }>> -static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)> +void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)>  {>     int status = NETDEV_TX_BUSY;>     unsigned long tries;> @@ -308,7 +312,9 @@ static void netpoll_send_skb(struct netp>           tries > 0; --tries) {>             if (__netif_tx_trylock(txq)) {>                 if (!netif_tx_queue_stopped(txq)) {> +                    dev->priv_flags |= IFF_IN_NETPOLL;>                     status = ops->ndo_start_xmit(skb, dev);> +                    dev->priv_flags &= ~IFF_IN_NETPOLL;>                     if (status == NETDEV_TX_OK)>                         txq_trans_update(txq);>                 }> @@ -756,7 +762,10 @@ int netpoll_setup(struct netpoll *np)>         atomic_inc(&npinfo->refcnt);>     }>> -    if (!ndev->netdev_ops->ndo_poll_controller) {> +    npinfo->netpoll = np;> +> +    if (ndev->priv_flags & IFF_DISABLE_NETPOLL> +            || !ndev->netdev_ops->ndo_poll_controller) {>         printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",>            np->name, np->dev_name);>         err = -ENOTSUPP;> @@ -878,6 +887,7 @@ void netpoll_cleanup(struct netpoll *np)>             }>>             if (atomic_dec_and_test(&npinfo->refcnt)) {> +                const struct net_device_ops *ops;>                 skb_queue_purge(&npinfo->arp_tx);>                 skb_queue_purge(&npinfo->txq);>                 cancel_rearming_delayed_work(&npinfo->tx_work);> @@ -885,7 +895,11 @@ void netpoll_cleanup(struct netpoll *np)>                 /* clean after last, unfinished work */>                 __skb_queue_purge(&npinfo->txq);>                 kfree(npinfo);> -                np->dev->npinfo = NULL;> +                ops = np->dev->netdev_ops;> +                if (ops->ndo_netpoll_cleanup)> +                    ops->ndo_netpoll_cleanup(np->dev);> +                else> +                    np->dev->npinfo = NULL;
+ if (ops->ndo_netpoll_cleanup)+ ops->ndo_netpoll_cleanup(np->dev);+ np->dev->npinfo = NULL;
I think it is good to set np->dev->npinfo to NULL even though we havethe netpoll_cleanup opt.
RegardsDongdong
>             }>         }>> @@ -908,6 +922,7 @@ void netpoll_set_trap(int trap)>         atomic_dec(&trapped);>  }>> +EXPORT_SYMBOL(netpoll_send_skb);>  EXPORT_SYMBOL(netpoll_set_trap);>  EXPORT_SYMBOL(netpoll_trap);>  EXPORT_SYMBOL(netpoll_print_options);> @@ -915,4 +930,5 @@ EXPORT_SYMBOL(netpoll_parse_options);>  EXPORT_SYMBOL(netpoll_setup);>  EXPORT_SYMBOL(netpoll_cleanup);>  EXPORT_SYMBOL(netpoll_send_udp);> +EXPORT_SYMBOL(netpoll_poll_dev);>  EXPORT_SYMBOL(netpoll_poll);> Index: linux-2.6/drivers/net/netconsole.c> ===================================================================> --- linux-2.6.orig/drivers/net/netconsole.c> +++ linux-2.6/drivers/net/netconsole.c> @@ -665,7 +665,8 @@ static int netconsole_netdev_event(struc>     struct netconsole_target *nt;>     struct net_device *dev = ptr;>> -    if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER))> +    if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||> +       event == NETDEV_BONDING_DESLAVE || event == NETDEV_GOING_DOWN))>         goto done;>>     spin_lock_irqsave(&target_list_lock, flags);> @@ -677,19 +678,21 @@ static int netconsole_netdev_event(struc>                 strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);>                 break;>             case NETDEV_UNREGISTER:> -                if (!nt->enabled)> -                    break;>                 netpoll_cleanup(&nt->np);> +                /* Fall through */> +            case NETDEV_GOING_DOWN:> +            case NETDEV_BONDING_DESLAVE:>                 nt->enabled = 0;> -                printk(KERN_INFO "netconsole: network logging stopped"> -                    ", interface %s unregistered\n",> -                    dev->name);>                 break;>             }>         }>         netconsole_target_put(nt);>     }>     spin_unlock_irqrestore(&target_list_lock, flags);> +    if (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE)> +        printk(KERN_INFO "netconsole: network logging stopped, "> +            "interface %s %s\n",  dev->name,> +            event == NETDEV_UNREGISTER ? "unregistered" : "released slaves");>>  done:>     return NOTIFY_DONE;> Index: linux-2.6/include/linux/notifier.h> ===================================================================> --- linux-2.6.orig/include/linux/notifier.h> +++ linux-2.6/include/linux/notifier.h> @@ -203,6 +203,7 @@ static inline int notifier_to_errno(int>  #define NETDEV_BONDING_NEWTYPE  0x000F>  #define NETDEV_POST_INIT    0x0010>  #define NETDEV_UNREGISTER_BATCH 0x0011> +#define NETDEV_BONDING_DESLAVE  0x0012>>  #define SYS_DOWN    0x0001  /* Notify of system down */>  #define SYS_RESTART   SYS_DOWN> --> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in> the body of a message to majordomo@vger.kernel.org> More majordomo info at  http://vger.kernel.org/majordomo-info.html> Please read the FAQ at  http://www.tux.org/lkml/>ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [v4 Patch 1/3] netpoll: add generic support for bridge and bonding devices
2010-04-28 4:02 ` Dongdong Deng
@ 2010-04-28 9:59 ` Cong Wang
0 siblings, 0 replies; 9+ messages in thread
From: Cong Wang @ 2010-04-28 9:59 UTC (permalink / raw)
To: Dongdong Deng
Cc: linux-kernel, Matt Mackall, netdev, bridge, Andy Gospodarek,
Neil Horman, Jeff Moyer, Stephen Hemminger, bonding-devel,
Jay Vosburgh, David Miller
Dongdong Deng wrote:
>
>
> + if (ops->ndo_netpoll_cleanup)
> + ops->ndo_netpoll_cleanup(np->dev);
> + np->dev->npinfo = NULL;
>
> I think it is good to set np->dev->npinfo to NULL even though we have
> the netpoll_cleanup opt.
>
This is redundant, since ->ndo_netpoll_cleanup will set it.
Thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread