Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: Fix inconsistent teardown and release of private netdev state.

Network devices can allocate reasources and private memory using
netdev_ops->ndo_init(). However, the release of these resources
can occur in one of two different places.

Either netdev_ops->ndo_uninit() or netdev->destructor().

The decision of which operation frees the resources depends upon
whether it is necessary for all netdev refs to be released before it
is safe to perform the freeing.

netdev_ops->ndo_uninit() presumably can occur right after the
NETDEV_UNREGISTER notifier completes and the unicast and multicast
address lists are flushed.

netdev->destructor(), on the other hand, does not run until the
netdev references all go away.

Further complicating the situation is that netdev->destructor()
almost universally does also a free_netdev().

This creates a problem for the logic in register_netdevice().
Because all callers of register_netdevice() manage the freeing
of the netdev, and invoke free_netdev(dev) if register_netdevice()
fails.

If netdev_ops->ndo_init() succeeds, but something else fails inside
of register_netdevice(), it does call ndo_ops->ndo_uninit(). But
it is not able to invoke netdev->destructor().

This is because netdev->destructor() will do a free_netdev() and
then the caller of register_netdevice() will do the same.

However, this means that the resources that would normally be released
by netdev->destructor() will not be.

Over the years drivers have added local hacks to deal with this, by
invoking their destructor parts by hand when register_netdevice()
fails.

Many drivers do not try to deal with this, and instead we have leaks.

Let's close this hole by formalizing the distinction between what
private things need to be freed up by netdev->destructor() and whether
the driver needs unregister_netdevice() to perform the free_netdev().

netdev->priv_destructor() performs all actions to free up the private
resources that used to be freed by netdev->destructor(), except for
free_netdev().

netdev->needs_free_netdev is a boolean that indicates whether
free_netdev() should be done at the end of unregister_netdevice().

Now, register_netdevice() can sanely release all resources after
ndo_ops->ndo_init() succeeds, by invoking both ndo_ops->ndo_uninit()
and netdev->priv_destructor().

And at the end of unregister_netdevice(), we invoke
netdev->priv_destructor() and optionally call free_netdev().

Signed-off-by: David S. Miller <davem@davemloft.net>

+105 -103
+3 -3
drivers/net/bonding/bond_main.c
··· 4192 4192 struct bonding *bond = netdev_priv(bond_dev); 4193 4193 if (bond->wq) 4194 4194 destroy_workqueue(bond->wq); 4195 - free_netdev(bond_dev); 4196 4195 } 4197 4196 4198 4197 void bond_setup(struct net_device *bond_dev) ··· 4211 4212 bond_dev->netdev_ops = &bond_netdev_ops; 4212 4213 bond_dev->ethtool_ops = &bond_ethtool_ops; 4213 4214 4214 - bond_dev->destructor = bond_destructor; 4215 + bond_dev->needs_free_netdev = true; 4216 + bond_dev->priv_destructor = bond_destructor; 4215 4217 4216 4218 SET_NETDEV_DEVTYPE(bond_dev, &bond_type); 4217 4219 ··· 4736 4736 4737 4737 rtnl_unlock(); 4738 4738 if (res < 0) 4739 - bond_destructor(bond_dev); 4739 + free_netdev(bond_dev); 4740 4740 return res; 4741 4741 } 4742 4742
+1 -1
drivers/net/caif/caif_hsi.c
··· 1121 1121 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 1122 1122 dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ; 1123 1123 dev->priv_flags |= IFF_NO_QUEUE; 1124 - dev->destructor = free_netdev; 1124 + dev->needs_free_netdev = true; 1125 1125 dev->netdev_ops = &cfhsi_netdevops; 1126 1126 for (i = 0; i < CFHSI_PRIO_LAST; ++i) 1127 1127 skb_queue_head_init(&cfhsi->qhead[i]);
+1 -1
drivers/net/caif/caif_serial.c
··· 428 428 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 429 429 dev->mtu = CAIF_MAX_MTU; 430 430 dev->priv_flags |= IFF_NO_QUEUE; 431 - dev->destructor = free_netdev; 431 + dev->needs_free_netdev = true; 432 432 skb_queue_head_init(&serdev->head); 433 433 serdev->common.link_select = CAIF_LINK_LOW_LATENCY; 434 434 serdev->common.use_frag = true;
+1 -1
drivers/net/caif/caif_spi.c
··· 712 712 dev->flags = IFF_NOARP | IFF_POINTOPOINT; 713 713 dev->priv_flags |= IFF_NO_QUEUE; 714 714 dev->mtu = SPI_MAX_PAYLOAD_SIZE; 715 - dev->destructor = free_netdev; 715 + dev->needs_free_netdev = true; 716 716 skb_queue_head_init(&cfspi->qhead); 717 717 skb_queue_head_init(&cfspi->chead); 718 718 cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
+1 -1
drivers/net/caif/caif_virtio.c
··· 617 617 netdev->tx_queue_len = 100; 618 618 netdev->flags = IFF_POINTOPOINT | IFF_NOARP; 619 619 netdev->mtu = CFV_DEF_MTU_SIZE; 620 - netdev->destructor = free_netdev; 620 + netdev->needs_free_netdev = true; 621 621 } 622 622 623 623 /* Create debugfs counters for the device */
+3 -4
drivers/net/can/slcan.c
··· 417 417 static void slc_free_netdev(struct net_device *dev) 418 418 { 419 419 int i = dev->base_addr; 420 - free_netdev(dev); 420 + 421 421 slcan_devs[i] = NULL; 422 422 } 423 423 ··· 436 436 static void slc_setup(struct net_device *dev) 437 437 { 438 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 442 dev->hard_header_len = 0; 442 443 dev->addr_len = 0; ··· 762 761 if (sl->tty) { 763 762 printk(KERN_ERR "%s: tty discipline still running\n", 764 763 dev->name); 765 - /* Intentionally leak the control block. */ 766 - dev->destructor = NULL; 767 764 } 768 765 769 766 unregister_netdev(dev);
+1 -1
drivers/net/can/vcan.c
··· 163 163 dev->flags |= IFF_ECHO; 164 164 165 165 dev->netdev_ops = &vcan_netdev_ops; 166 - dev->destructor = free_netdev; 166 + dev->needs_free_netdev = true; 167 167 } 168 168 169 169 static struct rtnl_link_ops vcan_link_ops __read_mostly = {
+1 -1
drivers/net/can/vxcan.c
··· 156 156 dev->tx_queue_len = 0; 157 157 dev->flags = (IFF_NOARP|IFF_ECHO); 158 158 dev->netdev_ops = &vxcan_netdev_ops; 159 - dev->destructor = free_netdev; 159 + dev->needs_free_netdev = true; 160 160 } 161 161 162 162 /* forward declaration for rtnl_create_link() */
+2 -2
drivers/net/dummy.c
··· 328 328 struct dummy_priv *priv = netdev_priv(dev); 329 329 330 330 kfree(priv->vfinfo); 331 - free_netdev(dev); 332 331 } 333 332 334 333 static void dummy_setup(struct net_device *dev) ··· 337 338 /* Initialize the device structure. */ 338 339 dev->netdev_ops = &dummy_netdev_ops; 339 340 dev->ethtool_ops = &dummy_ethtool_ops; 340 - dev->destructor = dummy_free_netdev; 341 + dev->needs_free_netdev = true; 342 + dev->priv_destructor = dummy_free_netdev; 341 343 342 344 /* Fill in device structure with ethernet-generic values. */ 343 345 dev->flags |= IFF_NOARP;
+1 -1
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
··· 4525 4525 /* Initialize the device structure. */ 4526 4526 dev->netdev_ops = &cxgb4_mgmt_netdev_ops; 4527 4527 dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops; 4528 - dev->destructor = free_netdev; 4528 + dev->needs_free_netdev = true; 4529 4529 } 4530 4530 4531 4531 static int config_mgmt_dev(struct pci_dev *pdev)
+1 -1
drivers/net/geneve.c
··· 1007 1007 1008 1008 dev->netdev_ops = &geneve_netdev_ops; 1009 1009 dev->ethtool_ops = &geneve_ethtool_ops; 1010 - dev->destructor = free_netdev; 1010 + dev->needs_free_netdev = true; 1011 1011 1012 1012 SET_NETDEV_DEVTYPE(dev, &geneve_type); 1013 1013
+1 -1
drivers/net/gtp.c
··· 611 611 static void gtp_link_setup(struct net_device *dev) 612 612 { 613 613 dev->netdev_ops = &gtp_netdev_ops; 614 - dev->destructor = free_netdev; 614 + dev->needs_free_netdev = true; 615 615 616 616 dev->hard_header_len = 0; 617 617 dev->addr_len = 0;
+1 -1
drivers/net/hamradio/6pack.c
··· 311 311 { 312 312 /* Finish setting up the DEVICE info. */ 313 313 dev->netdev_ops = &sp_netdev_ops; 314 - dev->destructor = free_netdev; 314 + dev->needs_free_netdev = true; 315 315 dev->mtu = SIXP_MTU; 316 316 dev->hard_header_len = AX25_MAX_HEADER_LEN; 317 317 dev->header_ops = &ax25_header_ops;
+1 -1
drivers/net/hamradio/bpqether.c
··· 476 476 static void bpq_setup(struct net_device *dev) 477 477 { 478 478 dev->netdev_ops = &bpq_netdev_ops; 479 - dev->destructor = free_netdev; 479 + dev->needs_free_netdev = true; 480 480 481 481 memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); 482 482 memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
+2 -2
drivers/net/ifb.c
··· 207 207 __skb_queue_purge(&txp->tq); 208 208 } 209 209 kfree(dp->tx_private); 210 - free_netdev(dev); 211 210 } 212 211 213 212 static void ifb_setup(struct net_device *dev) ··· 229 230 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 230 231 netif_keep_dst(dev); 231 232 eth_hw_addr_random(dev); 232 - dev->destructor = ifb_dev_free; 233 + dev->needs_free_netdev = true; 234 + dev->priv_destructor = ifb_dev_free; 233 235 } 234 236 235 237 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
+1 -1
drivers/net/ipvlan/ipvlan_main.c
··· 632 632 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); 633 633 dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE; 634 634 dev->netdev_ops = &ipvlan_netdev_ops; 635 - dev->destructor = free_netdev; 635 + dev->needs_free_netdev = true; 636 636 dev->header_ops = &ipvlan_header_ops; 637 637 dev->ethtool_ops = &ipvlan_ethtool_ops; 638 638 }
+2 -2
drivers/net/loopback.c
··· 159 159 { 160 160 dev_net(dev)->loopback_dev = NULL; 161 161 free_percpu(dev->lstats); 162 - free_netdev(dev); 163 162 } 164 163 165 164 static const struct net_device_ops loopback_ops = { ··· 195 196 dev->ethtool_ops = &loopback_ethtool_ops; 196 197 dev->header_ops = &eth_header_ops; 197 198 dev->netdev_ops = &loopback_ops; 198 - dev->destructor = loopback_dev_free; 199 + dev->needs_free_netdev = true; 200 + dev->priv_destructor = loopback_dev_free; 199 201 } 200 202 201 203 /* Setup and register the loopback device. */
+2 -2
drivers/net/macsec.c
··· 2996 2996 free_percpu(macsec->secy.tx_sc.stats); 2997 2997 2998 2998 dev_put(real_dev); 2999 - free_netdev(dev); 3000 2999 } 3001 3000 3002 3001 static void macsec_setup(struct net_device *dev) ··· 3005 3006 dev->max_mtu = ETH_MAX_MTU; 3006 3007 dev->priv_flags |= IFF_NO_QUEUE; 3007 3008 dev->netdev_ops = &macsec_netdev_ops; 3008 - dev->destructor = macsec_free_netdev; 3009 + dev->needs_free_netdev = true; 3010 + dev->priv_destructor = macsec_free_netdev; 3009 3011 SET_NETDEV_DEVTYPE(dev, &macsec_type); 3010 3012 3011 3013 eth_zero_addr(dev->broadcast);
+1 -1
drivers/net/macvlan.c
··· 1092 1092 netif_keep_dst(dev); 1093 1093 dev->priv_flags |= IFF_UNICAST_FLT; 1094 1094 dev->netdev_ops = &macvlan_netdev_ops; 1095 - dev->destructor = free_netdev; 1095 + dev->needs_free_netdev = true; 1096 1096 dev->header_ops = &macvlan_hard_header_ops; 1097 1097 dev->ethtool_ops = &macvlan_ethtool_ops; 1098 1098 }
+1 -1
drivers/net/nlmon.c
··· 113 113 114 114 dev->netdev_ops = &nlmon_ops; 115 115 dev->ethtool_ops = &nlmon_ethtool_ops; 116 - dev->destructor = free_netdev; 116 + dev->needs_free_netdev = true; 117 117 118 118 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | 119 119 NETIF_F_HIGHDMA | NETIF_F_LLTX;
+3 -4
drivers/net/slip/slip.c
··· 629 629 static void sl_free_netdev(struct net_device *dev) 630 630 { 631 631 int i = dev->base_addr; 632 - free_netdev(dev); 632 + 633 633 slip_devs[i] = NULL; 634 634 } 635 635 ··· 651 651 static void sl_setup(struct net_device *dev) 652 652 { 653 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 657 dev->hard_header_len = 0; 657 658 dev->addr_len = 0; ··· 1370 1369 if (sl->tty) { 1371 1370 printk(KERN_ERR "%s: tty discipline still running\n", 1372 1371 dev->name); 1373 - /* Intentionally leak the control block. */ 1374 - dev->destructor = NULL; 1375 1372 } 1376 1373 1377 1374 unregister_netdev(dev);
+2 -2
drivers/net/team/team.c
··· 1643 1643 struct team *team = netdev_priv(dev); 1644 1644 1645 1645 free_percpu(team->pcpu_stats); 1646 - free_netdev(dev); 1647 1646 } 1648 1647 1649 1648 static int team_open(struct net_device *dev) ··· 2078 2079 2079 2080 dev->netdev_ops = &team_netdev_ops; 2080 2081 dev->ethtool_ops = &team_ethtool_ops; 2081 - dev->destructor = team_destructor; 2082 + dev->needs_free_netdev = true; 2083 + dev->priv_destructor = team_destructor; 2082 2084 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); 2083 2085 dev->priv_flags |= IFF_NO_QUEUE; 2084 2086 dev->priv_flags |= IFF_TEAM;
+2 -2
drivers/net/tun.c
··· 1560 1560 free_percpu(tun->pcpu_stats); 1561 1561 tun_flow_uninit(tun); 1562 1562 security_tun_dev_free_security(tun->security); 1563 - free_netdev(dev); 1564 1563 } 1565 1564 1566 1565 static void tun_setup(struct net_device *dev) ··· 1570 1571 tun->group = INVALID_GID; 1571 1572 1572 1573 dev->ethtool_ops = &tun_ethtool_ops; 1573 - dev->destructor = tun_free_netdev; 1574 + dev->needs_free_netdev = true; 1575 + dev->priv_destructor = tun_free_netdev; 1574 1576 /* We prefer our own queue length */ 1575 1577 dev->tx_queue_len = TUN_READQ_SIZE; 1576 1578 }
+1 -1
drivers/net/usb/cdc-phonet.c
··· 298 298 dev->addr_len = 1; 299 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 /*
+1 -1
drivers/net/usb/qmi_wwan.c
··· 123 123 dev->addr_len = 0; 124 124 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; 125 125 dev->netdev_ops = &qmimux_netdev_ops; 126 - dev->destructor = free_netdev; 126 + dev->needs_free_netdev = true; 127 127 } 128 128 129 129 static struct net_device *qmimux_find_dev(struct usbnet *dev, u8 mux_id)
+2 -2
drivers/net/veth.c
··· 222 222 static void veth_dev_free(struct net_device *dev) 223 223 { 224 224 free_percpu(dev->vstats); 225 - free_netdev(dev); 226 225 } 227 226 228 227 #ifdef CONFIG_NET_POLL_CONTROLLER ··· 316 317 NETIF_F_HW_VLAN_STAG_TX | 317 318 NETIF_F_HW_VLAN_CTAG_RX | 318 319 NETIF_F_HW_VLAN_STAG_RX); 319 - dev->destructor = veth_dev_free; 320 + dev->needs_free_netdev = true; 321 + dev->priv_destructor = veth_dev_free; 320 322 dev->max_mtu = ETH_MAX_MTU; 321 323 322 324 dev->hw_features = VETH_FEATURES;
+1 -1
drivers/net/vrf.c
··· 1348 1348 dev->netdev_ops = &vrf_netdev_ops; 1349 1349 dev->l3mdev_ops = &vrf_l3mdev_ops; 1350 1350 dev->ethtool_ops = &vrf_ethtool_ops; 1351 - dev->destructor = free_netdev; 1351 + dev->needs_free_netdev = true; 1352 1352 1353 1353 /* Fill in device structure with ethernet-generic values. */ 1354 1354 eth_hw_addr_random(dev);
+1 -1
drivers/net/vsockmon.c
··· 135 135 136 136 dev->netdev_ops = &vsockmon_ops; 137 137 dev->ethtool_ops = &vsockmon_ethtool_ops; 138 - dev->destructor = free_netdev; 138 + dev->needs_free_netdev = true; 139 139 140 140 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | 141 141 NETIF_F_HIGHDMA | NETIF_F_LLTX;
+1 -1
drivers/net/vxlan.c
··· 2611 2611 eth_hw_addr_random(dev); 2612 2612 ether_setup(dev); 2613 2613 2614 - dev->destructor = free_netdev; 2614 + dev->needs_free_netdev = true; 2615 2615 SET_NETDEV_DEVTYPE(dev, &vxlan_type); 2616 2616 2617 2617 dev->features |= NETIF_F_LLTX;
+1 -1
drivers/net/wan/dlci.c
··· 475 475 dev->flags = 0; 476 476 dev->header_ops = &dlci_header_ops; 477 477 dev->netdev_ops = &dlci_netdev_ops; 478 - dev->destructor = free_netdev; 478 + dev->needs_free_netdev = true; 479 479 480 480 dlp->receive = dlci_receive; 481 481
+1 -1
drivers/net/wan/hdlc_fr.c
··· 1106 1106 return -EIO; 1107 1107 } 1108 1108 1109 - dev->destructor = free_netdev; 1109 + dev->needs_free_netdev = true; 1110 1110 *get_dev_p(pvc, type) = dev; 1111 1111 if (!used) { 1112 1112 state(hdlc)->dce_changed = 1;
+1 -1
drivers/net/wan/lapbether.c
··· 306 306 static void lapbeth_setup(struct net_device *dev) 307 307 { 308 308 dev->netdev_ops = &lapbeth_netdev_ops; 309 - dev->destructor = free_netdev; 309 + dev->needs_free_netdev = true; 310 310 dev->type = ARPHRD_X25; 311 311 dev->hard_header_len = 3; 312 312 dev->mtu = 1000;
+1 -1
drivers/net/wireless/ath/ath6kl/main.c
··· 1287 1287 struct ath6kl *ar = ath6kl_priv(dev); 1288 1288 1289 1289 dev->netdev_ops = &ath6kl_netdev_ops; 1290 - dev->destructor = free_netdev; 1290 + dev->needs_free_netdev = true; 1291 1291 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT; 1292 1292 1293 1293 dev->needed_headroom = ETH_HLEN;
-1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
··· 5225 5225 5226 5226 if (vif) 5227 5227 brcmf_free_vif(vif); 5228 - free_netdev(ndev); 5229 5228 } 5230 5229 5231 5230 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
+2 -1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
··· 624 624 if (!ndev) 625 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 629 ifp = netdev_priv(ndev); 629 630 ifp->ndev = ndev; 630 631 /* store mapping ifidx to bsscfgidx */
+1 -1
drivers/net/wireless/intersil/hostap/hostap_main.c
··· 73 73 dev->mem_end = mdev->mem_end; 74 74 75 75 hostap_setup_dev(dev, local, type); 76 - dev->destructor = free_netdev; 76 + dev->needs_free_netdev = true; 77 77 78 78 sprintf(dev->name, "%s%s", prefix, name); 79 79 if (!rtnl_locked)
+1 -1
drivers/net/wireless/mac80211_hwsim.c
··· 2861 2861 static void hwsim_mon_setup(struct net_device *dev) 2862 2862 { 2863 2863 dev->netdev_ops = &hwsim_netdev_ops; 2864 - dev->destructor = free_netdev; 2864 + dev->needs_free_netdev = true; 2865 2865 ether_setup(dev); 2866 2866 dev->priv_flags |= IFF_NO_QUEUE; 2867 2867 dev->type = ARPHRD_IEEE80211_RADIOTAP;
+1 -1
drivers/net/wireless/marvell/mwifiex/main.c
··· 1280 1280 struct net_device *dev) 1281 1281 { 1282 1282 dev->netdev_ops = &mwifiex_netdev_ops; 1283 - dev->destructor = free_netdev; 1283 + dev->needs_free_netdev = true; 1284 1284 /* Initialize private structure */ 1285 1285 priv->current_key_index = 0; 1286 1286 priv->media_connected = false;
+1 -1
drivers/staging/rtl8188eu/os_dep/mon.c
··· 152 152 static void mon_setup(struct net_device *dev) 153 153 { 154 154 dev->netdev_ops = &mon_netdev_ops; 155 - dev->destructor = free_netdev; 155 + dev->needs_free_netdev = true; 156 156 ether_setup(dev); 157 157 dev->priv_flags |= IFF_NO_QUEUE; 158 158 dev->type = ARPHRD_IEEE80211;
+1 -1
drivers/usb/gadget/function/f_phonet.c
··· 281 281 dev->tx_queue_len = 1; 282 282 283 283 dev->netdev_ops = &pn_netdev_ops; 284 - dev->destructor = free_netdev; 284 + dev->needs_free_netdev = true; 285 285 dev->header_ops = &phonet_header_ops; 286 286 } 287 287
+4 -3
include/linux/netdevice.h
··· 1596 1596 * @rtnl_link_state: This enum represents the phases of creating 1597 1597 * a new link 1598 1598 * 1599 - * @destructor: Called from unregister, 1600 - * can be used to call free_netdev 1599 + * @needs_free_netdev: Should unregister perform free_netdev? 1600 + * @priv_destructor: Called from unregister 1601 1601 * @npinfo: XXX: need comments on this one 1602 1602 * @nd_net: Network namespace this network device is inside 1603 1603 * ··· 1858 1858 RTNL_LINK_INITIALIZING, 1859 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 1864 #ifdef CONFIG_NETPOLL 1864 1865 struct netpoll_info __rcu *npinfo;
+2 -2
net/8021q/vlan_dev.c
··· 813 813 814 814 free_percpu(vlan->vlan_pcpu_stats); 815 815 vlan->vlan_pcpu_stats = NULL; 816 - free_netdev(dev); 817 816 } 818 817 819 818 void vlan_setup(struct net_device *dev) ··· 825 826 netif_keep_dst(dev); 826 827 827 828 dev->netdev_ops = &vlan_netdev_ops; 828 - dev->destructor = vlan_dev_free; 829 + dev->needs_free_netdev = true; 830 + dev->priv_destructor = vlan_dev_free; 829 831 dev->ethtool_ops = &vlan_ethtool_ops; 830 832 831 833 dev->min_mtu = 0;
+2 -3
net/batman-adv/soft-interface.c
··· 1034 1034 * netdev and its private data (bat_priv) 1035 1035 */ 1036 1036 rcu_barrier(); 1037 - 1038 - free_netdev(dev); 1039 1037 } 1040 1038 1041 1039 /** ··· 1045 1047 ether_setup(dev); 1046 1048 1047 1049 dev->netdev_ops = &batadv_netdev_ops; 1048 - dev->destructor = batadv_softif_free; 1050 + dev->needs_free_netdev = true; 1051 + dev->priv_destructor = batadv_softif_free; 1049 1052 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; 1050 1053 dev->priv_flags |= IFF_NO_QUEUE; 1051 1054
+1 -1
net/bluetooth/6lowpan.c
··· 598 598 599 599 dev->netdev_ops = &netdev_ops; 600 600 dev->header_ops = &header_ops; 601 - dev->destructor = free_netdev; 601 + dev->needs_free_netdev = true; 602 602 } 603 603 604 604 static struct device_type bt_type = {
+1 -1
net/bridge/br_device.c
··· 379 379 ether_setup(dev); 380 380 381 381 dev->netdev_ops = &br_netdev_ops; 382 - dev->destructor = free_netdev; 382 + dev->needs_free_netdev = true; 383 383 dev->ethtool_ops = &br_ethtool_ops; 384 384 SET_NETDEV_DEVTYPE(dev, &br_type); 385 385 dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
+2 -2
net/caif/chnl_net.c
··· 392 392 { 393 393 struct chnl_net *priv = netdev_priv(dev); 394 394 caif_free_client(&priv->chnl); 395 - free_netdev(dev); 396 395 } 397 396 398 397 static void ipcaif_net_setup(struct net_device *dev) 399 398 { 400 399 struct chnl_net *priv; 401 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 403 dev->flags |= IFF_NOARP; 404 404 dev->flags |= IFF_POINTOPOINT; 405 405 dev->mtu = GPRS_PDP_MTU;
+6 -2
net/core/dev.c
··· 7502 7502 err_uninit: 7503 7503 if (dev->netdev_ops->ndo_uninit) 7504 7504 dev->netdev_ops->ndo_uninit(dev); 7505 + if (dev->priv_destructor) 7506 + dev->priv_destructor(dev); 7505 7507 goto out; 7506 7508 } 7507 7509 EXPORT_SYMBOL(register_netdevice); ··· 7711 7709 WARN_ON(rcu_access_pointer(dev->ip6_ptr)); 7712 7710 WARN_ON(dev->dn_ptr); 7713 7711 7714 - if (dev->destructor) 7715 - dev->destructor(dev); 7712 + if (dev->priv_destructor) 7713 + dev->priv_destructor(dev); 7714 + if (dev->needs_free_netdev) 7715 + free_netdev(dev); 7716 7716 7717 7717 /* Report a network device has been unregistered */ 7718 7718 rtnl_lock();
+2 -2
net/hsr/hsr_device.c
··· 378 378 del_timer_sync(&hsr->announce_timer); 379 379 380 380 synchronize_rcu(); 381 - free_netdev(hsr_dev); 382 381 } 383 382 384 383 static const struct net_device_ops hsr_device_ops = { ··· 403 404 SET_NETDEV_DEVTYPE(dev, &hsr_type); 404 405 dev->priv_flags |= IFF_NO_QUEUE; 405 406 406 - dev->destructor = hsr_dev_destroy; 407 + dev->needs_free_netdev = true; 408 + dev->priv_destructor = hsr_dev_destroy; 407 409 408 410 dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 409 411 NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
+1 -1
net/ieee802154/6lowpan/core.c
··· 107 107 108 108 ldev->netdev_ops = &lowpan_netdev_ops; 109 109 ldev->header_ops = &lowpan_header_ops; 110 - ldev->destructor = free_netdev; 110 + ldev->needs_free_netdev = true; 111 111 ldev->features |= NETIF_F_NETNS_LOCAL; 112 112 } 113 113
+2 -2
net/ipv4/ip_tunnel.c
··· 967 967 gro_cells_destroy(&tunnel->gro_cells); 968 968 dst_cache_destroy(&tunnel->dst_cache); 969 969 free_percpu(dev->tstats); 970 - free_netdev(dev); 971 970 } 972 971 973 972 void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) ··· 1154 1155 struct iphdr *iph = &tunnel->parms.iph; 1155 1156 int err; 1156 1157 1157 - dev->destructor = ip_tunnel_dev_free; 1158 + dev->needs_free_netdev = true; 1159 + dev->priv_destructor = ip_tunnel_dev_free; 1158 1160 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 1159 1161 if (!dev->tstats) 1160 1162 return -ENOMEM;
+1 -1
net/ipv4/ipmr.c
··· 501 501 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8; 502 502 dev->flags = IFF_NOARP; 503 503 dev->netdev_ops = &reg_vif_netdev_ops; 504 - dev->destructor = free_netdev; 504 + dev->needs_free_netdev = true; 505 505 dev->features |= NETIF_F_NETNS_LOCAL; 506 506 } 507 507
+5 -4
net/ipv6/ip6_gre.c
··· 991 991 992 992 dst_cache_destroy(&t->dst_cache); 993 993 free_percpu(dev->tstats); 994 - free_netdev(dev); 995 994 } 996 995 997 996 static void ip6gre_tunnel_setup(struct net_device *dev) 998 997 { 999 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 1002 dev->type = ARPHRD_IP6GRE; 1003 1003 ··· 1148 1148 return 0; 1149 1149 1150 1150 err_reg_dev: 1151 - ip6gre_dev_free(ign->fb_tunnel_dev); 1151 + free_netdev(ign->fb_tunnel_dev); 1152 1152 err_alloc_dev: 1153 1153 return err; 1154 1154 } ··· 1300 1300 ether_setup(dev); 1301 1301 1302 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 1306 dev->features |= NETIF_F_NETNS_LOCAL; 1306 1307 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+4 -4
net/ipv6/ip6_tunnel.c
··· 254 254 gro_cells_destroy(&t->gro_cells); 255 255 dst_cache_destroy(&t->dst_cache); 256 256 free_percpu(dev->tstats); 257 - free_netdev(dev); 258 257 } 259 258 260 259 static int ip6_tnl_create2(struct net_device *dev) ··· 321 322 return t; 322 323 323 324 failed_free: 324 - ip6_dev_free(dev); 325 + free_netdev(dev); 325 326 failed: 326 327 return ERR_PTR(err); 327 328 } ··· 1776 1777 static void ip6_tnl_dev_setup(struct net_device *dev) 1777 1778 { 1778 1779 dev->netdev_ops = &ip6_tnl_netdev_ops; 1779 - dev->destructor = ip6_dev_free; 1780 + dev->needs_free_netdev = true; 1781 + dev->priv_destructor = ip6_dev_free; 1780 1782 1781 1783 dev->type = ARPHRD_TUNNEL6; 1782 1784 dev->flags |= IFF_NOARP; ··· 2224 2224 return 0; 2225 2225 2226 2226 err_register: 2227 - ip6_dev_free(ip6n->fb_tnl_dev); 2227 + free_netdev(ip6n->fb_tnl_dev); 2228 2228 err_alloc_dev: 2229 2229 return err; 2230 2230 }
+4 -4
net/ipv6/ip6_vti.c
··· 180 180 static void vti6_dev_free(struct net_device *dev) 181 181 { 182 182 free_percpu(dev->tstats); 183 - free_netdev(dev); 184 183 } 185 184 186 185 static int vti6_tnl_create2(struct net_device *dev) ··· 234 235 return t; 235 236 236 237 failed_free: 237 - vti6_dev_free(dev); 238 + free_netdev(dev); 238 239 failed: 239 240 return NULL; 240 241 } ··· 841 842 static void vti6_dev_setup(struct net_device *dev) 842 843 { 843 844 dev->netdev_ops = &vti6_netdev_ops; 844 - dev->destructor = vti6_dev_free; 845 + dev->needs_free_netdev = true; 846 + dev->priv_destructor = vti6_dev_free; 845 847 846 848 dev->type = ARPHRD_TUNNEL6; 847 849 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr); ··· 1100 1100 return 0; 1101 1101 1102 1102 err_register: 1103 - vti6_dev_free(ip6n->fb_tnl_dev); 1103 + free_netdev(ip6n->fb_tnl_dev); 1104 1104 err_alloc_dev: 1105 1105 return err; 1106 1106 }
+1 -1
net/ipv6/ip6mr.c
··· 733 733 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; 734 734 dev->flags = IFF_NOARP; 735 735 dev->netdev_ops = &reg_vif_netdev_ops; 736 - dev->destructor = free_netdev; 736 + dev->needs_free_netdev = true; 737 737 dev->features |= NETIF_F_NETNS_LOCAL; 738 738 } 739 739
+3 -3
net/ipv6/sit.c
··· 265 265 return nt; 266 266 267 267 failed_free: 268 - ipip6_dev_free(dev); 268 + free_netdev(dev); 269 269 failed: 270 270 return NULL; 271 271 } ··· 1336 1336 1337 1337 dst_cache_destroy(&tunnel->dst_cache); 1338 1338 free_percpu(dev->tstats); 1339 - free_netdev(dev); 1340 1339 } 1341 1340 1342 1341 #define SIT_FEATURES (NETIF_F_SG | \ ··· 1350 1351 int t_hlen = tunnel->hlen + sizeof(struct iphdr); 1351 1352 1352 1353 dev->netdev_ops = &ipip6_netdev_ops; 1353 - dev->destructor = ipip6_dev_free; 1354 + dev->needs_free_netdev = true; 1355 + dev->priv_destructor = ipip6_dev_free; 1354 1356 1355 1357 dev->type = ARPHRD_SIT; 1356 1358 dev->hard_header_len = LL_MAX_HEADER + t_hlen;
+1 -1
net/irda/irlan/irlan_eth.c
··· 65 65 ether_setup(dev); 66 66 67 67 dev->netdev_ops = &irlan_eth_netdev_ops; 68 - dev->destructor = free_netdev; 68 + dev->needs_free_netdev = true; 69 69 dev->min_mtu = 0; 70 70 dev->max_mtu = ETH_MAX_MTU; 71 71
+1 -1
net/l2tp/l2tp_eth.c
··· 141 141 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 142 142 dev->features |= NETIF_F_LLTX; 143 143 dev->netdev_ops = &l2tp_eth_netdev_ops; 144 - dev->destructor = free_netdev; 144 + dev->needs_free_netdev = true; 145 145 } 146 146 147 147 static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+3 -3
net/mac80211/iface.c
··· 1213 1213 static void ieee80211_if_free(struct net_device *dev) 1214 1214 { 1215 1215 free_percpu(dev->tstats); 1216 - free_netdev(dev); 1217 1216 } 1218 1217 1219 1218 static void ieee80211_if_setup(struct net_device *dev) ··· 1220 1221 ether_setup(dev); 1221 1222 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 1222 1223 dev->netdev_ops = &ieee80211_dataif_ops; 1223 - dev->destructor = ieee80211_if_free; 1224 + dev->needs_free_netdev = true; 1225 + dev->priv_destructor = ieee80211_if_free; 1224 1226 } 1225 1227 1226 1228 static void ieee80211_if_setup_no_queue(struct net_device *dev) ··· 1905 1905 1906 1906 ret = register_netdevice(ndev); 1907 1907 if (ret) { 1908 - ieee80211_if_free(ndev); 1908 + free_netdev(ndev); 1909 1909 return ret; 1910 1910 } 1911 1911 }
+3 -4
net/mac802154/iface.c
··· 526 526 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 527 527 528 528 mac802154_llsec_destroy(&sdata->sec); 529 - 530 - free_netdev(dev); 531 529 } 532 530 533 531 static void ieee802154_if_setup(struct net_device *dev) ··· 591 593 sdata->dev->dev_addr); 592 594 593 595 sdata->dev->header_ops = &mac802154_header_ops; 594 - sdata->dev->destructor = mac802154_wpan_free; 596 + sdata->dev->needs_free_netdev = true; 597 + sdata->dev->priv_destructor = mac802154_wpan_free; 595 598 sdata->dev->netdev_ops = &mac802154_wpan_ops; 596 599 sdata->dev->ml_priv = &mac802154_mlme_wpan; 597 600 wpan_dev->promiscuous_mode = false; ··· 607 608 608 609 break; 609 610 case NL802154_IFTYPE_MONITOR: 610 - sdata->dev->destructor = free_netdev; 611 + sdata->dev->needs_free_netdev = true; 611 612 sdata->dev->netdev_ops = &mac802154_monitor_ops; 612 613 wpan_dev->promiscuous_mode = true; 613 614 break;
+2 -2
net/openvswitch/vport-internal_dev.c
··· 94 94 struct vport *vport = ovs_internal_dev_get_vport(dev); 95 95 96 96 ovs_vport_free(vport); 97 - free_netdev(dev); 98 97 } 99 98 100 99 static void ··· 155 156 netdev->priv_flags &= ~IFF_TX_SKB_SHARING; 156 157 netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH | 157 158 IFF_PHONY_HEADROOM | IFF_NO_QUEUE; 158 - netdev->destructor = internal_dev_destructor; 159 + netdev->needs_free_netdev = true; 160 + netdev->priv_destructor = internal_dev_destructor; 159 161 netdev->ethtool_ops = &internal_dev_ethtool_ops; 160 162 netdev->rtnl_link_ops = &internal_dev_link_ops; 161 163
+1 -1
net/phonet/pep-gprs.c
··· 236 236 dev->tx_queue_len = 10; 237 237 238 238 dev->netdev_ops = &gprs_netdev_ops; 239 - dev->destructor = free_netdev; 239 + dev->needs_free_netdev = true; 240 240 } 241 241 242 242 /*