diff options
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 | ||
4198 | void bond_setup(struct net_device *bond_dev) | 4197 | void 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) | |||
417 | static void slc_free_netdev(struct net_device *dev) | 417 | static 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 = { | |||
436 | static void slc_setup(struct net_device *dev) | 436 | static 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 | ||
169 | static struct rtnl_link_ops vcan_link_ops __read_mostly = { | 169 | static 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 | ||
334 | static void dummy_setup(struct net_device *dev) | 333 | static 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 | ||
4531 | static int config_mgmt_dev(struct pci_dev *pdev) | 4531 | static 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 = { | |||
611 | static void gtp_link_setup(struct net_device *dev) | 611 | static void gtp_link_setup(struct net_device *dev) |
612 | { | 612 | { |
613 | dev->netdev_ops = >p_netdev_ops; | 613 | dev->netdev_ops = >p_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 = { | |||
476 | static void bpq_setup(struct net_device *dev) | 476 | static 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 | ||
213 | static void ifb_setup(struct net_device *dev) | 212 | static 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 | ||
236 | static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev) | 236 | static 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 | ||
165 | static const struct net_device_ops loopback_ops = { | 164 | static 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 = ð_header_ops; | 196 | dev->header_ops = ð_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 | ||
3002 | static void macsec_setup(struct net_device *dev) | 3001 | static 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) | |||
629 | static void sl_free_netdev(struct net_device *dev) | 629 | static 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 = { | |||
651 | static void sl_setup(struct net_device *dev) | 651 | static 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 | ||
1649 | static int team_open(struct net_device *dev) | 1648 | static 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 | ||
1566 | static void tun_setup(struct net_device *dev) | 1565 | static 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 | ||
129 | static struct net_device *qmimux_find_dev(struct usbnet *dev, u8 mux_id) | 129 | static 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) | |||
222 | static void veth_dev_free(struct net_device *dev) | 222 | static 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 = { | |||
306 | static void lapbeth_setup(struct net_device *dev) | 306 | static 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 | ||
5231 | static bool brcmf_is_linkup(const struct brcmf_event_msg *e) | 5230 | static 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 = { | |||
2861 | static void hwsim_mon_setup(struct net_device *dev) | 2861 | static 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 = { | |||
152 | static void mon_setup(struct net_device *dev) | 152 | static 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 | ||
819 | void vlan_setup(struct net_device *dev) | 818 | void 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 | ||
604 | static struct device_type bt_type = { | 604 | static 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 | ||
398 | static void ipcaif_net_setup(struct net_device *dev) | 397 | static 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: | |||
7502 | err_uninit: | 7502 | err_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 | } |
7507 | EXPORT_SYMBOL(register_netdevice); | 7509 | EXPORT_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 | ||
384 | static const struct net_device_ops hsr_device_ops = { | 383 | static 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 | ||
973 | void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) | 972 | void 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 = ®_vif_netdev_ops; | 503 | dev->netdev_ops = ®_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 | ||
997 | static void ip6gre_tunnel_setup(struct net_device *dev) | 996 | static 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 | ||
1150 | err_reg_dev: | 1150 | err_reg_dev: |
1151 | ip6gre_dev_free(ign->fb_tunnel_dev); | 1151 | free_netdev(ign->fb_tunnel_dev); |
1152 | err_alloc_dev: | 1152 | err_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 | ||
260 | static int ip6_tnl_create2(struct net_device *dev) | 259 | static 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 | ||
324 | failed_free: | 323 | failed_free: |
325 | ip6_dev_free(dev); | 324 | free_netdev(dev); |
326 | failed: | 325 | failed: |
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 = { | |||
1777 | static void ip6_tnl_dev_setup(struct net_device *dev) | 1776 | static 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 | ||
2226 | err_register: | 2226 | err_register: |
2227 | ip6_dev_free(ip6n->fb_tnl_dev); | 2227 | free_netdev(ip6n->fb_tnl_dev); |
2228 | err_alloc_dev: | 2228 | err_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) | |||
180 | static void vti6_dev_free(struct net_device *dev) | 180 | static 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 | ||
186 | static int vti6_tnl_create2(struct net_device *dev) | 185 | static 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 | ||
237 | failed_free: | 236 | failed_free: |
238 | vti6_dev_free(dev); | 237 | free_netdev(dev); |
239 | failed: | 238 | failed: |
240 | return NULL; | 239 | return NULL; |
241 | } | 240 | } |
@@ -842,7 +841,8 @@ static const struct net_device_ops vti6_netdev_ops = { | |||
842 | static void vti6_dev_setup(struct net_device *dev) | 841 | static 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 | ||
1102 | err_register: | 1102 | err_register: |
1103 | vti6_dev_free(ip6n->fb_tnl_dev); | 1103 | free_netdev(ip6n->fb_tnl_dev); |
1104 | err_alloc_dev: | 1104 | err_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 = ®_vif_netdev_ops; | 735 | dev->netdev_ops = ®_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 | ||
267 | failed_free: | 267 | failed_free: |
268 | ipip6_dev_free(dev); | 268 | free_netdev(dev); |
269 | failed: | 269 | failed: |
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 | ||
147 | static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) | 147 | static 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 = { | |||
1213 | static void ieee80211_if_free(struct net_device *dev) | 1213 | static 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 | ||
1219 | static void ieee80211_if_setup(struct net_device *dev) | 1218 | static 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 | ||
1227 | static void ieee80211_if_setup_no_queue(struct net_device *dev) | 1227 | static 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 | ||
533 | static void ieee802154_if_setup(struct net_device *dev) | 531 | static 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 | ||
100 | static void | 99 | static 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 | /* |