Commit 951fe07e authored by David S. Miller's avatar David S. Miller

[NET]: Kill NETIF_F_DYNALLOC, based upon ideas from Adam J. Richter

parent d9707786
...@@ -2214,6 +2214,11 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st) ...@@ -2214,6 +2214,11 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
* and for initialization. * and for initialization.
*/ */
static void ppp_device_destructor(struct net_device *dev)
{
kfree(dev);
}
/* /*
* Create a new ppp interface unit. Fails if it can't allocate memory * Create a new ppp interface unit. Fails if it can't allocate memory
* or if there is already a unit with the requested number. * or if there is already a unit with the requested number.
...@@ -2262,7 +2267,7 @@ ppp_create_interface(int unit, int *retp) ...@@ -2262,7 +2267,7 @@ ppp_create_interface(int unit, int *retp)
dev->init = ppp_net_init; dev->init = ppp_net_init;
sprintf(dev->name, "ppp%d", unit); sprintf(dev->name, "ppp%d", unit);
dev->priv = ppp; dev->priv = ppp;
dev->features |= NETIF_F_DYNALLOC; dev->destructor = ppp_device_destructor;
rtnl_lock(); rtnl_lock();
ret = register_netdevice(dev); ret = register_netdevice(dev);
......
...@@ -365,7 +365,6 @@ struct net_device ...@@ -365,7 +365,6 @@ struct net_device
#define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */ #define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
#define NETIF_F_DYNALLOC 16 /* Self-dectructable device. */
#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */ #define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */ #define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */
#define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */ #define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */
......
...@@ -433,7 +433,6 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -433,7 +433,6 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
/* set up method calls */ /* set up method calls */
new_dev->init = vlan_dev_init; new_dev->init = vlan_dev_init;
new_dev->destructor = vlan_dev_destruct; new_dev->destructor = vlan_dev_destruct;
new_dev->features |= NETIF_F_DYNALLOC ;
/* new_dev->ifindex = 0; it will be set when added to /* new_dev->ifindex = 0; it will be set when added to
* the global list. * the global list.
......
...@@ -785,6 +785,7 @@ void vlan_dev_destruct(struct net_device *dev) ...@@ -785,6 +785,7 @@ void vlan_dev_destruct(struct net_device *dev)
kfree(dev->priv); kfree(dev->priv);
dev->priv = NULL; dev->priv = NULL;
} }
kfree(dev);
} }
} }
......
...@@ -2639,12 +2639,10 @@ int netdev_finish_unregister(struct net_device *dev) ...@@ -2639,12 +2639,10 @@ int netdev_finish_unregister(struct net_device *dev)
} }
#ifdef NET_REFCNT_DEBUG #ifdef NET_REFCNT_DEBUG
printk(KERN_DEBUG "netdev_finish_unregister: %s%s.\n", dev->name, printk(KERN_DEBUG "netdev_finish_unregister: %s%s.\n", dev->name,
(dev->features & NETIF_F_DYNALLOC)?"":", old style"); (dev->destructor != NULL)?"":", old style");
#endif #endif
if (dev->destructor) if (dev->destructor)
dev->destructor(dev); dev->destructor(dev);
if (dev->features & NETIF_F_DYNALLOC)
kfree(dev);
return 0; return 0;
} }
...@@ -2724,7 +2722,7 @@ int unregister_netdevice(struct net_device *dev) ...@@ -2724,7 +2722,7 @@ int unregister_netdevice(struct net_device *dev)
free_divert_blk(dev); free_divert_blk(dev);
#endif #endif
if (dev->features & NETIF_F_DYNALLOC) { if (dev->destructor != NULL) {
#ifdef NET_REFCNT_DEBUG #ifdef NET_REFCNT_DEBUG
if (atomic_read(&dev->refcnt) != 1) if (atomic_read(&dev->refcnt) != 1)
printk(KERN_DEBUG "unregister_netdevice: holding %s " printk(KERN_DEBUG "unregister_netdevice: holding %s "
......
...@@ -228,7 +228,7 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void ...@@ -228,7 +228,7 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void
_race_ _condition_. _race_ _condition_.
*/ */
if (event!=NETDEV_DOWN && if (event!=NETDEV_DOWN &&
!(dev->features & NETIF_F_DYNALLOC) && dev->destructor == NULL &&
dst->output == dst_blackhole) { dst->output == dst_blackhole) {
dst->dev = &loopback_dev; dst->dev = &loopback_dev;
dev_put(dev); dev_put(dev);
......
...@@ -273,7 +273,6 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -273,7 +273,6 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
nt->dev = dev; nt->dev = dev;
dev->init = ipgre_tunnel_init; dev->init = ipgre_tunnel_init;
dev->features |= NETIF_F_DYNALLOC;
memcpy(&nt->parms, parms, sizeof(*parms)); memcpy(&nt->parms, parms, sizeof(*parms));
nt->parms.name[IFNAMSIZ-1] = '\0'; nt->parms.name[IFNAMSIZ-1] = '\0';
strcpy(dev->name, nt->parms.name); strcpy(dev->name, nt->parms.name);
...@@ -305,6 +304,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -305,6 +304,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int
static void ipgre_tunnel_destructor(struct net_device *dev) static void ipgre_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipgre_fb_tunnel_dev) { if (dev != &ipgre_fb_tunnel_dev) {
kfree(dev);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
} }
......
...@@ -242,7 +242,6 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -242,7 +242,6 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
nt->dev = dev; nt->dev = dev;
dev->init = ipip_tunnel_init; dev->init = ipip_tunnel_init;
dev->features |= NETIF_F_DYNALLOC;
memcpy(&nt->parms, parms, sizeof(*parms)); memcpy(&nt->parms, parms, sizeof(*parms));
nt->parms.name[IFNAMSIZ-1] = '\0'; nt->parms.name[IFNAMSIZ-1] = '\0';
strcpy(dev->name, nt->parms.name); strcpy(dev->name, nt->parms.name);
...@@ -274,6 +273,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) ...@@ -274,6 +273,7 @@ struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
static void ipip_tunnel_destructor(struct net_device *dev) static void ipip_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipip_fb_tunnel_dev) { if (dev != &ipip_fb_tunnel_dev) {
kfree(dev);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
} }
......
...@@ -182,6 +182,11 @@ static struct net_device_stats *reg_vif_get_stats(struct net_device *dev) ...@@ -182,6 +182,11 @@ static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
return (struct net_device_stats*)dev->priv; return (struct net_device_stats*)dev->priv;
} }
static void vif_dev_destructor(struct net_device *dev)
{
kfree(dev);
}
static static
struct net_device *ipmr_reg_vif(struct vifctl *v) struct net_device *ipmr_reg_vif(struct vifctl *v)
{ {
...@@ -205,7 +210,7 @@ struct net_device *ipmr_reg_vif(struct vifctl *v) ...@@ -205,7 +210,7 @@ struct net_device *ipmr_reg_vif(struct vifctl *v)
dev->flags = IFF_NOARP; dev->flags = IFF_NOARP;
dev->hard_start_xmit = reg_vif_xmit; dev->hard_start_xmit = reg_vif_xmit;
dev->get_stats = reg_vif_get_stats; dev->get_stats = reg_vif_get_stats;
dev->features |= NETIF_F_DYNALLOC; dev->destructor = vif_dev_destructor;
if (register_netdevice(dev)) { if (register_netdevice(dev)) {
kfree(dev); kfree(dev);
......
...@@ -181,7 +181,6 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -181,7 +181,6 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
nt = (struct ip_tunnel*)dev->priv; nt = (struct ip_tunnel*)dev->priv;
nt->dev = dev; nt->dev = dev;
dev->init = ipip6_tunnel_init; dev->init = ipip6_tunnel_init;
dev->features |= NETIF_F_DYNALLOC;
memcpy(&nt->parms, parms, sizeof(*parms)); memcpy(&nt->parms, parms, sizeof(*parms));
nt->parms.name[IFNAMSIZ-1] = '\0'; nt->parms.name[IFNAMSIZ-1] = '\0';
strcpy(dev->name, nt->parms.name); strcpy(dev->name, nt->parms.name);
...@@ -213,6 +212,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int ...@@ -213,6 +212,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
static void ipip6_tunnel_destructor(struct net_device *dev) static void ipip6_tunnel_destructor(struct net_device *dev)
{ {
if (dev != &ipip6_fb_tunnel_dev) { if (dev != &ipip6_fb_tunnel_dev) {
kfree(dev);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
} }
......
...@@ -372,6 +372,11 @@ static void irda_task_timer_expired(void *data) ...@@ -372,6 +372,11 @@ static void irda_task_timer_expired(void *data)
irda_task_kick(task); irda_task_kick(task);
} }
static void irda_device_destructor(struct net_device *dev)
{
kfree(dev);
}
/* /*
* Function irda_device_setup (dev) * Function irda_device_setup (dev)
* *
...@@ -385,8 +390,7 @@ int irda_device_setup(struct net_device *dev) ...@@ -385,8 +390,7 @@ int irda_device_setup(struct net_device *dev)
dev->hard_header_len = 0; dev->hard_header_len = 0;
dev->addr_len = 0; dev->addr_len = 0;
dev->features |= NETIF_F_DYNALLOC; dev->destructor = irda_device_destructor;
/* dev->destructor = irda_device_destructor; */
dev->type = ARPHRD_IRDA; dev->type = ARPHRD_IRDA;
dev->tx_queue_len = 8; /* Window size + 1 s-frame */ dev->tx_queue_len = 8; /* Window size + 1 s-frame */
......
...@@ -62,16 +62,6 @@ int irlan_eth_init(struct net_device *dev) ...@@ -62,16 +62,6 @@ int irlan_eth_init(struct net_device *dev)
dev->get_stats = irlan_eth_get_stats; dev->get_stats = irlan_eth_get_stats;
dev->set_multicast_list = irlan_eth_set_multicast_list; dev->set_multicast_list = irlan_eth_set_multicast_list;
/* NETIF_F_DYNALLOC feature was set by irlan_eth_init() and would
* cause the unregister_netdev() to do asynch completion _and_
* kfree self->dev afterwards. Which is really bad because the
* netdevice was not allocated separately but is embedded in
* our control block and therefore gets freed with *self.
* The only reason why this would have been enabled is to hide
* some netdev refcount issues. If unregister_netdev() blocks
* forever, tell us about it... */
//dev->features |= NETIF_F_DYNALLOC;
ether_setup(dev); ether_setup(dev);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment