summaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2020-08-26 12:40:06 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-09-12 13:40:23 +0200
commit9f313bcb3b3d021f9b2f04f6d8464f8e9e309452 (patch)
tree76bb5daa6c38cf34d5f626c8e1ef4a034714f3b8 /net/core/dev.c
parent553d1bb7f4d1d2b86b7527c10be31b2f5f78bd8c (diff)
downloadlinux-stable-9f313bcb3b3d021f9b2f04f6d8464f8e9e309452.tar.gz
linux-stable-9f313bcb3b3d021f9b2f04f6d8464f8e9e309452.tar.bz2
linux-stable-9f313bcb3b3d021f9b2f04f6d8464f8e9e309452.zip
net: disable netpoll on fresh napis
[ Upstream commit 96e97bc07e90f175a8980a22827faf702ca4cb30 ] napi_disable() makes sure to set the NAPI_STATE_NPSVC bit to prevent netpoll from accessing rings before init is complete. However, the same is not done for fresh napi instances in netif_napi_add(), even though we expect NAPI instances to be added as disabled. This causes crashes during driver reconfiguration (enabling XDP, changing the channel count) - if there is any printk() after netif_napi_add() but before napi_enable(). To ensure memory ordering is correct we need to use RCU accessors. Reported-by: Rob Sherwood <rsher@fb.com> Fixes: 2d8bff12699a ("netpoll: Close race condition between poll_one_napi and napi_disable") Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 42ba150fa18d..c77d12a35f92 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6196,12 +6196,13 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
pr_err_once("netif_napi_add() called with weight %d on device %s\n",
weight, dev->name);
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);