aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <[email protected]>2020-08-26 16:16:39 -0700
committerDavid S. Miller <[email protected]>2020-08-26 16:16:39 -0700
commit5875568aa187c0330fdd81159d0d72f855886099 (patch)
tree212b4bc9439e21c34da2ad7984be27c7be44a7bd
parent7f6f32bb7d3355cd78ebf1dece9a6ea7a0ca8158 (diff)
parent96ecdcc992eb7f468b2cf829b0f5408a1fad4668 (diff)
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 <[email protected]>
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c12
-rw-r--r--net/core/dev.c3
-rw-r--r--net/core/netpoll.c2
3 files changed, 7 insertions, 10 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 316227136f5b..57d0e195cddf 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -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);
diff --git a/net/core/dev.c b/net/core/dev.c
index d42c9ea0c3c0..95ac7568f693 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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);
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 093e90e52bc2..2338753e936b 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -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);