Commit a18c8357 authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by Shuah Khan

selftests: vDSO: align getrandom states to cache line

This prevents false sharing, which makes a large difference on machines
with several NUMA nodes, such as on a dual socket Intel(R) Xeon(R) Gold
6338 CPU @ 2.00GHz, where the "bench-multi" test goes from 2.7s down to
1.9s. While this is just test code, it also forms the basis of how folks
will wind up implementing this in libraries, so we should implement this
simple cache alignment improvement here.
Suggested-by: default avatarFlorian Weimer <fweimer@redhat.com>
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
parent 45a8897d
...@@ -59,10 +59,12 @@ static void *vgetrandom_get_state(void) ...@@ -59,10 +59,12 @@ static void *vgetrandom_get_state(void)
size_t page_size = getpagesize(); size_t page_size = getpagesize();
size_t new_cap; size_t new_cap;
size_t alloc_size, num = sysconf(_SC_NPROCESSORS_ONLN); /* Just a decent heuristic. */ size_t alloc_size, num = sysconf(_SC_NPROCESSORS_ONLN); /* Just a decent heuristic. */
size_t state_size_aligned, cache_line_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE) ?: 1;
void *new_block, *new_states; void *new_block, *new_states;
alloc_size = (num * vgrnd.params.size_of_opaque_state + page_size - 1) & (~(page_size - 1)); state_size_aligned = (vgrnd.params.size_of_opaque_state + cache_line_size - 1) & (~(cache_line_size - 1));
num = (page_size / vgrnd.params.size_of_opaque_state) * (alloc_size / page_size); alloc_size = (num * state_size_aligned + page_size - 1) & (~(page_size - 1));
num = (page_size / state_size_aligned) * (alloc_size / page_size);
new_block = mmap(0, alloc_size, vgrnd.params.mmap_prot, vgrnd.params.mmap_flags, -1, 0); new_block = mmap(0, alloc_size, vgrnd.params.mmap_prot, vgrnd.params.mmap_flags, -1, 0);
if (new_block == MAP_FAILED) if (new_block == MAP_FAILED)
goto out; goto out;
...@@ -78,7 +80,7 @@ static void *vgetrandom_get_state(void) ...@@ -78,7 +80,7 @@ static void *vgetrandom_get_state(void)
if (((uintptr_t)new_block & (page_size - 1)) + vgrnd.params.size_of_opaque_state > page_size) if (((uintptr_t)new_block & (page_size - 1)) + vgrnd.params.size_of_opaque_state > page_size)
new_block = (void *)(((uintptr_t)new_block + page_size - 1) & (~(page_size - 1))); new_block = (void *)(((uintptr_t)new_block + page_size - 1) & (~(page_size - 1)));
vgrnd.states[i] = new_block; vgrnd.states[i] = new_block;
new_block += vgrnd.params.size_of_opaque_state; new_block += state_size_aligned;
} }
vgrnd.len = num; vgrnd.len = num;
goto success; goto success;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment