aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2021-06-01 23:19:48 +0200
committerFelix Fietkau <nbd@nbd.name>2021-06-01 23:20:07 +0200
commit9bda91d805b02ba3d3a6481bee31f4569e3c2324 (patch)
tree320d74e65ba1b5dadf6817579ff6bb65733f25c8 /target/linux/generic
parent507257778c733749816a8ca611f072d07916a918 (diff)
downloadupstream-9bda91d805b02ba3d3a6481bee31f4569e3c2324.tar.gz
upstream-9bda91d805b02ba3d3a6481bee31f4569e3c2324.tar.bz2
upstream-9bda91d805b02ba3d3a6481bee31f4569e3c2324.zip
kernel: backport fix for hang on napi_disable with threaded NAPI
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/generic')
-rw-r--r--target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch53
-rw-r--r--target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch8
2 files changed, 57 insertions, 4 deletions
diff --git a/target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch b/target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch
new file mode 100644
index 0000000000..4b83641291
--- /dev/null
+++ b/target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch
@@ -0,0 +1,53 @@
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Fri, 9 Apr 2021 17:24:17 +0200
+Subject: [PATCH] net: fix hangup on napi_disable for threaded napi
+
+napi_disable() is subject to an hangup, when the threaded
+mode is enabled and the napi is under heavy traffic.
+
+If the relevant napi has been scheduled and the napi_disable()
+kicks in before the next napi_threaded_wait() completes - so
+that the latter quits due to the napi_disable_pending() condition,
+the existing code leaves the NAPI_STATE_SCHED bit set and the
+napi_disable() loop waiting for such bit will hang.
+
+This patch addresses the issue by dropping the NAPI_STATE_DISABLE
+bit test in napi_thread_wait(). The later napi_threaded_poll()
+iteration will take care of clearing the NAPI_STATE_SCHED.
+
+This also addresses a related problem reported by Jakub:
+before this patch a napi_disable()/napi_enable() pair killed
+the napi thread, effectively disabling the threaded mode.
+On the patched kernel napi_disable() simply stops scheduling
+the relevant thread.
+
+v1 -> v2:
+ - let the main napi_thread_poll() loop clear the SCHED bit
+
+Reported-by: Jakub Kicinski <kuba@kernel.org>
+Fixes: 29863d41bb6e ("net: implement threaded-able napi poll loop support")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/883923fa22745a9589e8610962b7dc59df09fb1f.1617981844.git.pabeni@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -6951,7 +6951,7 @@ static int napi_thread_wait(struct napi_
+
+ set_current_state(TASK_INTERRUPTIBLE);
+
+- while (!kthread_should_stop() && !napi_disable_pending(napi)) {
++ while (!kthread_should_stop()) {
+ /* Testing SCHED_THREADED bit here to make sure the current
+ * kthread owns this napi and could poll on this napi.
+ * Testing SCHED bit is not enough because SCHED bit might be
+@@ -6969,6 +6969,7 @@ static int napi_thread_wait(struct napi_
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+ __set_current_state(TASK_RUNNING);
++
+ return -1;
+ }
+
diff --git a/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
index 8b5ec9c305..3b485e3cc9 100644
--- a/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
+++ b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
@@ -42,7 +42,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (netif_elide_gro(skb->dev))
goto normal;
-@@ -7986,6 +7989,48 @@ static void __netdev_adjacent_dev_unlink
+@@ -7987,6 +7990,48 @@ static void __netdev_adjacent_dev_unlink
&upper_dev->adj_list.lower);
}
@@ -91,7 +91,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static int __netdev_upper_dev_link(struct net_device *dev,
struct net_device *upper_dev, bool master,
void *upper_priv, void *upper_info,
-@@ -8037,6 +8082,7 @@ static int __netdev_upper_dev_link(struc
+@@ -8038,6 +8083,7 @@ static int __netdev_upper_dev_link(struc
if (ret)
return ret;
@@ -99,7 +99,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
&changeupper_info.info);
ret = notifier_to_errno(ret);
-@@ -8133,6 +8179,7 @@ static void __netdev_upper_dev_unlink(st
+@@ -8134,6 +8180,7 @@ static void __netdev_upper_dev_unlink(st
__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
@@ -107,7 +107,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
&changeupper_info.info);
-@@ -8919,6 +8966,7 @@ int dev_set_mac_address(struct net_devic
+@@ -8920,6 +8967,7 @@ int dev_set_mac_address(struct net_devic
if (err)
return err;
dev->addr_assign_type = NET_ADDR_SET;