Commit 5875568a authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 7f6f32bb 96ecdcc9
...@@ -9504,15 +9504,15 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) ...@@ -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); rc = bnxt_init_nic(bp, irq_re_init);
if (rc) { if (rc) {
netdev_err(bp->dev, "bnxt_init_nic err: %x\n", 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) { if (link_re_init) {
mutex_lock(&bp->link_lock); mutex_lock(&bp->link_lock);
rc = bnxt_update_phy_setting(bp); 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) ...@@ -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); bnxt_vf_reps_open(bp);
return 0; return 0;
open_err:
bnxt_debug_dev_exit(bp);
bnxt_disable_napi(bp);
open_err_irq: open_err_irq:
bnxt_del_napi(bp); bnxt_del_napi(bp);
......
...@@ -6612,12 +6612,13 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi, ...@@ -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__, netdev_err_once(dev, "%s() called with weight %d\n", __func__,
weight); weight);
napi->weight = weight; napi->weight = weight;
list_add(&napi->dev_list, &dev->napi_list);
napi->dev = dev; napi->dev = dev;
#ifdef CONFIG_NETPOLL #ifdef CONFIG_NETPOLL
napi->poll_owner = -1; napi->poll_owner = -1;
#endif #endif
set_bit(NAPI_STATE_SCHED, &napi->state); 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); napi_hash_add(napi);
} }
EXPORT_SYMBOL(netif_napi_add); EXPORT_SYMBOL(netif_napi_add);
......
...@@ -162,7 +162,7 @@ static void poll_napi(struct net_device *dev) ...@@ -162,7 +162,7 @@ static void poll_napi(struct net_device *dev)
struct napi_struct *napi; struct napi_struct *napi;
int cpu = smp_processor_id(); 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) { if (cmpxchg(&napi->poll_owner, -1, cpu) == -1) {
poll_one_napi(napi); poll_one_napi(napi);
smp_store_release(&napi->poll_owner, -1); smp_store_release(&napi->poll_owner, -1);
......
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