vxlan: move cleanup to uninit
authorStephen Hemminger <stephen@networkplumber.org>
Mon, 17 Jun 2013 21:16:11 +0000 (14:16 -0700)
committerStephen Hemminger <stephen@networkplumber.org>
Mon, 24 Jun 2013 15:40:32 +0000 (08:40 -0700)
Put destruction of per-cpu statistics removal in
ndo_uninit since it is created by ndo_init.
This also avoids any problems that might be cause by destructor
being called after module removed.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
drivers/net/vxlan.c

index 71da8be98801b942b19d3ba06983f21e63f5027d..500f9ce437ecb6a7b664f314723a7ae1fb87c4a8 100644 (file)
@@ -1256,6 +1256,17 @@ static int vxlan_init(struct net_device *dev)
        return 0;
 }
 
+static void vxlan_uninit(struct net_device *dev)
+{
+       struct vxlan_dev *vxlan = netdev_priv(dev);
+       struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+       struct vxlan_sock *vs = vxlan->vn_sock;
+
+       if (vs)
+               vxlan_sock_release(vn, vs);
+       free_percpu(dev->tstats);
+}
+
 /* Start ageing timer and join group when device is brought up */
 static int vxlan_open(struct net_device *dev)
 {
@@ -1321,6 +1332,7 @@ static void vxlan_set_multicast_list(struct net_device *dev)
 
 static const struct net_device_ops vxlan_netdev_ops = {
        .ndo_init               = vxlan_init,
+       .ndo_uninit             = vxlan_uninit,
        .ndo_open               = vxlan_open,
        .ndo_stop               = vxlan_stop,
        .ndo_start_xmit         = vxlan_xmit,
@@ -1339,12 +1351,6 @@ static struct device_type vxlan_type = {
        .name = "vxlan",
 };
 
-static void vxlan_free(struct net_device *dev)
-{
-       free_percpu(dev->tstats);
-       free_netdev(dev);
-}
-
 /* Initialize the device structure. */
 static void vxlan_setup(struct net_device *dev)
 {
@@ -1357,7 +1363,7 @@ static void vxlan_setup(struct net_device *dev)
        dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
 
        dev->netdev_ops = &vxlan_netdev_ops;
-       dev->destructor = vxlan_free;
+       dev->destructor = free_netdev;
        SET_NETDEV_DEVTYPE(dev, &vxlan_type);
 
        dev->tx_queue_len = 0;
@@ -1660,14 +1666,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
 static void vxlan_dellink(struct net_device *dev, struct list_head *head)
 {
        struct vxlan_dev *vxlan = netdev_priv(dev);
-       struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
-       struct vxlan_sock *vs = vxlan->vn_sock;
 
        hlist_del_rcu(&vxlan->hlist);
        list_del(&vxlan->next);
        unregister_netdevice_queue(dev, head);
-       if (vs)
-               vxlan_sock_release(vn, vs);
 }
 
 static size_t vxlan_get_size(const struct net_device *dev)