aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-5.4/080-wireguard-0134-wireguard-allowedips-allocate-nodes-in-kmem_cache.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-5.4/080-wireguard-0134-wireguard-allowedips-allocate-nodes-in-kmem_cache.patch')
-rw-r--r--target/linux/generic/backport-5.4/080-wireguard-0134-wireguard-allowedips-allocate-nodes-in-kmem_cache.patch173
1 files changed, 0 insertions, 173 deletions
diff --git a/target/linux/generic/backport-5.4/080-wireguard-0134-wireguard-allowedips-allocate-nodes-in-kmem_cache.patch b/target/linux/generic/backport-5.4/080-wireguard-0134-wireguard-allowedips-allocate-nodes-in-kmem_cache.patch
deleted file mode 100644
index 65b31b05f5..0000000000
--- a/target/linux/generic/backport-5.4/080-wireguard-0134-wireguard-allowedips-allocate-nodes-in-kmem_cache.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Fri, 4 Jun 2021 17:17:37 +0200
-Subject: [PATCH] wireguard: allowedips: allocate nodes in kmem_cache
-
-commit dc680de28ca849dfe589dc15ac56d22505f0ef11 upstream.
-
-The previous commit moved from O(n) to O(1) for removal, but in the
-process introduced an additional pointer member to a struct that
-increased the size from 60 to 68 bytes, putting nodes in the 128-byte
-slab. With deployed systems having as many as 2 million nodes, this
-represents a significant doubling in memory usage (128 MiB -> 256 MiB).
-Fix this by using our own kmem_cache, that's sized exactly right. This
-also makes wireguard's memory usage more transparent in tools like
-slabtop and /proc/slabinfo.
-
-Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
-Suggested-by: Arnd Bergmann <arnd@arndb.de>
-Suggested-by: Matthew Wilcox <willy@infradead.org>
-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/allowedips.c | 31 ++++++++++++++++++++++++------
- drivers/net/wireguard/allowedips.h | 5 ++++-
- drivers/net/wireguard/main.c | 10 +++++++++-
- 3 files changed, 38 insertions(+), 8 deletions(-)
-
---- a/drivers/net/wireguard/allowedips.c
-+++ b/drivers/net/wireguard/allowedips.c
-@@ -6,6 +6,8 @@
- #include "allowedips.h"
- #include "peer.h"
-
-+static struct kmem_cache *node_cache;
-+
- static void swap_endian(u8 *dst, const u8 *src, u8 bits)
- {
- if (bits == 32) {
-@@ -40,6 +42,11 @@ static void push_rcu(struct allowedips_n
- }
- }
-
-+static void node_free_rcu(struct rcu_head *rcu)
-+{
-+ kmem_cache_free(node_cache, container_of(rcu, struct allowedips_node, rcu));
-+}
-+
- static void root_free_rcu(struct rcu_head *rcu)
- {
- struct allowedips_node *node, *stack[128] = {
-@@ -49,7 +56,7 @@ static void root_free_rcu(struct rcu_hea
- while (len > 0 && (node = stack[--len])) {
- push_rcu(stack, node->bit[0], &len);
- push_rcu(stack, node->bit[1], &len);
-- kfree(node);
-+ kmem_cache_free(node_cache, node);
- }
- }
-
-@@ -164,7 +171,7 @@ static int add(struct allowedips_node __
- return -EINVAL;
-
- if (!rcu_access_pointer(*trie)) {
-- node = kzalloc(sizeof(*node), GFP_KERNEL);
-+ node = kmem_cache_zalloc(node_cache, GFP_KERNEL);
- if (unlikely(!node))
- return -ENOMEM;
- RCU_INIT_POINTER(node->peer, peer);
-@@ -180,7 +187,7 @@ static int add(struct allowedips_node __
- return 0;
- }
-
-- newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);
-+ newnode = kmem_cache_zalloc(node_cache, GFP_KERNEL);
- if (unlikely(!newnode))
- return -ENOMEM;
- RCU_INIT_POINTER(newnode->peer, peer);
-@@ -213,10 +220,10 @@ static int add(struct allowedips_node __
- return 0;
- }
-
-- node = kzalloc(sizeof(*node), GFP_KERNEL);
-+ node = kmem_cache_zalloc(node_cache, GFP_KERNEL);
- if (unlikely(!node)) {
- list_del(&newnode->peer_list);
-- kfree(newnode);
-+ kmem_cache_free(node_cache, newnode);
- return -ENOMEM;
- }
- INIT_LIST_HEAD(&node->peer_list);
-@@ -306,7 +313,7 @@ void wg_allowedips_remove_by_peer(struct
- if (child)
- child->parent_bit = node->parent_bit;
- *rcu_dereference_protected(node->parent_bit, lockdep_is_held(lock)) = child;
-- kfree_rcu(node, rcu);
-+ call_rcu(&node->rcu, node_free_rcu);
-
- /* TODO: Note that we currently don't walk up and down in order to
- * free any potential filler nodes. This means that this function
-@@ -350,4 +357,16 @@ struct wg_peer *wg_allowedips_lookup_src
- return NULL;
- }
-
-+int __init wg_allowedips_slab_init(void)
-+{
-+ node_cache = KMEM_CACHE(allowedips_node, 0);
-+ return node_cache ? 0 : -ENOMEM;
-+}
-+
-+void wg_allowedips_slab_uninit(void)
-+{
-+ rcu_barrier();
-+ kmem_cache_destroy(node_cache);
-+}
-+
- #include "selftest/allowedips.c"
---- a/drivers/net/wireguard/allowedips.h
-+++ b/drivers/net/wireguard/allowedips.h
-@@ -19,7 +19,7 @@ struct allowedips_node {
- u8 bits[16] __aligned(__alignof(u64));
-
- /* Keep rarely used members at bottom to be beyond cache line. */
-- struct allowedips_node *__rcu *parent_bit; /* XXX: this puts us at 68->128 bytes instead of 60->64 bytes!! */
-+ struct allowedips_node *__rcu *parent_bit;
- union {
- struct list_head peer_list;
- struct rcu_head rcu;
-@@ -53,4 +53,7 @@ struct wg_peer *wg_allowedips_lookup_src
- bool wg_allowedips_selftest(void);
- #endif
-
-+int wg_allowedips_slab_init(void);
-+void wg_allowedips_slab_uninit(void);
-+
- #endif /* _WG_ALLOWEDIPS_H */
---- a/drivers/net/wireguard/main.c
-+++ b/drivers/net/wireguard/main.c
-@@ -21,10 +21,15 @@ static int __init mod_init(void)
- {
- int ret;
-
-+ ret = wg_allowedips_slab_init();
-+ if (ret < 0)
-+ goto err_allowedips;
-+
- #ifdef DEBUG
-+ ret = -ENOTRECOVERABLE;
- if (!wg_allowedips_selftest() || !wg_packet_counter_selftest() ||
- !wg_ratelimiter_selftest())
-- return -ENOTRECOVERABLE;
-+ goto err_peer;
- #endif
- wg_noise_init();
-
-@@ -50,6 +55,8 @@ err_netlink:
- err_device:
- wg_peer_uninit();
- err_peer:
-+ wg_allowedips_slab_uninit();
-+err_allowedips:
- return ret;
- }
-
-@@ -58,6 +65,7 @@ static void __exit mod_exit(void)
- wg_genetlink_uninit();
- wg_device_uninit();
- wg_peer_uninit();
-+ wg_allowedips_slab_uninit();
- }
-
- module_init(mod_init);