Commit ebf4063e authored by Stephen Hemminger's avatar Stephen Hemminger

vxlan: move cleanup to uninit

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: default avatarStephen Hemminger <stephen@networkplumber.org>
parent 1c51a915
...@@ -1256,6 +1256,17 @@ static int vxlan_init(struct net_device *dev) ...@@ -1256,6 +1256,17 @@ static int vxlan_init(struct net_device *dev)
return 0; 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 */ /* Start ageing timer and join group when device is brought up */
static int vxlan_open(struct net_device *dev) static int vxlan_open(struct net_device *dev)
{ {
...@@ -1321,6 +1332,7 @@ static void vxlan_set_multicast_list(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 = { static const struct net_device_ops vxlan_netdev_ops = {
.ndo_init = vxlan_init, .ndo_init = vxlan_init,
.ndo_uninit = vxlan_uninit,
.ndo_open = vxlan_open, .ndo_open = vxlan_open,
.ndo_stop = vxlan_stop, .ndo_stop = vxlan_stop,
.ndo_start_xmit = vxlan_xmit, .ndo_start_xmit = vxlan_xmit,
...@@ -1339,12 +1351,6 @@ static struct device_type vxlan_type = { ...@@ -1339,12 +1351,6 @@ static struct device_type vxlan_type = {
.name = "vxlan", .name = "vxlan",
}; };
static void vxlan_free(struct net_device *dev)
{
free_percpu(dev->tstats);
free_netdev(dev);
}
/* Initialize the device structure. */ /* Initialize the device structure. */
static void vxlan_setup(struct net_device *dev) static void vxlan_setup(struct net_device *dev)
{ {
...@@ -1357,7 +1363,7 @@ 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->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
dev->netdev_ops = &vxlan_netdev_ops; dev->netdev_ops = &vxlan_netdev_ops;
dev->destructor = vxlan_free; dev->destructor = free_netdev;
SET_NETDEV_DEVTYPE(dev, &vxlan_type); SET_NETDEV_DEVTYPE(dev, &vxlan_type);
dev->tx_queue_len = 0; dev->tx_queue_len = 0;
...@@ -1660,14 +1666,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, ...@@ -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) static void vxlan_dellink(struct net_device *dev, struct list_head *head)
{ {
struct vxlan_dev *vxlan = netdev_priv(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;
hlist_del_rcu(&vxlan->hlist); hlist_del_rcu(&vxlan->hlist);
list_del(&vxlan->next); list_del(&vxlan->next);
unregister_netdevice_queue(dev, head); unregister_netdevice_queue(dev, head);
if (vs)
vxlan_sock_release(vn, vs);
} }
static size_t vxlan_get_size(const struct net_device *dev) static size_t vxlan_get_size(const struct net_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment