提交 f0f9deae 编写于 作者: H Herbert Xu 提交者: 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: NHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册