Merge branch 'net-fix-netpoll-crash-with-bnxt'

Jakub Kicinski says:

====================
net: fix netpoll crash with bnxt

Rob run into crashes when using XDP on bnxt. Upon investigation
it turns out that during driver reconfig irq core produces
a warning message when IRQs are requested. This triggers netpoll,
which in turn accesses uninitialized driver state. Same crash can
also be triggered on this platform by changing the number of rings.

Looks like we have two missing pieces here, netif_napi_add() has
to make sure we start out with netpoll blocked. The driver also
has to be more careful about when napi gets enabled.

Tested XDP and channel count changes, the warning message no longer
causes a crash. Not sure if the memory barriers added in patch 1
are necessary, but it seems we should have them.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2020-08-26 16:16:39 -07:00
commit 5875568aa1
3 changed files with 7 additions and 10 deletions

View File

@ -9504,15 +9504,15 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
}
}
bnxt_enable_napi(bp);
bnxt_debug_dev_init(bp);
rc = bnxt_init_nic(bp, irq_re_init);
if (rc) {
netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc);
goto open_err;
goto open_err_irq;
}
bnxt_enable_napi(bp);
bnxt_debug_dev_init(bp);
if (link_re_init) {
mutex_lock(&bp->link_lock);
rc = bnxt_update_phy_setting(bp);
@ -9543,10 +9543,6 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
bnxt_vf_reps_open(bp);
return 0;
open_err:
bnxt_debug_dev_exit(bp);
bnxt_disable_napi(bp);
open_err_irq:
bnxt_del_napi(bp);

View File

@ -6612,12 +6612,13 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
netdev_err_once(dev, "%s() called with weight %d\n", __func__,
weight);
napi->weight = weight;
list_add(&napi->dev_list, &dev->napi_list);
napi->dev = dev;
#ifdef CONFIG_NETPOLL
napi->poll_owner = -1;
#endif
set_bit(NAPI_STATE_SCHED, &napi->state);
set_bit(NAPI_STATE_NPSVC, &napi->state);
list_add_rcu(&napi->dev_list, &dev->napi_list);
napi_hash_add(napi);
}
EXPORT_SYMBOL(netif_napi_add);

View File

@ -162,7 +162,7 @@ static void poll_napi(struct net_device *dev)
struct napi_struct *napi;
int cpu = smp_processor_id();
list_for_each_entry(napi, &dev->napi_list, dev_list) {
list_for_each_entry_rcu(napi, &dev->napi_list, dev_list) {
if (cmpxchg(&napi->poll_owner, -1, cpu) == -1) {
poll_one_napi(napi);
smp_store_release(&napi->poll_owner, -1);