]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/hsr/hsr_device.c
Merge tag 'for-5.3-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
[linux.git] / net / hsr / hsr_device.c
index 15c72065df79103fa78ee47db8f076a62529b055..f509b495451a9f434a2bfee206c0adce9937a439 100644 (file)
@@ -229,7 +229,6 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
        skb->dev = master->dev;
        hsr_forward_skb(skb, master);
-
        return NETDEV_TX_OK;
 }
 
@@ -344,27 +343,28 @@ static void hsr_announce(struct timer_list *t)
        rcu_read_unlock();
 }
 
-/* According to comments in the declaration of struct net_device, this function
- * is "Called from unregister, can be used to call free_netdev". Ok then...
+/* This has to be called after all the readers are gone.
+ * Otherwise we would have to check the return value of
+ * hsr_port_get_hsr().
  */
 static void hsr_dev_destroy(struct net_device *hsr_dev)
 {
        struct hsr_priv *hsr;
        struct hsr_port *port;
+       struct hsr_port *tmp;
 
        hsr = netdev_priv(hsr_dev);
 
        hsr_debugfs_term(hsr);
 
-       rtnl_lock();
-       hsr_for_each_port(hsr, port)
+       list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
                hsr_del_port(port);
-       rtnl_unlock();
 
        del_timer_sync(&hsr->prune_timer);
        del_timer_sync(&hsr->announce_timer);
 
-       synchronize_rcu();
+       hsr_del_self_node(&hsr->self_node_db);
+       hsr_del_nodes(&hsr->node_db);
 }
 
 static const struct net_device_ops hsr_device_ops = {
@@ -373,6 +373,7 @@ static const struct net_device_ops hsr_device_ops = {
        .ndo_stop = hsr_dev_close,
        .ndo_start_xmit = hsr_dev_xmit,
        .ndo_fix_features = hsr_fix_features,
+       .ndo_uninit = hsr_dev_destroy,
 };
 
 static struct device_type hsr_type = {
@@ -391,7 +392,6 @@ void hsr_dev_setup(struct net_device *dev)
        dev->priv_flags |= IFF_NO_QUEUE;
 
        dev->needs_free_netdev = true;
-       dev->priv_destructor = hsr_dev_destroy;
 
        dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
                           NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
@@ -428,6 +428,7 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
 {
        struct hsr_priv *hsr;
        struct hsr_port *port;
+       struct hsr_port *tmp;
        int res;
 
        hsr = netdev_priv(hsr_dev);
@@ -492,10 +493,10 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
        return 0;
 
 fail:
-       hsr_for_each_port(hsr, port)
+       list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
                hsr_del_port(port);
 err_add_port:
-       hsr_del_node(&hsr->self_node_db);
+       hsr_del_self_node(&hsr->self_node_db);
 
        return res;
 }