Message ID | 1414032226.2094.14.camel@edumazet-glaptop2.roam.corp.google.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
On Wed, Oct 22, 2014 at 07:43:46PM -0700, Eric Dumazet wrote: > From: Eric Dumazet <edumazet@google.com> > > We need to cancel the work queue after rcu grace period, > otherwise it can be rescheduled by incoming packets. > > We need to purge queue if some skbs are still in it. > > We can use __skb_queue_head_init() variant in > macvlan_process_broadcast() > > Signed-off-by: Eric Dumazet <edumazet@google.com> > Fixes: 412ca1550cbec ("macvlan: Move broadcasts into a work queue") > Cc: Herbert Xu <herbert@gondor.apana.org.au> Good catch! Your fix looks good to me. Thanks,
From: Herbert Xu <herbert@gondor.apana.org.au> Date: Thu, 23 Oct 2014 11:28:58 +0800 > On Wed, Oct 22, 2014 at 07:43:46PM -0700, Eric Dumazet wrote: >> From: Eric Dumazet <edumazet@google.com> >> >> We need to cancel the work queue after rcu grace period, >> otherwise it can be rescheduled by incoming packets. >> >> We need to purge queue if some skbs are still in it. >> >> We can use __skb_queue_head_init() variant in >> macvlan_process_broadcast() >> >> Signed-off-by: Eric Dumazet <edumazet@google.com> >> Fixes: 412ca1550cbec ("macvlan: Move broadcasts into a work queue") >> Cc: Herbert Xu <herbert@gondor.apana.org.au> > > Good catch! Your fix looks good to me. Applied and queued up for -stable, thanks everyone. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 29b3bb410781..98c2732755ea 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -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); }