summaryrefslogtreecommitdiffhomepage
path: root/src/noise.c
diff options
context:
space:
mode:
authorSultan Alsawaf <sultan@kerneltoast.com>2019-02-02 14:13:03 -0800
committerJason A. Donenfeld <Jason@zx2c4.com>2019-02-03 18:27:33 +0100
commit75f476905a1bcd013c8bee07282fd7fb1dca738e (patch)
tree987fcd2a85f2afe63f0da292826646192bfb8eec /src/noise.c
parentd063dfb80911854ed273f6374b02f339a86462ba (diff)
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> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/noise.c')
-rw-r--r--src/noise.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/src/noise.c b/src/noise.c
index 1a85723..e1d4519 100644
--- a/src/noise.c
+++ b/src/noise.c
@@ -93,13 +93,13 @@ static void handshake_zero(struct noise_handshake *handshake)
void wg_noise_handshake_clear(struct noise_handshake *handshake)
{
wg_index_hashtable_remove(
- &handshake->entry.peer->device->index_hashtable,
+ handshake->entry.peer->device->index_hashtable,
&handshake->entry);
down_write(&handshake->lock);
handshake_zero(handshake);
up_write(&handshake->lock);
wg_index_hashtable_remove(
- &handshake->entry.peer->device->index_hashtable,
+ handshake->entry.peer->device->index_hashtable,
&handshake->entry);
}
@@ -130,7 +130,7 @@ static void keypair_free_kref(struct kref *kref)
keypair->entry.peer->device->dev->name,
keypair->internal_id,
keypair->entry.peer->internal_id);
- wg_index_hashtable_remove(&keypair->entry.peer->device->index_hashtable,
+ wg_index_hashtable_remove(keypair->entry.peer->device->index_hashtable,
&keypair->entry);
call_rcu_bh(&keypair->rcu, keypair_free_rcu);
}
@@ -141,7 +141,7 @@ void wg_noise_keypair_put(struct noise_keypair *keypair, bool unreference_now)
return;
if (unlikely(unreference_now))
wg_index_hashtable_remove(
- &keypair->entry.peer->device->index_hashtable,
+ keypair->entry.peer->device->index_hashtable,
&keypair->entry);
kref_put(&keypair->refcount, keypair_free_kref);
}
@@ -520,7 +520,7 @@ wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
NOISE_TIMESTAMP_LEN, key, handshake->hash);
dst->sender_index = wg_index_hashtable_insert(
- &handshake->entry.peer->device->index_hashtable,
+ handshake->entry.peer->device->index_hashtable,
&handshake->entry);
handshake->state = HANDSHAKE_CREATED_INITIATION;
@@ -566,7 +566,7 @@ wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
goto out;
/* Lookup which peer we're actually talking to */
- peer = wg_pubkey_hashtable_lookup(&wg->peer_hashtable, s);
+ peer = wg_pubkey_hashtable_lookup(wg->peer_hashtable, s);
if (!peer)
goto out;
handshake = &peer->handshake;
@@ -660,7 +660,7 @@ bool wg_noise_handshake_create_response(struct message_handshake_response *dst,
message_encrypt(dst->encrypted_nothing, NULL, 0, key, handshake->hash);
dst->sender_index = wg_index_hashtable_insert(
- &handshake->entry.peer->device->index_hashtable,
+ handshake->entry.peer->device->index_hashtable,
&handshake->entry);
handshake->state = HANDSHAKE_CREATED_RESPONSE;
@@ -693,7 +693,7 @@ wg_noise_handshake_consume_response(struct message_handshake_response *src,
goto out;
handshake = (struct noise_handshake *)wg_index_hashtable_lookup(
- &wg->index_hashtable, INDEX_HASHTABLE_HANDSHAKE,
+ wg->index_hashtable, INDEX_HASHTABLE_HANDSHAKE,
src->receiver_index, &peer);
if (unlikely(!handshake))
goto out;
@@ -793,7 +793,7 @@ bool wg_noise_handshake_begin_session(struct noise_handshake *handshake,
new_keypair->internal_id,
handshake->entry.peer->internal_id);
ret = wg_index_hashtable_replace(
- &handshake->entry.peer->device->index_hashtable,
+ handshake->entry.peer->device->index_hashtable,
&handshake->entry, &new_keypair->entry);
} else {
kzfree(new_keypair);