|
@@ -272,7 +272,7 @@ static void macvlan_process_broadcast(struct work_struct *w)
|
|
|
struct sk_buff *skb;
|
|
|
struct sk_buff_head list;
|
|
|
|
|
|
- skb_queue_head_init(&list);
|
|
|
+ __skb_queue_head_init(&list);
|
|
|
|
|
|
spin_lock_bh(&port->bc_queue.lock);
|
|
|
skb_queue_splice_tail_init(&port->bc_queue, &list);
|
|
@@ -1082,9 +1082,15 @@ static void macvlan_port_destroy(struct net_device *dev)
|
|
|
{
|
|
|
struct macvlan_port *port = macvlan_port_get_rtnl(dev);
|
|
|
|
|
|
- cancel_work_sync(&port->bc_work);
|
|
|
dev->priv_flags &= ~IFF_MACVLAN_PORT;
|
|
|
netdev_rx_handler_unregister(dev);
|
|
|
+
|
|
|
+ /* After this point, no packet can schedule bc_work anymore,
|
|
|
+ * but we need to cancel it and purge left skbs if any.
|
|
|
+ */
|
|
|
+ cancel_work_sync(&port->bc_work);
|
|
|
+ __skb_queue_purge(&port->bc_queue);
|
|
|
+
|
|
|
kfree_rcu(port, rcu);
|
|
|
}
|
|
|
|