diff options
author | Sultan Alsawaf <sultan@kerneltoast.com> | 2019-02-02 14:13:03 -0800 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-02-03 18:27:33 +0100 |
commit | d814238650b16d9fd990ce604feb94b6ee31f9eb (patch) | |
tree | 76e3bf51b05f48308cbb2d6c24fd605eb60b266d /src/peer.c | |
parent | queueing: more reasonable allocator function convention (diff) | |
download | wireguard-monolithic-historical-d814238650b16d9fd990ce604feb94b6ee31f9eb.tar.xz wireguard-monolithic-historical-d814238650b16d9fd990ce604feb94b6ee31f9eb.zip |
hashtables: decouple hashtable allocations from the main device allocation
The hashtable allocations are quite large, and cause the device allocation in
the net framework to stall sometimes while it tries to find a contiguous region
that can fit the device struct:
[<0000000000000000>] __switch_to+0x94/0xb8
[<0000000000000000>] __alloc_pages_nodemask+0x764/0x7e8
[<0000000000000000>] kmalloc_order+0x20/0x40
[<0000000000000000>] __kmalloc+0x144/0x1a0
[<0000000000000000>] alloc_netdev_mqs+0x5c/0x368
[<0000000000000000>] rtnl_create_link+0x48/0x180
[<0000000000000000>] rtnl_newlink+0x410/0x708
[<0000000000000000>] rtnetlink_rcv_msg+0x190/0x1f8
[<0000000000000000>] netlink_rcv_skb+0x4c/0xf8
[<0000000000000000>] rtnetlink_rcv+0x30/0x40
[<0000000000000000>] netlink_unicast+0x18c/0x208
[<0000000000000000>] netlink_sendmsg+0x19c/0x348
[<0000000000000000>] sock_sendmsg+0x3c/0x58
[<0000000000000000>] ___sys_sendmsg+0x290/0x2b0
[<0000000000000000>] __sys_sendmsg+0x58/0xa0
[<0000000000000000>] SyS_sendmsg+0x10/0x20
[<0000000000000000>] el0_svc_naked+0x34/0x38
[<0000000000000000>] 0xffffffffffffffff
To fix the allocation stalls, decouple the hashtable allocations from the device
allocation and allocate the hashtables with kvmalloc's implicit __GFP_NORETRY
so that the allocations fall back to vmalloc with little resistance.
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
Diffstat (limited to 'src/peer.c')
-rw-r--r-- | src/peer.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -64,7 +64,7 @@ struct wg_peer *wg_peer_create(struct wg_device *wg, NAPI_POLL_WEIGHT); napi_enable(&peer->napi); list_add_tail(&peer->peer_list, &wg->peer_list); - wg_pubkey_hashtable_add(&wg->peer_hashtable, peer); + wg_pubkey_hashtable_add(wg->peer_hashtable, peer); ++wg->num_peers; pr_debug("%s: Peer %llu created\n", wg->dev->name, peer->internal_id); return peer; @@ -101,7 +101,7 @@ void wg_peer_remove(struct wg_peer *peer) list_del_init(&peer->peer_list); wg_allowedips_remove_by_peer(&peer->device->peer_allowedips, peer, &peer->device->device_update_lock); - wg_pubkey_hashtable_remove(&peer->device->peer_hashtable, peer); + wg_pubkey_hashtable_remove(peer->device->peer_hashtable, peer); /* Mark as dead, so that we don't allow jumping contexts after. */ WRITE_ONCE(peer->is_dead, true); @@ -186,7 +186,7 @@ static void kref_release(struct kref *refcount) /* Remove ourself from dynamic runtime lookup structures, now that the * last reference is gone. */ - wg_index_hashtable_remove(&peer->device->index_hashtable, + wg_index_hashtable_remove(peer->device->index_hashtable, &peer->handshake.entry); /* Remove any lingering packets that didn't have a chance to be |