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>
Signed-off-by: David S. Miller <davem@davemloft.net>
Esse commit está contido em:
Herbert Xu
2010-09-17 16:55:03 -07:00
commit de David S. Miller
commit f0f9deae9e
+4 -4
Ver Arquivo
@@ -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;
}