aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/macvlan.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 29b3bb410781..bfb0b6ec8c56 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -272,7 +272,7 @@ static void macvlan_process_broadcast(struct work_struct *w)
272 struct sk_buff *skb; 272 struct sk_buff *skb;
273 struct sk_buff_head list; 273 struct sk_buff_head list;
274 274
275 skb_queue_head_init(&list); 275 __skb_queue_head_init(&list);
276 276
277 spin_lock_bh(&port->bc_queue.lock); 277 spin_lock_bh(&port->bc_queue.lock);
278 skb_queue_splice_tail_init(&port->bc_queue, &list); 278 skb_queue_splice_tail_init(&port->bc_queue, &list);
@@ -1082,9 +1082,15 @@ static void macvlan_port_destroy(struct net_device *dev)
1082{ 1082{
1083 struct macvlan_port *port = macvlan_port_get_rtnl(dev); 1083 struct macvlan_port *port = macvlan_port_get_rtnl(dev);
1084 1084
1085 cancel_work_sync(&port->bc_work);
1086 dev->priv_flags &= ~IFF_MACVLAN_PORT; 1085 dev->priv_flags &= ~IFF_MACVLAN_PORT;
1087 netdev_rx_handler_unregister(dev); 1086 netdev_rx_handler_unregister(dev);
1087
1088 /* After this point, no packet can schedule bc_work anymore,
1089 * but we need to cancel it and purge left skbs if any.
1090 */
1091 cancel_work_sync(&port->bc_work);
1092 __skb_queue_purge(&port->bc_queue);
1093
1088 kfree_rcu(port, rcu); 1094 kfree_rcu(port, rcu);
1089} 1095}
1090 1096