summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_main.c6
-rw-r--r--drivers/net/caif/caif_hsi.c2
-rw-r--r--drivers/net/caif/caif_serial.c2
-rw-r--r--drivers/net/caif/caif_spi.c2
-rw-r--r--drivers/net/caif/caif_virtio.c2
-rw-r--r--drivers/net/can/slcan.c7
-rw-r--r--drivers/net/can/vcan.c2
-rw-r--r--drivers/net/can/vxcan.c2
-rw-r--r--drivers/net/dummy.c4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c2
-rw-r--r--drivers/net/geneve.c2
-rw-r--r--drivers/net/gtp.c2
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/bpqether.c2
-rw-r--r--drivers/net/ifb.c4
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c2
-rw-r--r--drivers/net/loopback.c4
-rw-r--r--drivers/net/macsec.c4
-rw-r--r--drivers/net/macvlan.c2
-rw-r--r--drivers/net/nlmon.c2
-rw-r--r--drivers/net/slip/slip.c7
-rw-r--r--drivers/net/team/team.c4
-rw-r--r--drivers/net/tun.c4
-rw-r--r--drivers/net/usb/cdc-phonet.c2
-rw-r--r--drivers/net/usb/qmi_wwan.c2
-rw-r--r--drivers/net/veth.c4
-rw-r--r--drivers/net/vrf.c2
-rw-r--r--drivers/net/vsockmon.c2
-rw-r--r--drivers/net/vxlan.c2
-rw-r--r--drivers/net/wan/dlci.c2
-rw-r--r--drivers/net/wan/hdlc_fr.c2
-rw-r--r--drivers/net/wan/lapbether.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c3
-rw-r--r--drivers/net/wireless/intersil/hostap/hostap_main.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.c2
-rw-r--r--drivers/staging/rtl8188eu/os_dep/mon.c2
-rw-r--r--drivers/usb/gadget/function/f_phonet.c2
-rw-r--r--include/linux/netdevice.h7
-rw-r--r--net/8021q/vlan_dev.c4
-rw-r--r--net/batman-adv/soft-interface.c5
-rw-r--r--net/bluetooth/6lowpan.c2
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/caif/chnl_net.c4
-rw-r--r--net/core/dev.c8
-rw-r--r--net/hsr/hsr_device.c4
-rw-r--r--net/ieee802154/6lowpan/core.c2
-rw-r--r--net/ipv4/ip_tunnel.c4
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv6/ip6_gre.c9
-rw-r--r--net/ipv6/ip6_tunnel.c8
-rw-r--r--net/ipv6/ip6_vti.c8
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/sit.c6
-rw-r--r--net/irda/irlan/irlan_eth.c2
-rw-r--r--net/l2tp/l2tp_eth.c2
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac802154/iface.c7
-rw-r--r--net/openvswitch/vport-internal_dev.c4
-rw-r--r--net/phonet/pep-gprs.c2
62 files changed, 105 insertions, 103 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2359478b977f..8ab6bdbe1682 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4192,7 +4192,6 @@ static void bond_destructor(struct net_device *bond_dev)
4192 struct bonding *bond = netdev_priv(bond_dev); 4192 struct bonding *bond = netdev_priv(bond_dev);
4193 if (bond->wq) 4193 if (bond->wq)
4194 destroy_workqueue(bond->wq); 4194 destroy_workqueue(bond->wq);
4195 free_netdev(bond_dev);
4196} 4195}
4197 4196
4198void bond_setup(struct net_device *bond_dev) 4197void bond_setup(struct net_device *bond_dev)
@@ -4212,7 +4211,8 @@ void bond_setup(struct net_device *bond_dev)
4212 bond_dev->netdev_ops = &bond_netdev_ops; 4211 bond_dev->netdev_ops = &bond_netdev_ops;
4213 bond_dev->ethtool_ops = &bond_ethtool_ops; 4212 bond_dev->ethtool_ops = &bond_ethtool_ops;
4214 4213
4215 bond_dev->destructor = bond_destructor; 4214 bond_dev->needs_free_netdev = true;
4215 bond_dev->priv_destructor = bond_destructor;
4216 4216
4217 SET_NETDEV_DEVTYPE(bond_dev, &bond_type); 4217 SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
4218 4218
@@ -4736,7 +4736,7 @@ int bond_create(struct net *net, const char *name)
4736 4736
4737 rtnl_unlock(); 4737 rtnl_unlock();
4738 if (res < 0) 4738 if (res < 0)
4739 bond_destructor(bond_dev); 4739 free_netdev(bond_dev);
4740 return res; 4740 return res;
4741} 4741}
4742 4742
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index ddabce759456..71a7c3b44fdd 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -1121,7 +1121,7 @@ static void cfhsi_setup(struct net_device *dev)
1121 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 1121 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
1122 dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ; 1122 dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
1123 dev->priv_flags |= IFF_NO_QUEUE; 1123 dev->priv_flags |= IFF_NO_QUEUE;
1124 dev->destructor = free_netdev; 1124 dev->needs_free_netdev = true;
1125 dev->netdev_ops = &cfhsi_netdevops; 1125 dev->netdev_ops = &cfhsi_netdevops;
1126 for (i = 0; i < CFHSI_PRIO_LAST; ++i) 1126 for (i = 0; i < CFHSI_PRIO_LAST; ++i)
1127 skb_queue_head_init(&cfhsi->qhead[i]); 1127 skb_queue_head_init(&cfhsi->qhead[i]);
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
index c2dea4916e5d..76e1d3545105 100644
--- a/drivers/net/caif/caif_serial.c
+++ b/drivers/net/caif/caif_serial.c
@@ -428,7 +428,7 @@ static void caifdev_setup(struct net_device *dev)
428 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 428 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
429 dev->mtu = CAIF_MAX_MTU; 429 dev->mtu = CAIF_MAX_MTU;
430 dev->priv_flags |= IFF_NO_QUEUE; 430 dev->priv_flags |= IFF_NO_QUEUE;
431 dev->destructor = free_netdev; 431 dev->needs_free_netdev = true;
432 skb_queue_head_init(&serdev->head); 432 skb_queue_head_init(&serdev->head);
433 serdev->common.link_select = CAIF_LINK_LOW_LATENCY; 433 serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
434 serdev->common.use_frag = true; 434 serdev->common.use_frag = true;
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index 3a529fbe539f..fc21afe852b9 100644
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -712,7 +712,7 @@ static void cfspi_setup(struct net_device *dev)
712 dev->flags = IFF_NOARP | IFF_POINTOPOINT; 712 dev->flags = IFF_NOARP | IFF_POINTOPOINT;
713 dev->priv_flags |= IFF_NO_QUEUE; 713 dev->priv_flags |= IFF_NO_QUEUE;
714 dev->mtu = SPI_MAX_PAYLOAD_SIZE; 714 dev->mtu = SPI_MAX_PAYLOAD_SIZE;
715 dev->destructor = free_netdev; 715 dev->needs_free_netdev = true;
716 skb_queue_head_init(&cfspi->qhead); 716 skb_queue_head_init(&cfspi->qhead);
717 skb_queue_head_init(&cfspi->chead); 717 skb_queue_head_init(&cfspi->chead);
718 cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW; 718 cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
index 6122768c8644..1794ea0420b7 100644
--- a/drivers/net/caif/caif_virtio.c
+++ b/drivers/net/caif/caif_virtio.c
@@ -617,7 +617,7 @@ static void cfv_netdev_setup(struct net_device *netdev)
617 netdev->tx_queue_len = 100; 617 netdev->tx_queue_len = 100;
618 netdev->flags = IFF_POINTOPOINT | IFF_NOARP; 618 netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
619 netdev->mtu = CFV_DEF_MTU_SIZE; 619 netdev->mtu = CFV_DEF_MTU_SIZE;
620 netdev->destructor = free_netdev; 620 netdev->needs_free_netdev = true;
621} 621}
622 622
623/* Create debugfs counters for the device */ 623/* Create debugfs counters for the device */
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index eb7173713bbc..6a6e896e52fa 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -417,7 +417,7 @@ static int slc_open(struct net_device *dev)
417static void slc_free_netdev(struct net_device *dev) 417static void slc_free_netdev(struct net_device *dev)
418{ 418{
419 int i = dev->base_addr; 419 int i = dev->base_addr;
420 free_netdev(dev); 420
421 slcan_devs[i] = NULL; 421 slcan_devs[i] = NULL;
422} 422}
423 423
@@ -436,7 +436,8 @@ static const struct net_device_ops slc_netdev_ops = {
436static void slc_setup(struct net_device *dev) 436static void slc_setup(struct net_device *dev)
437{ 437{
438 dev->netdev_ops = &slc_netdev_ops; 438 dev->netdev_ops = &slc_netdev_ops;
439 dev->destructor = slc_free_netdev; 439 dev->needs_free_netdev = true;
440 dev->priv_destructor = slc_free_netdev;
440 441
441 dev->hard_header_len = 0; 442 dev->hard_header_len = 0;
442 dev->addr_len = 0; 443 dev->addr_len = 0;
@@ -761,8 +762,6 @@ static void __exit slcan_exit(void)
761 if (sl->tty) { 762 if (sl->tty) {
762 printk(KERN_ERR "%s: tty discipline still running\n", 763 printk(KERN_ERR "%s: tty discipline still running\n",
763 dev->name); 764 dev->name);
764 /* Intentionally leak the control block. */
765 dev->destructor = NULL;
766 } 765 }
767 766
768 unregister_netdev(dev); 767 unregister_netdev(dev);
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index facca33d53e9..0eda1b308583 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -163,7 +163,7 @@ static void vcan_setup(struct net_device *dev)
163 dev->flags |= IFF_ECHO; 163 dev->flags |= IFF_ECHO;
164 164
165 dev->netdev_ops = &vcan_netdev_ops; 165 dev->netdev_ops = &vcan_netdev_ops;
166 dev->destructor = free_netdev; 166 dev->needs_free_netdev = true;
167} 167}
168 168
169static struct rtnl_link_ops vcan_link_ops __read_mostly = { 169static struct rtnl_link_ops vcan_link_ops __read_mostly = {
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index 7fbb24795681..30cf2368becf 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -156,7 +156,7 @@ static void vxcan_setup(struct net_device *dev)
156 dev->tx_queue_len = 0; 156 dev->tx_queue_len = 0;
157 dev->flags = (IFF_NOARP|IFF_ECHO); 157 dev->flags = (IFF_NOARP|IFF_ECHO);
158 dev->netdev_ops = &vxcan_netdev_ops; 158 dev->netdev_ops = &vxcan_netdev_ops;
159 dev->destructor = free_netdev; 159 dev->needs_free_netdev = true;
160} 160}
161 161
162/* forward declaration for rtnl_create_link() */ 162/* forward declaration for rtnl_create_link() */
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 149244aac20a..9905b52fe293 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -328,7 +328,6 @@ static void dummy_free_netdev(struct net_device *dev)
328 struct dummy_priv *priv = netdev_priv(dev); 328 struct dummy_priv *priv = netdev_priv(dev);
329 329
330 kfree(priv->vfinfo); 330 kfree(priv->vfinfo);
331 free_netdev(dev);
332} 331}
333 332
334static void dummy_setup(struct net_device *dev) 333static void dummy_setup(struct net_device *dev)
@@ -338,7 +337,8 @@ static void dummy_setup(struct net_device *dev)
338 /* Initialize the device structure. */ 337 /* Initialize the device structure. */
339 dev->netdev_ops = &dummy_netdev_ops; 338 dev->netdev_ops = &dummy_netdev_ops;
340 dev->ethtool_ops = &dummy_ethtool_ops; 339 dev->ethtool_ops = &dummy_ethtool_ops;
341 dev->destructor = dummy_free_netdev; 340 dev->needs_free_netdev = true;
341 dev->priv_destructor = dummy_free_netdev;
342 342
343 /* Fill in device structure with ethernet-generic values. */ 343 /* Fill in device structure with ethernet-generic values. */
344 dev->flags |= IFF_NOARP; 344 dev->flags |= IFF_NOARP;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 77ed2f628f9c..ea1bfcf1870a 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -4525,7 +4525,7 @@ static void dummy_setup(struct net_device *dev)
4525 /* Initialize the device structure. */ 4525 /* Initialize the device structure. */
4526 dev->netdev_ops = &cxgb4_mgmt_netdev_ops; 4526 dev->netdev_ops = &cxgb4_mgmt_netdev_ops;
4527 dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops; 4527 dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops;
4528 dev->destructor = free_netdev; 4528 dev->needs_free_netdev = true;
4529} 4529}
4530 4530
4531static int config_mgmt_dev(struct pci_dev *pdev) 4531static int config_mgmt_dev(struct pci_dev *pdev)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 6ebb0f559a42..199459bd6961 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1007,7 +1007,7 @@ static void geneve_setup(struct net_device *dev)
1007 1007
1008 dev->netdev_ops = &geneve_netdev_ops; 1008 dev->netdev_ops = &geneve_netdev_ops;
1009 dev->ethtool_ops = &geneve_ethtool_ops; 1009 dev->ethtool_ops = &geneve_ethtool_ops;
1010 dev->destructor = free_netdev; 1010 dev->needs_free_netdev = true;
1011 1011
1012 SET_NETDEV_DEVTYPE(dev, &geneve_type); 1012 SET_NETDEV_DEVTYPE(dev, &geneve_type);
1013 1013
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 7b652bb7ebe4..ca110cd2a4e4 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -611,7 +611,7 @@ static const struct net_device_ops gtp_netdev_ops = {
611static void gtp_link_setup(struct net_device *dev) 611static void gtp_link_setup(struct net_device *dev)
612{ 612{
613 dev->netdev_ops = &gtp_netdev_ops; 613 dev->netdev_ops = &gtp_netdev_ops;
614 dev->destructor = free_netdev; 614 dev->needs_free_netdev = true;
615 615
616 dev->hard_header_len = 0; 616 dev->hard_header_len = 0;
617 dev->addr_len = 0; 617 dev->addr_len = 0;
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 922bf440e9f1..021a8ec411ab 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -311,7 +311,7 @@ static void sp_setup(struct net_device *dev)
311{ 311{
312 /* Finish setting up the DEVICE info. */ 312 /* Finish setting up the DEVICE info. */
313 dev->netdev_ops = &sp_netdev_ops; 313 dev->netdev_ops = &sp_netdev_ops;
314 dev->destructor = free_netdev; 314 dev->needs_free_netdev = true;
315 dev->mtu = SIXP_MTU; 315 dev->mtu = SIXP_MTU;
316 dev->hard_header_len = AX25_MAX_HEADER_LEN; 316 dev->hard_header_len = AX25_MAX_HEADER_LEN;
317 dev->header_ops = &ax25_header_ops; 317 dev->header_ops = &ax25_header_ops;
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index f62e7f325cf9..78a6414c5fd9 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -476,7 +476,7 @@ static const struct net_device_ops bpq_netdev_ops = {
476static void bpq_setup(struct net_device *dev) 476static void bpq_setup(struct net_device *dev)
477{ 477{
478 dev->netdev_ops = &bpq_netdev_ops; 478 dev->netdev_ops = &bpq_netdev_ops;
479 dev->destructor = free_netdev; 479 dev->needs_free_netdev = true;
480 480
481 memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); 481 memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
482 memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN); 482 memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 312fce7302d3..144ea5ae8ab4 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -207,7 +207,6 @@ static void ifb_dev_free(struct net_device *dev)
207 __skb_queue_purge(&txp->tq); 207 __skb_queue_purge(&txp->tq);
208 } 208 }
209 kfree(dp->tx_private); 209 kfree(dp->tx_private);
210 free_netdev(dev);
211} 210}
212 211
213static void ifb_setup(struct net_device *dev) 212static void ifb_setup(struct net_device *dev)
@@ -230,7 +229,8 @@ static void ifb_setup(struct net_device *dev)
230 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 229 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
231 netif_keep_dst(dev); 230 netif_keep_dst(dev);
232 eth_hw_addr_random(dev); 231 eth_hw_addr_random(dev);
233 dev->destructor = ifb_dev_free; 232 dev->needs_free_netdev = true;
233 dev->priv_destructor = ifb_dev_free;
234} 234}
235 235
236static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) 236static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 618ed88fad0f..7c7680c8f0e3 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -632,7 +632,7 @@ void ipvlan_link_setup(struct net_device *dev)
632 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); 632 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
633 dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE; 633 dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE;
634 dev->netdev_ops = &ipvlan_netdev_ops; 634 dev->netdev_ops = &ipvlan_netdev_ops;
635 dev->destructor = free_netdev; 635 dev->needs_free_netdev = true;
636 dev->header_ops = &ipvlan_header_ops; 636 dev->header_ops = &ipvlan_header_ops;
637 dev->ethtool_ops = &ipvlan_ethtool_ops; 637 dev->ethtool_ops = &ipvlan_ethtool_ops;
638} 638}
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 224f65cb576b..30612497643c 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -159,7 +159,6 @@ static void loopback_dev_free(struct net_device *dev)
159{ 159{
160 dev_net(dev)->loopback_dev = NULL; 160 dev_net(dev)->loopback_dev = NULL;
161 free_percpu(dev->lstats); 161 free_percpu(dev->lstats);
162 free_netdev(dev);
163} 162}
164 163
165static const struct net_device_ops loopback_ops = { 164static const struct net_device_ops loopback_ops = {
@@ -196,7 +195,8 @@ static void loopback_setup(struct net_device *dev)
196 dev->ethtool_ops = &loopback_ethtool_ops; 195 dev->ethtool_ops = &loopback_ethtool_ops;
197 dev->header_ops = &eth_header_ops; 196 dev->header_ops = &eth_header_ops;
198 dev->netdev_ops = &loopback_ops; 197 dev->netdev_ops = &loopback_ops;
199 dev->destructor = loopback_dev_free; 198 dev->needs_free_netdev = true;
199 dev->priv_destructor = loopback_dev_free;
200} 200}
201 201
202/* Setup and register the loopback device. */ 202/* Setup and register the loopback device. */
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index cdc347be68f2..79411675f0e6 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2996,7 +2996,6 @@ static void macsec_free_netdev(struct net_device *dev)
2996 free_percpu(macsec->secy.tx_sc.stats); 2996 free_percpu(macsec->secy.tx_sc.stats);
2997 2997
2998 dev_put(real_dev); 2998 dev_put(real_dev);
2999 free_netdev(dev);
3000} 2999}
3001 3000
3002static void macsec_setup(struct net_device *dev) 3001static void macsec_setup(struct net_device *dev)
@@ -3006,7 +3005,8 @@ static void macsec_setup(struct net_device *dev)
3006 dev->max_mtu = ETH_MAX_MTU; 3005 dev->max_mtu = ETH_MAX_MTU;
3007 dev->priv_flags |= IFF_NO_QUEUE; 3006 dev->priv_flags |= IFF_NO_QUEUE;
3008 dev->netdev_ops = &macsec_netdev_ops; 3007 dev->netdev_ops = &macsec_netdev_ops;
3009 dev->destructor = macsec_free_netdev; 3008 dev->needs_free_netdev = true;
3009 dev->priv_destructor = macsec_free_netdev;
3010 SET_NETDEV_DEVTYPE(dev, &macsec_type); 3010 SET_NETDEV_DEVTYPE(dev, &macsec_type);
3011 3011
3012 eth_zero_addr(dev->broadcast); 3012 eth_zero_addr(dev->broadcast);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 346ad2ff3998..67bf7ebae5c6 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1092,7 +1092,7 @@ void macvlan_common_setup(struct net_device *dev)
1092 netif_keep_dst(dev); 1092 netif_keep_dst(dev);
1093 dev->priv_flags |= IFF_UNICAST_FLT; 1093 dev->priv_flags |= IFF_UNICAST_FLT;
1094 dev->netdev_ops = &macvlan_netdev_ops; 1094 dev->netdev_ops = &macvlan_netdev_ops;
1095 dev->destructor = free_netdev; 1095 dev->needs_free_netdev = true;
1096 dev->header_ops = &macvlan_hard_header_ops; 1096 dev->header_ops = &macvlan_hard_header_ops;
1097 dev->ethtool_ops = &macvlan_ethtool_ops; 1097 dev->ethtool_ops = &macvlan_ethtool_ops;
1098} 1098}
diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c
index b91603835d26..c4b3362da4a2 100644
--- a/drivers/net/nlmon.c
+++ b/drivers/net/nlmon.c
@@ -113,7 +113,7 @@ static void nlmon_setup(struct net_device *dev)
113 113
114 dev->netdev_ops = &nlmon_ops; 114 dev->netdev_ops = &nlmon_ops;
115 dev->ethtool_ops = &nlmon_ethtool_ops; 115 dev->ethtool_ops = &nlmon_ethtool_ops;
116 dev->destructor = free_netdev; 116 dev->needs_free_netdev = true;
117 117
118 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | 118 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
119 NETIF_F_HIGHDMA | NETIF_F_LLTX; 119 NETIF_F_HIGHDMA | NETIF_F_LLTX;
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index 1da31dc47f86..74b907206aa7 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -629,7 +629,7 @@ static void sl_uninit(struct net_device *dev)
629static void sl_free_netdev(struct net_device *dev) 629static void sl_free_netdev(struct net_device *dev)
630{ 630{
631 int i = dev->base_addr; 631 int i = dev->base_addr;
632 free_netdev(dev); 632
633 slip_devs[i] = NULL; 633 slip_devs[i] = NULL;
634} 634}
635 635
@@ -651,7 +651,8 @@ static const struct net_device_ops sl_netdev_ops = {
651static void sl_setup(struct net_device *dev) 651static void sl_setup(struct net_device *dev)
652{ 652{
653 dev->netdev_ops = &sl_netdev_ops; 653 dev->netdev_ops = &sl_netdev_ops;
654 dev->destructor = sl_free_netdev; 654 dev->needs_free_netdev = true;
655 dev->priv_destructor = sl_free_netdev;
655 656
656 dev->hard_header_len = 0; 657 dev->hard_header_len = 0;
657 dev->addr_len = 0; 658 dev->addr_len = 0;
@@ -1369,8 +1370,6 @@ static void __exit slip_exit(void)
1369 if (sl->tty) { 1370 if (sl->tty) {
1370 printk(KERN_ERR "%s: tty discipline still running\n", 1371 printk(KERN_ERR "%s: tty discipline still running\n",
1371 dev->name); 1372 dev->name);
1372 /* Intentionally leak the control block. */
1373 dev->destructor = NULL;
1374 } 1373 }
1375 1374
1376 unregister_netdev(dev); 1375 unregister_netdev(dev);
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 6c5d5ef46f75..fba8c136aa7c 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1643,7 +1643,6 @@ static void team_destructor(struct net_device *dev)
1643 struct team *team = netdev_priv(dev); 1643 struct team *team = netdev_priv(dev);
1644 1644
1645 free_percpu(team->pcpu_stats); 1645 free_percpu(team->pcpu_stats);
1646 free_netdev(dev);
1647} 1646}
1648 1647
1649static int team_open(struct net_device *dev) 1648static int team_open(struct net_device *dev)
@@ -2079,7 +2078,8 @@ static void team_setup(struct net_device *dev)
2079 2078
2080 dev->netdev_ops = &team_netdev_ops; 2079 dev->netdev_ops = &team_netdev_ops;
2081 dev->ethtool_ops = &team_ethtool_ops; 2080 dev->ethtool_ops = &team_ethtool_ops;
2082 dev->destructor = team_destructor; 2081 dev->needs_free_netdev = true;
2082 dev->priv_destructor = team_destructor;
2083 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); 2083 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
2084 dev->priv_flags |= IFF_NO_QUEUE; 2084 dev->priv_flags |= IFF_NO_QUEUE;
2085 dev->priv_flags |= IFF_TEAM; 2085 dev->priv_flags |= IFF_TEAM;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index bbd707b9ef7a..9ee7d4275640 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1560,7 +1560,6 @@ static void tun_free_netdev(struct net_device *dev)
1560 free_percpu(tun->pcpu_stats); 1560 free_percpu(tun->pcpu_stats);
1561 tun_flow_uninit(tun); 1561 tun_flow_uninit(tun);
1562 security_tun_dev_free_security(tun->security); 1562 security_tun_dev_free_security(tun->security);
1563 free_netdev(dev);
1564} 1563}
1565 1564
1566static void tun_setup(struct net_device *dev) 1565static void tun_setup(struct net_device *dev)
@@ -1571,7 +1570,8 @@ static void tun_setup(struct net_device *dev)
1571 tun->group = INVALID_GID; 1570 tun->group = INVALID_GID;
1572 1571
1573 dev->ethtool_ops = &tun_ethtool_ops; 1572 dev->ethtool_ops = &tun_ethtool_ops;
1574 dev->destructor = tun_free_netdev; 1573 dev->needs_free_netdev = true;
1574 dev->priv_destructor = tun_free_netdev;
1575 /* We prefer our own queue length */ 1575 /* We prefer our own queue length */
1576 dev->tx_queue_len = TUN_READQ_SIZE; 1576 dev->tx_queue_len = TUN_READQ_SIZE;
1577} 1577}
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
index eb52de8205f0..c7a350bbaaa7 100644
--- a/drivers/net/usb/cdc-phonet.c
+++ b/drivers/net/usb/cdc-phonet.c
@@ -298,7 +298,7 @@ static void usbpn_setup(struct net_device *dev)
298 dev->addr_len = 1; 298 dev->addr_len = 1;
299 dev->tx_queue_len = 3; 299 dev->tx_queue_len = 3;
300 300
301 dev->destructor = free_netdev; 301 dev->needs_free_netdev = true;
302} 302}
303 303
304/* 304/*
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 8f923a147fa9..949671ce4039 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -123,7 +123,7 @@ static void qmimux_setup(struct net_device *dev)
123 dev->addr_len = 0; 123 dev->addr_len = 0;
124 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; 124 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
125 dev->netdev_ops = &qmimux_netdev_ops; 125 dev->netdev_ops = &qmimux_netdev_ops;
126 dev->destructor = free_netdev; 126 dev->needs_free_netdev = true;
127} 127}
128 128
129static struct net_device *qmimux_find_dev(struct usbnet *dev, u8 mux_id) 129static struct net_device *qmimux_find_dev(struct usbnet *dev, u8 mux_id)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 38f0f03a29c8..0156fe8cac17 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -222,7 +222,6 @@ static int veth_dev_init(struct net_device *dev)
222static void veth_dev_free(struct net_device *dev) 222static void veth_dev_free(struct net_device *dev)
223{ 223{
224 free_percpu(dev->vstats); 224 free_percpu(dev->vstats);
225 free_netdev(dev);
226} 225}
227 226
228#ifdef CONFIG_NET_POLL_CONTROLLER 227#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -317,7 +316,8 @@ static void veth_setup(struct net_device *dev)
317 NETIF_F_HW_VLAN_STAG_TX | 316 NETIF_F_HW_VLAN_STAG_TX |
318 NETIF_F_HW_VLAN_CTAG_RX | 317 NETIF_F_HW_VLAN_CTAG_RX |
319 NETIF_F_HW_VLAN_STAG_RX); 318 NETIF_F_HW_VLAN_STAG_RX);
320 dev->destructor = veth_dev_free; 319 dev->needs_free_netdev = true;
320 dev->priv_destructor = veth_dev_free;
321 dev->max_mtu = ETH_MAX_MTU; 321 dev->max_mtu = ETH_MAX_MTU;
322 322
323 dev->hw_features = VETH_FEATURES; 323 dev->hw_features = VETH_FEATURES;
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index db882493875c..d38f11d833fe 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1348,7 +1348,7 @@ static void vrf_setup(struct net_device *dev)
1348 dev->netdev_ops = &vrf_netdev_ops; 1348 dev->netdev_ops = &vrf_netdev_ops;
1349 dev->l3mdev_ops = &vrf_l3mdev_ops; 1349 dev->l3mdev_ops = &vrf_l3mdev_ops;
1350 dev->ethtool_ops = &vrf_ethtool_ops; 1350 dev->ethtool_ops = &vrf_ethtool_ops;
1351 dev->destructor = free_netdev; 1351 dev->needs_free_netdev = true;
1352 1352
1353 /* Fill in device structure with ethernet-generic values. */ 1353 /* Fill in device structure with ethernet-generic values. */
1354 eth_hw_addr_random(dev); 1354 eth_hw_addr_random(dev);
diff --git a/drivers/net/vsockmon.c b/drivers/net/vsockmon.c
index 7f0136f2dd9d..c28bdce14fd5 100644
--- a/drivers/net/vsockmon.c
+++ b/drivers/net/vsockmon.c
@@ -135,7 +135,7 @@ static void vsockmon_setup(struct net_device *dev)
135 135
136 dev->netdev_ops = &vsockmon_ops; 136 dev->netdev_ops = &vsockmon_ops;
137 dev->ethtool_ops = &vsockmon_ethtool_ops; 137 dev->ethtool_ops = &vsockmon_ethtool_ops;
138 dev->destructor = free_netdev; 138 dev->needs_free_netdev = true;
139 139
140 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | 140 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
141 NETIF_F_HIGHDMA | NETIF_F_LLTX; 141 NETIF_F_HIGHDMA | NETIF_F_LLTX;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index a6b5052c1d36..5fa798a5c9a6 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2611,7 +2611,7 @@ static void vxlan_setup(struct net_device *dev)
2611 eth_hw_addr_random(dev); 2611 eth_hw_addr_random(dev);
2612 ether_setup(dev); 2612 ether_setup(dev);
2613 2613
2614 dev->destructor = free_netdev; 2614 dev->needs_free_netdev = true;
2615 SET_NETDEV_DEVTYPE(dev, &vxlan_type); 2615 SET_NETDEV_DEVTYPE(dev, &vxlan_type);
2616 2616
2617 dev->features |= NETIF_F_LLTX; 2617 dev->features |= NETIF_F_LLTX;
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index 65ee2a6f248c..a0d76f70c428 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -475,7 +475,7 @@ static void dlci_setup(struct net_device *dev)
475 dev->flags = 0; 475 dev->flags = 0;
476 dev->header_ops = &dlci_header_ops; 476 dev->header_ops = &dlci_header_ops;
477 dev->netdev_ops = &dlci_netdev_ops; 477 dev->netdev_ops = &dlci_netdev_ops;
478 dev->destructor = free_netdev; 478 dev->needs_free_netdev = true;
479 479
480 dlp->receive = dlci_receive; 480 dlp->receive = dlci_receive;
481 481
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index eb915281197e..78596e42a3f3 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1106,7 +1106,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
1106 return -EIO; 1106 return -EIO;
1107 } 1107 }
1108 1108
1109 dev->destructor = free_netdev; 1109 dev->needs_free_netdev = true;
1110 *get_dev_p(pvc, type) = dev; 1110 *get_dev_p(pvc, type) = dev;
1111 if (!used) { 1111 if (!used) {
1112 state(hdlc)->dce_changed = 1; 1112 state(hdlc)->dce_changed = 1;
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 9df9ed62beff..63f749078a1f 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -306,7 +306,7 @@ static const struct net_device_ops lapbeth_netdev_ops = {
306static void lapbeth_setup(struct net_device *dev) 306static void lapbeth_setup(struct net_device *dev)
307{ 307{
308 dev->netdev_ops = &lapbeth_netdev_ops; 308 dev->netdev_ops = &lapbeth_netdev_ops;
309 dev->destructor = free_netdev; 309 dev->needs_free_netdev = true;
310 dev->type = ARPHRD_X25; 310 dev->type = ARPHRD_X25;
311 dev->hard_header_len = 3; 311 dev->hard_header_len = 3;
312 dev->mtu = 1000; 312 dev->mtu = 1000;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 91ee542de3d7..b90c77ef792e 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1287,7 +1287,7 @@ void init_netdev(struct net_device *dev)
1287 struct ath6kl *ar = ath6kl_priv(dev); 1287 struct ath6kl *ar = ath6kl_priv(dev);
1288 1288
1289 dev->netdev_ops = &ath6kl_netdev_ops; 1289 dev->netdev_ops = &ath6kl_netdev_ops;
1290 dev->destructor = free_netdev; 1290 dev->needs_free_netdev = true;
1291 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT; 1291 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
1292 1292
1293 dev->needed_headroom = ETH_HLEN; 1293 dev->needed_headroom = ETH_HLEN;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index cd1d6730eab7..617199c0e5a0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5225,7 +5225,6 @@ void brcmf_cfg80211_free_netdev(struct net_device *ndev)
5225 5225
5226 if (vif) 5226 if (vif)
5227 brcmf_free_vif(vif); 5227 brcmf_free_vif(vif);
5228 free_netdev(ndev);
5229} 5228}
5230 5229
5231static bool brcmf_is_linkup(const struct brcmf_event_msg *e) 5230static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index a3d82368f1a9..511d190c6cca 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -624,7 +624,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
624 if (!ndev) 624 if (!ndev)
625 return ERR_PTR(-ENOMEM); 625 return ERR_PTR(-ENOMEM);
626 626
627 ndev->destructor = brcmf_cfg80211_free_netdev; 627 ndev->needs_free_netdev = true;
628 ndev->priv_destructor = brcmf_cfg80211_free_netdev;
628 ifp = netdev_priv(ndev); 629 ifp = netdev_priv(ndev);
629 ifp->ndev = ndev; 630 ifp->ndev = ndev;
630 /* store mapping ifidx to bsscfgidx */ 631 /* store mapping ifidx to bsscfgidx */
diff --git a/drivers/net/wireless/intersil/hostap/hostap_main.c b/drivers/net/wireless/intersil/hostap/hostap_main.c
index 544fc09dcb62..1372b20f931e 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
@@ -73,7 +73,7 @@ struct net_device * hostap_add_interface(struct local_info *local,
73 dev->mem_end = mdev->mem_end; 73 dev->mem_end = mdev->mem_end;
74 74
75 hostap_setup_dev(dev, local, type); 75 hostap_setup_dev(dev, local, type);
76 dev->destructor = free_netdev; 76 dev->needs_free_netdev = true;
77 77
78 sprintf(dev->name, "%s%s", prefix, name); 78 sprintf(dev->name, "%s%s", prefix, name);
79 if (!rtnl_locked) 79 if (!rtnl_locked)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 002b25cff5b6..c854a557998b 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2861,7 +2861,7 @@ static const struct net_device_ops hwsim_netdev_ops = {
2861static void hwsim_mon_setup(struct net_device *dev) 2861static void hwsim_mon_setup(struct net_device *dev)
2862{ 2862{
2863 dev->netdev_ops = &hwsim_netdev_ops; 2863 dev->netdev_ops = &hwsim_netdev_ops;
2864 dev->destructor = free_netdev; 2864 dev->needs_free_netdev = true;
2865 ether_setup(dev); 2865 ether_setup(dev);
2866 dev->priv_flags |= IFF_NO_QUEUE; 2866 dev->priv_flags |= IFF_NO_QUEUE;
2867 dev->type = ARPHRD_IEEE80211_RADIOTAP; 2867 dev->type = ARPHRD_IEEE80211_RADIOTAP;
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index dd87b9ff64c3..39b6b5e3f6e0 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1280,7 +1280,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
1280 struct net_device *dev) 1280 struct net_device *dev)
1281{ 1281{
1282 dev->netdev_ops = &mwifiex_netdev_ops; 1282 dev->netdev_ops = &mwifiex_netdev_ops;
1283 dev->destructor = free_netdev; 1283 dev->needs_free_netdev = true;
1284 /* Initialize private structure */ 1284 /* Initialize private structure */
1285 priv->current_key_index = 0; 1285 priv->current_key_index = 0;
1286 priv->media_connected = false; 1286 priv->media_connected = false;
diff --git a/drivers/staging/rtl8188eu/os_dep/mon.c b/drivers/staging/rtl8188eu/os_dep/mon.c
index cfe37eb026d6..859d0d6051cd 100644
--- a/drivers/staging/rtl8188eu/os_dep/mon.c
+++ b/drivers/staging/rtl8188eu/os_dep/mon.c
@@ -152,7 +152,7 @@ static const struct net_device_ops mon_netdev_ops = {
152static void mon_setup(struct net_device *dev) 152static void mon_setup(struct net_device *dev)
153{ 153{
154 dev->netdev_ops = &mon_netdev_ops; 154 dev->netdev_ops = &mon_netdev_ops;
155 dev->destructor = free_netdev; 155 dev->needs_free_netdev = true;
156 ether_setup(dev); 156 ether_setup(dev);
157 dev->priv_flags |= IFF_NO_QUEUE; 157 dev->priv_flags |= IFF_NO_QUEUE;
158 dev->type = ARPHRD_IEEE80211; 158 dev->type = ARPHRD_IEEE80211;
diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c
index b4058f0000e4..6a1ce6a55158 100644
--- a/drivers/usb/gadget/function/f_phonet.c
+++ b/drivers/usb/gadget/function/f_phonet.c
@@ -281,7 +281,7 @@ static void pn_net_setup(struct net_device *dev)
281 dev->tx_queue_len = 1; 281 dev->tx_queue_len = 1;
282 282
283 dev->netdev_ops = &pn_netdev_ops; 283 dev->netdev_ops = &pn_netdev_ops;
284 dev->destructor = free_netdev; 284 dev->needs_free_netdev = true;
285 dev->header_ops = &phonet_header_ops; 285 dev->header_ops = &phonet_header_ops;
286} 286}
287 287
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3f39d27decf4..ab7ca3fdc495 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1596,8 +1596,8 @@ enum netdev_priv_flags {
1596 * @rtnl_link_state: This enum represents the phases of creating 1596 * @rtnl_link_state: This enum represents the phases of creating
1597 * a new link 1597 * a new link
1598 * 1598 *
1599 * @destructor: Called from unregister, 1599 * @needs_free_netdev: Should unregister perform free_netdev?
1600 * can be used to call free_netdev 1600 * @priv_destructor: Called from unregister
1601 * @npinfo: XXX: need comments on this one 1601 * @npinfo: XXX: need comments on this one
1602 * @nd_net: Network namespace this network device is inside 1602 * @nd_net: Network namespace this network device is inside
1603 * 1603 *
@@ -1858,7 +1858,8 @@ struct net_device {
1858 RTNL_LINK_INITIALIZING, 1858 RTNL_LINK_INITIALIZING,
1859 } rtnl_link_state:16; 1859 } rtnl_link_state:16;
1860 1860
1861 void (*destructor)(struct net_device *dev); 1861 bool needs_free_netdev;
1862 void (*priv_destructor)(struct net_device *dev);
1862 1863
1863#ifdef CONFIG_NETPOLL 1864#ifdef CONFIG_NETPOLL
1864 struct netpoll_info __rcu *npinfo; 1865 struct netpoll_info __rcu *npinfo;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 953b6728bd00..abc5f400fc71 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -813,7 +813,6 @@ static void vlan_dev_free(struct net_device *dev)
813 813
814 free_percpu(vlan->vlan_pcpu_stats); 814 free_percpu(vlan->vlan_pcpu_stats);
815 vlan->vlan_pcpu_stats = NULL; 815 vlan->vlan_pcpu_stats = NULL;
816 free_netdev(dev);
817} 816}
818 817
819void vlan_setup(struct net_device *dev) 818void vlan_setup(struct net_device *dev)
@@ -826,7 +825,8 @@ void vlan_setup(struct net_device *dev)
826 netif_keep_dst(dev); 825 netif_keep_dst(dev);
827 826
828 dev->netdev_ops = &vlan_netdev_ops; 827 dev->netdev_ops = &vlan_netdev_ops;
829 dev->destructor = vlan_dev_free; 828 dev->needs_free_netdev = true;
829 dev->priv_destructor = vlan_dev_free;
830 dev->ethtool_ops = &vlan_ethtool_ops; 830 dev->ethtool_ops = &vlan_ethtool_ops;
831 831
832 dev->min_mtu = 0; 832 dev->min_mtu = 0;
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index b25789abf7b9..10f7edfb176e 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -1034,8 +1034,6 @@ static void batadv_softif_free(struct net_device *dev)
1034 * netdev and its private data (bat_priv) 1034 * netdev and its private data (bat_priv)
1035 */ 1035 */
1036 rcu_barrier(); 1036 rcu_barrier();
1037
1038 free_netdev(dev);
1039} 1037}
1040 1038
1041/** 1039/**
@@ -1047,7 +1045,8 @@ static void batadv_softif_init_early(struct net_device *dev)
1047 ether_setup(dev); 1045 ether_setup(dev);
1048 1046
1049 dev->netdev_ops = &batadv_netdev_ops; 1047 dev->netdev_ops = &batadv_netdev_ops;
1050 dev->destructor = batadv_softif_free; 1048 dev->needs_free_netdev = true;
1049 dev->priv_destructor = batadv_softif_free;
1051 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; 1050 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL;
1052 dev->priv_flags |= IFF_NO_QUEUE; 1051 dev->priv_flags |= IFF_NO_QUEUE;
1053 1052
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 608959989f8e..ab3b654b05cc 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -598,7 +598,7 @@ static void netdev_setup(struct net_device *dev)
598 598
599 dev->netdev_ops = &netdev_ops; 599 dev->netdev_ops = &netdev_ops;
600 dev->header_ops = &header_ops; 600 dev->header_ops = &header_ops;
601 dev->destructor = free_netdev; 601 dev->needs_free_netdev = true;
602} 602}
603 603
604static struct device_type bt_type = { 604static struct device_type bt_type = {
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 430b53e7d941..f0f3447e8aa4 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -379,7 +379,7 @@ void br_dev_setup(struct net_device *dev)
379 ether_setup(dev); 379 ether_setup(dev);
380 380
381 dev->netdev_ops = &br_netdev_ops; 381 dev->netdev_ops = &br_netdev_ops;
382 dev->destructor = free_netdev; 382 dev->needs_free_netdev = true;
383 dev->ethtool_ops = &br_ethtool_ops; 383 dev->ethtool_ops = &br_ethtool_ops;
384 SET_NETDEV_DEVTYPE(dev, &br_type); 384 SET_NETDEV_DEVTYPE(dev, &br_type);
385 dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE; 385 dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 1816fc9f1ee7..fe3c53efb949 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -392,14 +392,14 @@ static void chnl_net_destructor(struct net_device *dev)
392{ 392{
393 struct chnl_net *priv = netdev_priv(dev); 393 struct chnl_net *priv = netdev_priv(dev);
394 caif_free_client(&priv->chnl); 394 caif_free_client(&priv->chnl);
395 free_netdev(dev);
396} 395}
397 396
398static void ipcaif_net_setup(struct net_device *dev) 397static void ipcaif_net_setup(struct net_device *dev)
399{ 398{
400 struct chnl_net *priv; 399 struct chnl_net *priv;
401 dev->netdev_ops = &netdev_ops; 400 dev->netdev_ops = &netdev_ops;
402 dev->destructor = chnl_net_destructor; 401 dev->needs_free_netdev = true;
402 dev->priv_destructor = chnl_net_destructor;
403 dev->flags |= IFF_NOARP; 403 dev->flags |= IFF_NOARP;
404 dev->flags |= IFF_POINTOPOINT; 404 dev->flags |= IFF_POINTOPOINT;
405 dev->mtu = GPRS_PDP_MTU; 405 dev->mtu = GPRS_PDP_MTU;
diff --git a/net/core/dev.c b/net/core/dev.c
index 84e1e86a4bce..4c15466305c3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7502,6 +7502,8 @@ out:
7502err_uninit: 7502err_uninit:
7503 if (dev->netdev_ops->ndo_uninit) 7503 if (dev->netdev_ops->ndo_uninit)
7504 dev->netdev_ops->ndo_uninit(dev); 7504 dev->netdev_ops->ndo_uninit(dev);
7505 if (dev->priv_destructor)
7506 dev->priv_destructor(dev);
7505 goto out; 7507 goto out;
7506} 7508}
7507EXPORT_SYMBOL(register_netdevice); 7509EXPORT_SYMBOL(register_netdevice);
@@ -7709,8 +7711,10 @@ void netdev_run_todo(void)
7709 WARN_ON(rcu_access_pointer(dev->ip6_ptr)); 7711 WARN_ON(rcu_access_pointer(dev->ip6_ptr));
7710 WARN_ON(dev->dn_ptr); 7712 WARN_ON(dev->dn_ptr);
7711 7713
7712 if (dev->destructor) 7714 if (dev->priv_destructor)
7713 dev->destructor(dev); 7715 dev->priv_destructor(dev);
7716 if (dev->needs_free_netdev)
7717 free_netdev(dev);
7714 7718
7715 /* Report a network device has been unregistered */ 7719 /* Report a network device has been unregistered */
7716 rtnl_lock(); 7720 rtnl_lock();
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index c73160fb11e7..0a0a392dc2bd 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -378,7 +378,6 @@ static void hsr_dev_destroy(struct net_device *hsr_dev)
378 del_timer_sync(&hsr->announce_timer); 378 del_timer_sync(&hsr->announce_timer);
379 379
380 synchronize_rcu(); 380 synchronize_rcu();
381 free_netdev(hsr_dev);
382} 381}
383 382
384static const struct net_device_ops hsr_device_ops = { 383static const struct net_device_ops hsr_device_ops = {
@@ -404,7 +403,8 @@ void hsr_dev_setup(struct net_device *dev)
404 SET_NETDEV_DEVTYPE(dev, &hsr_type); 403 SET_NETDEV_DEVTYPE(dev, &hsr_type);
405 dev->priv_flags |= IFF_NO_QUEUE; 404 dev->priv_flags |= IFF_NO_QUEUE;
406 405
407 dev->destructor = hsr_dev_destroy; 406 dev->needs_free_netdev = true;
407 dev->priv_destructor = hsr_dev_destroy;
408 408
409 dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 409 dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
410 NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | 410 NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index d7efbf0dad20..0a866f332290 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -107,7 +107,7 @@ static void lowpan_setup(struct net_device *ldev)
107 107
108 ldev->netdev_ops = &lowpan_netdev_ops; 108 ldev->netdev_ops = &lowpan_netdev_ops;
109 ldev->header_ops = &lowpan_header_ops; 109 ldev->header_ops = &lowpan_header_ops;
110 ldev->destructor = free_netdev; 110 ldev->needs_free_netdev = true;
111 ldev->features |= NETIF_F_NETNS_LOCAL; 111 ldev->features |= NETIF_F_NETNS_LOCAL;
112} 112}
113 113
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index b878ecbc0608..b436d0775631 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -967,7 +967,6 @@ static void ip_tunnel_dev_free(struct net_device *dev)
967 gro_cells_destroy(&tunnel->gro_cells); 967 gro_cells_destroy(&tunnel->gro_cells);
968 dst_cache_destroy(&tunnel->dst_cache); 968 dst_cache_destroy(&tunnel->dst_cache);
969 free_percpu(dev->tstats); 969 free_percpu(dev->tstats);
970 free_netdev(dev);
971} 970}
972 971
973void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) 972void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
@@ -1155,7 +1154,8 @@ int ip_tunnel_init(struct net_device *dev)
1155 struct iphdr *iph = &tunnel->parms.iph; 1154 struct iphdr *iph = &tunnel->parms.iph;
1156 int err; 1155 int err;
1157 1156
1158 dev->destructor = ip_tunnel_dev_free; 1157 dev->needs_free_netdev = true;
1158 dev->priv_destructor = ip_tunnel_dev_free;
1159 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 1159 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
1160 if (!dev->tstats) 1160 if (!dev->tstats)
1161 return -ENOMEM; 1161 return -ENOMEM;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 551de4d023a8..b4f9622ee9f5 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -501,7 +501,7 @@ static void reg_vif_setup(struct net_device *dev)
501 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8; 501 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8;
502 dev->flags = IFF_NOARP; 502 dev->flags = IFF_NOARP;
503 dev->netdev_ops = &reg_vif_netdev_ops; 503 dev->netdev_ops = &reg_vif_netdev_ops;
504 dev->destructor = free_netdev; 504 dev->needs_free_netdev = true;
505 dev->features |= NETIF_F_NETNS_LOCAL; 505 dev->features |= NETIF_F_NETNS_LOCAL;
506} 506}
507 507
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 0c5b4caa1949..64eea3962733 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -991,13 +991,13 @@ static void ip6gre_dev_free(struct net_device *dev)
991 991
992 dst_cache_destroy(&t->dst_cache); 992 dst_cache_destroy(&t->dst_cache);
993 free_percpu(dev->tstats); 993 free_percpu(dev->tstats);
994 free_netdev(dev);
995} 994}
996 995
997static void ip6gre_tunnel_setup(struct net_device *dev) 996static void ip6gre_tunnel_setup(struct net_device *dev)
998{ 997{
999 dev->netdev_ops = &ip6gre_netdev_ops; 998 dev->netdev_ops = &ip6gre_netdev_ops;
1000 dev->destructor = ip6gre_dev_free; 999 dev->needs_free_netdev = true;
1000 dev->priv_destructor = ip6gre_dev_free;
1001 1001
1002 dev->type = ARPHRD_IP6GRE; 1002 dev->type = ARPHRD_IP6GRE;
1003 1003
@@ -1148,7 +1148,7 @@ static int __net_init ip6gre_init_net(struct net *net)
1148 return 0; 1148 return 0;
1149 1149
1150err_reg_dev: 1150err_reg_dev:
1151 ip6gre_dev_free(ign->fb_tunnel_dev); 1151 free_netdev(ign->fb_tunnel_dev);
1152err_alloc_dev: 1152err_alloc_dev:
1153 return err; 1153 return err;
1154} 1154}
@@ -1300,7 +1300,8 @@ static void ip6gre_tap_setup(struct net_device *dev)
1300 ether_setup(dev); 1300 ether_setup(dev);
1301 1301
1302 dev->netdev_ops = &ip6gre_tap_netdev_ops; 1302 dev->netdev_ops = &ip6gre_tap_netdev_ops;
1303 dev->destructor = ip6gre_dev_free; 1303 dev->needs_free_netdev = true;
1304 dev->priv_destructor = ip6gre_dev_free;
1304 1305
1305 dev->features |= NETIF_F_NETNS_LOCAL; 1306 dev->features |= NETIF_F_NETNS_LOCAL;
1306 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 1307 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9b37f9747fc6..c3581973f5d7 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -254,7 +254,6 @@ static void ip6_dev_free(struct net_device *dev)
254 gro_cells_destroy(&t->gro_cells); 254 gro_cells_destroy(&t->gro_cells);
255 dst_cache_destroy(&t->dst_cache); 255 dst_cache_destroy(&t->dst_cache);
256 free_percpu(dev->tstats); 256 free_percpu(dev->tstats);
257 free_netdev(dev);
258} 257}
259 258
260static int ip6_tnl_create2(struct net_device *dev) 259static int ip6_tnl_create2(struct net_device *dev)
@@ -322,7 +321,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
322 return t; 321 return t;
323 322
324failed_free: 323failed_free:
325 ip6_dev_free(dev); 324 free_netdev(dev);
326failed: 325failed:
327 return ERR_PTR(err); 326 return ERR_PTR(err);
328} 327}
@@ -1777,7 +1776,8 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
1777static void ip6_tnl_dev_setup(struct net_device *dev) 1776static void ip6_tnl_dev_setup(struct net_device *dev)
1778{ 1777{
1779 dev->netdev_ops = &ip6_tnl_netdev_ops; 1778 dev->netdev_ops = &ip6_tnl_netdev_ops;
1780 dev->destructor = ip6_dev_free; 1779 dev->needs_free_netdev = true;
1780 dev->priv_destructor = ip6_dev_free;
1781 1781
1782 dev->type = ARPHRD_TUNNEL6; 1782 dev->type = ARPHRD_TUNNEL6;
1783 dev->flags |= IFF_NOARP; 1783 dev->flags |= IFF_NOARP;
@@ -2224,7 +2224,7 @@ static int __net_init ip6_tnl_init_net(struct net *net)
2224 return 0; 2224 return 0;
2225 2225
2226err_register: 2226err_register:
2227 ip6_dev_free(ip6n->fb_tnl_dev); 2227 free_netdev(ip6n->fb_tnl_dev);
2228err_alloc_dev: 2228err_alloc_dev:
2229 return err; 2229 return err;
2230} 2230}
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index d67ef56454b2..837ea1eefe7f 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -180,7 +180,6 @@ vti6_tnl_unlink(struct vti6_net *ip6n, struct ip6_tnl *t)
180static void vti6_dev_free(struct net_device *dev) 180static void vti6_dev_free(struct net_device *dev)
181{ 181{
182 free_percpu(dev->tstats); 182 free_percpu(dev->tstats);
183 free_netdev(dev);
184} 183}
185 184
186static int vti6_tnl_create2(struct net_device *dev) 185static int vti6_tnl_create2(struct net_device *dev)
@@ -235,7 +234,7 @@ static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p
235 return t; 234 return t;
236 235
237failed_free: 236failed_free:
238 vti6_dev_free(dev); 237 free_netdev(dev);
239failed: 238failed:
240 return NULL; 239 return NULL;
241} 240}
@@ -842,7 +841,8 @@ static const struct net_device_ops vti6_netdev_ops = {
842static void vti6_dev_setup(struct net_device *dev) 841static void vti6_dev_setup(struct net_device *dev)
843{ 842{
844 dev->netdev_ops = &vti6_netdev_ops; 843 dev->netdev_ops = &vti6_netdev_ops;
845 dev->destructor = vti6_dev_free; 844 dev->needs_free_netdev = true;
845 dev->priv_destructor = vti6_dev_free;
846 846
847 dev->type = ARPHRD_TUNNEL6; 847 dev->type = ARPHRD_TUNNEL6;
848 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr); 848 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
@@ -1100,7 +1100,7 @@ static int __net_init vti6_init_net(struct net *net)
1100 return 0; 1100 return 0;
1101 1101
1102err_register: 1102err_register:
1103 vti6_dev_free(ip6n->fb_tnl_dev); 1103 free_netdev(ip6n->fb_tnl_dev);
1104err_alloc_dev: 1104err_alloc_dev:
1105 return err; 1105 return err;
1106} 1106}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 374997d26488..2ecb39b943b5 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -733,7 +733,7 @@ static void reg_vif_setup(struct net_device *dev)
733 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; 733 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8;
734 dev->flags = IFF_NOARP; 734 dev->flags = IFF_NOARP;
735 dev->netdev_ops = &reg_vif_netdev_ops; 735 dev->netdev_ops = &reg_vif_netdev_ops;
736 dev->destructor = free_netdev; 736 dev->needs_free_netdev = true;
737 dev->features |= NETIF_F_NETNS_LOCAL; 737 dev->features |= NETIF_F_NETNS_LOCAL;
738} 738}
739 739
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 61e5902f0687..2378503577b0 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -265,7 +265,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
265 return nt; 265 return nt;
266 266
267failed_free: 267failed_free:
268 ipip6_dev_free(dev); 268 free_netdev(dev);
269failed: 269failed:
270 return NULL; 270 return NULL;
271} 271}
@@ -1336,7 +1336,6 @@ static void ipip6_dev_free(struct net_device *dev)
1336 1336
1337 dst_cache_destroy(&tunnel->dst_cache); 1337 dst_cache_destroy(&tunnel->dst_cache);
1338 free_percpu(dev->tstats); 1338 free_percpu(dev->tstats);
1339 free_netdev(dev);
1340} 1339}
1341 1340
1342#define SIT_FEATURES (NETIF_F_SG | \ 1341#define SIT_FEATURES (NETIF_F_SG | \
@@ -1351,7 +1350,8 @@ static void ipip6_tunnel_setup(struct net_device *dev)
1351 int t_hlen = tunnel->hlen + sizeof(struct iphdr); 1350 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
1352 1351
1353 dev->netdev_ops = &ipip6_netdev_ops; 1352 dev->netdev_ops = &ipip6_netdev_ops;
1354 dev->destructor = ipip6_dev_free; 1353 dev->needs_free_netdev = true;
1354 dev->priv_destructor = ipip6_dev_free;
1355 1355
1356 dev->type = ARPHRD_SIT; 1356 dev->type = ARPHRD_SIT;
1357 dev->hard_header_len = LL_MAX_HEADER + t_hlen; 1357 dev->hard_header_len = LL_MAX_HEADER + t_hlen;
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
index 74d09f91709e..3be852808a9d 100644
--- a/net/irda/irlan/irlan_eth.c
+++ b/net/irda/irlan/irlan_eth.c
@@ -65,7 +65,7 @@ static void irlan_eth_setup(struct net_device *dev)
65 ether_setup(dev); 65 ether_setup(dev);
66 66
67 dev->netdev_ops = &irlan_eth_netdev_ops; 67 dev->netdev_ops = &irlan_eth_netdev_ops;
68 dev->destructor = free_netdev; 68 dev->needs_free_netdev = true;
69 dev->min_mtu = 0; 69 dev->min_mtu = 0;
70 dev->max_mtu = ETH_MAX_MTU; 70 dev->max_mtu = ETH_MAX_MTU;
71 71
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index 8b21af7321b9..f7c54ece3733 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -141,7 +141,7 @@ static void l2tp_eth_dev_setup(struct net_device *dev)
141 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 141 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
142 dev->features |= NETIF_F_LLTX; 142 dev->features |= NETIF_F_LLTX;
143 dev->netdev_ops = &l2tp_eth_netdev_ops; 143 dev->netdev_ops = &l2tp_eth_netdev_ops;
144 dev->destructor = free_netdev; 144 dev->needs_free_netdev = true;
145} 145}
146 146
147static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) 147static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8fae1a72e6a7..915d7e1b4545 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1213,7 +1213,6 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
1213static void ieee80211_if_free(struct net_device *dev) 1213static void ieee80211_if_free(struct net_device *dev)
1214{ 1214{
1215 free_percpu(dev->tstats); 1215 free_percpu(dev->tstats);
1216 free_netdev(dev);
1217} 1216}
1218 1217
1219static void ieee80211_if_setup(struct net_device *dev) 1218static void ieee80211_if_setup(struct net_device *dev)
@@ -1221,7 +1220,8 @@ static void ieee80211_if_setup(struct net_device *dev)
1221 ether_setup(dev); 1220 ether_setup(dev);
1222 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 1221 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
1223 dev->netdev_ops = &ieee80211_dataif_ops; 1222 dev->netdev_ops = &ieee80211_dataif_ops;
1224 dev->destructor = ieee80211_if_free; 1223 dev->needs_free_netdev = true;
1224 dev->priv_destructor = ieee80211_if_free;
1225} 1225}
1226 1226
1227static void ieee80211_if_setup_no_queue(struct net_device *dev) 1227static void ieee80211_if_setup_no_queue(struct net_device *dev)
@@ -1905,7 +1905,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1905 1905
1906 ret = register_netdevice(ndev); 1906 ret = register_netdevice(ndev);
1907 if (ret) { 1907 if (ret) {
1908 ieee80211_if_free(ndev); 1908 free_netdev(ndev);
1909 return ret; 1909 return ret;
1910 } 1910 }
1911 } 1911 }
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 06019dba4b10..bd88a9b80773 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -526,8 +526,6 @@ static void mac802154_wpan_free(struct net_device *dev)
526 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 526 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
527 527
528 mac802154_llsec_destroy(&sdata->sec); 528 mac802154_llsec_destroy(&sdata->sec);
529
530 free_netdev(dev);
531} 529}
532 530
533static void ieee802154_if_setup(struct net_device *dev) 531static void ieee802154_if_setup(struct net_device *dev)
@@ -593,7 +591,8 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
593 sdata->dev->dev_addr); 591 sdata->dev->dev_addr);
594 592
595 sdata->dev->header_ops = &mac802154_header_ops; 593 sdata->dev->header_ops = &mac802154_header_ops;
596 sdata->dev->destructor = mac802154_wpan_free; 594 sdata->dev->needs_free_netdev = true;
595 sdata->dev->priv_destructor = mac802154_wpan_free;
597 sdata->dev->netdev_ops = &mac802154_wpan_ops; 596 sdata->dev->netdev_ops = &mac802154_wpan_ops;
598 sdata->dev->ml_priv = &mac802154_mlme_wpan; 597 sdata->dev->ml_priv = &mac802154_mlme_wpan;
599 wpan_dev->promiscuous_mode = false; 598 wpan_dev->promiscuous_mode = false;
@@ -608,7 +607,7 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
608 607
609 break; 608 break;
610 case NL802154_IFTYPE_MONITOR: 609 case NL802154_IFTYPE_MONITOR:
611 sdata->dev->destructor = free_netdev; 610 sdata->dev->needs_free_netdev = true;
612 sdata->dev->netdev_ops = &mac802154_monitor_ops; 611 sdata->dev->netdev_ops = &mac802154_monitor_ops;
613 wpan_dev->promiscuous_mode = true; 612 wpan_dev->promiscuous_mode = true;
614 break; 613 break;
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 89193a634da4..04a3128adcf0 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -94,7 +94,6 @@ static void internal_dev_destructor(struct net_device *dev)
94 struct vport *vport = ovs_internal_dev_get_vport(dev); 94 struct vport *vport = ovs_internal_dev_get_vport(dev);
95 95
96 ovs_vport_free(vport); 96 ovs_vport_free(vport);
97 free_netdev(dev);
98} 97}
99 98
100static void 99static void
@@ -156,7 +155,8 @@ static void do_setup(struct net_device *netdev)
156 netdev->priv_flags &= ~IFF_TX_SKB_SHARING; 155 netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
157 netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH | 156 netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH |
158 IFF_PHONY_HEADROOM | IFF_NO_QUEUE; 157 IFF_PHONY_HEADROOM | IFF_NO_QUEUE;
159 netdev->destructor = internal_dev_destructor; 158 netdev->needs_free_netdev = true;
159 netdev->priv_destructor = internal_dev_destructor;
160 netdev->ethtool_ops = &internal_dev_ethtool_ops; 160 netdev->ethtool_ops = &internal_dev_ethtool_ops;
161 netdev->rtnl_link_ops = &internal_dev_link_ops; 161 netdev->rtnl_link_ops = &internal_dev_link_ops;
162 162
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c
index 21c28b51be94..2c9337946e30 100644
--- a/net/phonet/pep-gprs.c
+++ b/net/phonet/pep-gprs.c
@@ -236,7 +236,7 @@ static void gprs_setup(struct net_device *dev)
236 dev->tx_queue_len = 10; 236 dev->tx_queue_len = 10;
237 237
238 dev->netdev_ops = &gprs_netdev_ops; 238 dev->netdev_ops = &gprs_netdev_ops;
239 dev->destructor = free_netdev; 239 dev->needs_free_netdev = true;
240} 240}
241 241
242/* 242/*