Commit f0f9deae authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

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: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4bdab433
...@@ -63,20 +63,20 @@ static inline bool netpoll_rx(struct sk_buff *skb) ...@@ -63,20 +63,20 @@ static inline bool netpoll_rx(struct sk_buff *skb)
unsigned long flags; unsigned long flags;
bool ret = false; bool ret = false;
rcu_read_lock_bh(); local_irq_save(flags);
npinfo = rcu_dereference_bh(skb->dev->npinfo); npinfo = rcu_dereference_bh(skb->dev->npinfo);
if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags))
goto out; goto out;
spin_lock_irqsave(&npinfo->rx_lock, flags); spin_lock(&npinfo->rx_lock);
/* check rx_flags again with the lock held */ /* check rx_flags again with the lock held */
if (npinfo->rx_flags && __netpoll_rx(skb)) if (npinfo->rx_flags && __netpoll_rx(skb))
ret = true; ret = true;
spin_unlock_irqrestore(&npinfo->rx_lock, flags); spin_unlock(&npinfo->rx_lock);
out: out:
rcu_read_unlock_bh(); local_irq_restore(flags);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment