Message ID | 20100811112706.GA6772@gondor.apana.org.au |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
On Wed, Aug 11, 2010 at 07:27:06AM -0400, Herbert Xu wrote: > On Wed, Aug 11, 2010 at 07:03:30AM -0400, Herbert Xu wrote: > > > > To use rcu_read_lock safely we'd also need to add do synchronize_rcu > > in addition of synchronize_rcu_bh, right Paul? > > > > Of course as we were doing this unsafely prior to my patch anyway > > I'm also fine with just reverting it. > > Actually, we could just disable IRQs for stable. How about this > patch (untested)? > > netpoll: Disable IRQ around RCU dereference in netpoll_rx > > We cannot use rcu_dereference_bh safely in netpoll_rx as we may > be called with IRQs disabled. We could however simply disable > IRQs as that too causes BH to be disabled and is safe in either > case. > > Thanks to John Linville for discovering this bug and providing > a patch. > > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> This also seems to work for me. John P.S. As pointed-out elsewhere, my patch neglected to change synchronize_rcu_bh to synchronize_rcu in netpoll.c. If some fault is found w/ Herbert's patch then I can post a modified version of mine.
From: "John W. Linville" <linville@tuxdriver.com> Date: Wed, 11 Aug 2010 11:37:36 -0400 > On Wed, Aug 11, 2010 at 07:27:06AM -0400, Herbert Xu wrote: >> On Wed, Aug 11, 2010 at 07:03:30AM -0400, Herbert Xu wrote: >> > >> > To use rcu_read_lock safely we'd also need to add do synchronize_rcu >> > in addition of synchronize_rcu_bh, right Paul? >> > >> > Of course as we were doing this unsafely prior to my patch anyway >> > I'm also fine with just reverting it. >> >> Actually, we could just disable IRQs for stable. How about this >> patch (untested)? >> >> netpoll: Disable IRQ around RCU dereference in netpoll_rx >> >> We cannot use rcu_dereference_bh safely in netpoll_rx as we may >> be called with IRQs disabled. We could however simply disable >> IRQs as that too causes BH to be disabled and is safe in either >> case. >> >> Thanks to John Linville for discovering this bug and providing >> a patch. >> >> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> > > This also seems to work for me. I'll queue up this variant for -stable. And we'll go with making use of Paul's new RCU irqsoff interface approach for Linus's tree. Thanks. -- 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/include/linux/netpoll.h b/include/linux/netpoll.h index 413742c..54f286b 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -63,20 +63,20 @@ static inline bool netpoll_rx(struct sk_buff *skb) unsigned long flags; bool ret = false; - rcu_read_lock_bh(); + local_irq_save(flags); npinfo = rcu_dereference_bh(skb->dev->npinfo); if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) goto out; - spin_lock_irqsave(&npinfo->rx_lock, flags); + spin_lock(&npinfo->rx_lock); /* check rx_flags again with the lock held */ if (npinfo->rx_flags && __netpoll_rx(skb)) ret = true; - spin_unlock_irqrestore(&npinfo->rx_lock, flags); + spin_unlock(&npinfo->rx_lock); out: - rcu_read_unlock_bh(); + local_irq_restore(flags); return ret; }