network device ops phase 1
Subsystems (3)
RFC 1/1 network device ops phase 1
This early work on a series of patches to separate the management portions of the network device (immutable function pointers) from the data structure part of the network device.
This patch involves some hackery to maintain compatablity between the new and old model, so all 300+ drivers don't have to be changed at once. There are two copies of the same function pointers during the transistional step. As the transistion is completed the nag message can be changed to an WARN_ON, and the compatiablity code can be made configurable.
A couple function pointers aren't moved:
* destructor can't be in net_device_ops because it may need to be referenced after the module is unloaded.
* hard_start_xmit is in the fast path for transmit.
--- include/linux/if.h | 3 + include/linux/netdevice.h | 213 +++++++++++++++++++++++++++++++++------------ net/Kconfig | 3 + net/core/dev.c | 109 +++++++++++++++++------- net/core/neighbour.c | 3 +- net/core/netpoll.c | 7 +- net/sched/sch_generic.c | 4 +- 7 files changed, 250 insertions(+), 92 deletions(-)
include/linux/if.h +3 -0
@@ -67,6 +67,8 @@#define IFF_ISATAP 0x80/* ISATAP interface (RFC4214) */ #define IFF_MASTER_ARPMON 0x100/* bonding master, ARP mon in use */ +#define IFF_NETDEV_OPS 0x8000/* network devices ops allocated */ +#define IF_GET_IFACE 0x0001/* for querying only */ #define IF_GET_PROTO 0x0002
@@ -94,6 +96,7 @@#define IF_PROTO_FR_ETH_PVC 0x200B#define IF_PROTO_RAW 0x200C/* RAW Socket */ +/* RFC 2863 operational status */ enum {IF_OPER_UNKNOWN ,
include/linux/netdevice.h +157 -56
278 lines not on this page · raw message
net/Kconfig +3 -0
@@ -32,6 +32,9 @@ config NET_NS Allow user space to create what appear to be multiple instances of the network stack. +config COMPAT_NET_DEV_OPS + def_bool y + source "net/packet/Kconfig" source "net/unix/Kconfig" source "net/xfrm/Kconfig"
net/core/dev.c +79 -30
247 lines not on this page · raw message
net/core/neighbour.c +2 -1
@@ -1330,6 +1330,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, {struct neigh_parms *p, *ref;struct net *net; +const struct net_device_ops *ops = dev->netdev_ops; net =dev_net (dev); ref =lookup_neigh_params (tbl, net,0 );
@@ -1343,7 +1344,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, p->reachable_time =neigh_rand_reach_time (p->base_reachable_time); -if (dev->neigh_setup && dev->neigh_setup (dev, p)) { +if (ops->neigh_setup && ops->neigh_setup (dev, p)) {kfree (p);return NULL ; }
net/core/netpoll.c +4 -3
@@ -172,12 +172,13 @@ static void service_arp_queue(struct netpoll_info *npi)void netpoll_poll (struct netpoll *np) {struct net_device *dev = np->dev; +const struct net_device_ops *ops = dev->netdev_ops; -if (!dev || !netif_running (dev) || !dev->poll_controller) +if (!dev || !netif_running (dev) || !ops->poll_controller)return ;/* Process pending work on NIC */ - dev->poll_controller (dev); + ops->poll_controller (dev);poll_napi (dev);
@@ -694,7 +695,7 @@ int netpoll_setup(struct netpoll *np)atomic_inc (&npinfo->refcnt); } -if (!ndev->poll_controller) { +if (!ndev->netdev_ops->poll_controller) {printk (KERN_ERR "%s: %s doesn't support polling, aborting.\n" , np->name, np->dev_name); err = -ENOTSUPP ;
net/sched/sch_generic.c +2 -2
@@ -224,7 +224,7 @@ static void dev_watchdog(unsigned long arg)char drivername[64 ];WARN_ONCE (1 ,KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n" , dev->name,netdev_drivername (dev, drivername,64 )); - dev->tx_timeout (dev); + dev->netdev_ops->tx_timeout (dev); } if (!mod_timer(&dev->watchdog_timer, round_jiffies(jiffies +
@@ -239,7 +239,7 @@ static void dev_watchdog(unsigned long arg) void __netdev_watchdog_up(struct net_device *dev) { - if (dev->tx_timeout) { + if (dev->netdev_ops->tx_timeout) { if (dev->watchdog_timeo <= 0) dev->watchdog_timeo = 5*HZ; if (!mod_timer(&dev->watchdog_timer,
Signature · 1 line
1.5.4.3
David Miller
maintainerFrom: Stephen Hemminger <[email protected]>
Date: Fri, 7 Nov 2008 15:50:23 -0800
Quoted 3 lines
This early work on a series of patches to separate the management portions of the network device (immutable function pointers) from the data structure part of the network device.
...
I think this is a good way to attack this kind of transition.
Fix the build errors, do some testing, and please resubmit:
net/core/dev.c: In function ‘register_netdevice’:net/core/dev.c:4075: error: ‘struct net_device_ops’ has no member named ‘poll_controller’ net/core/dev.c:4075: error: ‘struct net_device’ has no member named ‘poll_controller’ make[2]: *** [net/core/dev.o] Error 1
make[1]: *** [net/core] Error 2
make: *** [net] Error 2
make: *** Waiting for unfinished jobs....
Thanks.
Quoted 20 lines · On Mon, 10 Nov 2008 17:02:11 -0800 (PST) David Miller <[email protected]>…
From: Stephen Hemminger <[email protected]>
Date: Fri, 7 Nov 2008 15:50:23 -0800Quoted 3 lines
This early work on a series of patches to separate the management portions of the network device (immutable function pointers) from the data structure part of the network device.
...
I think this is a good way to attack this kind of transition.
Fix the build errors, do some testing, and please resubmit:
net/core/dev.c: In function ‘register_netdevice’:net/core/dev.c:4075: error: ‘struct net_device_ops’ has no member named ‘poll_controller’net/core/dev.c:4075: error: ‘struct net_device’ has no member named ‘poll_controller’ make[2]: *** [net/core/dev.o] Error 1
make[1]: *** [net/core] Error 2
make: *** [net] Error 2
make: *** Waiting for unfinished jobs....
Quoted 1 line
Thanks.
This is one case where I wish GCC had more C++ style anonymous structures so the following would work, and avoid the copying and allocation.
struct net_device_ops {
int (*init)(struct net_device *);
...
};
struct net_device {
...
#ifdef CONFIG_COMPAT_XXX
struct net_device_ops;
#endif
struct net_device_ops *ops;
};
void register_netdevice(struct net_device *dev)
{
...
#ifdef CONFIG_COMPAT_XXX
if (ops == NULL) {
printk("loser device %s", dev->name);
dev->ops = (struct net_device_ops *) dev->init;
}#endif
}
include/linux/netdevice.h struct netdev_queue { · line 457
Quoted 4 lines · Stephen Hemminger
include/linux/netdevice.h +4
-0+ +/* +* This structure defines the management hooks for network devices. +* The following hooks can bed defined and are optonal (can be null)
s/bed/be/, /optonal/optional/
Quoted 3 lines
+ * unless otherwise noted.
+ *
- k