aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-5.4/080-wireguard-0130-wireguard-use-synchronize_net-rather-than-synchroniz.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-5.4/080-wireguard-0130-wireguard-use-synchronize_net-rather-than-synchroniz.patch')
-rw-r--r--target/linux/generic/backport-5.4/080-wireguard-0130-wireguard-use-synchronize_net-rather-than-synchroniz.patch66
1 files changed, 66 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.4/080-wireguard-0130-wireguard-use-synchronize_net-rather-than-synchroniz.patch b/target/linux/generic/backport-5.4/080-wireguard-0130-wireguard-use-synchronize_net-rather-than-synchroniz.patch
new file mode 100644
index 0000000000..309fe36198
--- /dev/null
+++ b/target/linux/generic/backport-5.4/080-wireguard-0130-wireguard-use-synchronize_net-rather-than-synchroniz.patch
@@ -0,0 +1,66 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Fri, 4 Jun 2021 17:17:33 +0200
+Subject: [PATCH] wireguard: use synchronize_net rather than synchronize_rcu
+
+commit 24b70eeeb4f46c09487f8155239ebfb1f875774a upstream.
+
+Many of the synchronization points are sometimes called under the rtnl
+lock, which means we should use synchronize_net rather than
+synchronize_rcu. Under the hood, this expands to using the expedited
+flavor of function in the event that rtnl is held, in order to not stall
+other concurrent changes.
+
+This fixes some very, very long delays when removing multiple peers at
+once, which would cause some operations to take several minutes.
+
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+---
+ drivers/net/wireguard/peer.c | 6 +++---
+ drivers/net/wireguard/socket.c | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireguard/peer.c
++++ b/drivers/net/wireguard/peer.c
+@@ -88,7 +88,7 @@ static void peer_make_dead(struct wg_pee
+ /* Mark as dead, so that we don't allow jumping contexts after. */
+ WRITE_ONCE(peer->is_dead, true);
+
+- /* The caller must now synchronize_rcu() for this to take effect. */
++ /* The caller must now synchronize_net() for this to take effect. */
+ }
+
+ static void peer_remove_after_dead(struct wg_peer *peer)
+@@ -160,7 +160,7 @@ void wg_peer_remove(struct wg_peer *peer
+ lockdep_assert_held(&peer->device->device_update_lock);
+
+ peer_make_dead(peer);
+- synchronize_rcu();
++ synchronize_net();
+ peer_remove_after_dead(peer);
+ }
+
+@@ -178,7 +178,7 @@ void wg_peer_remove_all(struct wg_device
+ peer_make_dead(peer);
+ list_add_tail(&peer->peer_list, &dead_peers);
+ }
+- synchronize_rcu();
++ synchronize_net();
+ list_for_each_entry_safe(peer, temp, &dead_peers, peer_list)
+ peer_remove_after_dead(peer);
+ }
+--- a/drivers/net/wireguard/socket.c
++++ b/drivers/net/wireguard/socket.c
+@@ -430,7 +430,7 @@ void wg_socket_reinit(struct wg_device *
+ if (new4)
+ wg->incoming_port = ntohs(inet_sk(new4)->inet_sport);
+ mutex_unlock(&wg->socket_update_lock);
+- synchronize_rcu();
++ synchronize_net();
+ sock_free(old4);
+ sock_free(old6);
+ }