aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/net.h
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2014-05-11 16:59:30 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-14 00:37:34 -0400
commit3d4405226d27b3a215e4d03cfa51f536244e5de7 (patch)
treec7b5f491bf08622f82d7abb0591a8ac4c038d4b4 /include/linux/net.h
parent773cd38f40b8834be991dbfed36683acc1dd41ee (diff)
net: avoid dependency of net_get_random_once on nop patching
net_get_random_once depends on the static keys infrastructure to patch up the branch to the slow path during boot. This was realized by abusing the static keys api and defining a new initializer to not enable the call site while still indicating that the branch point should get patched up. This was needed to have the fast path considered likely by gcc. The static key initialization during boot up normally walks through all the registered keys and either patches in ideal nops or enables the jump site but omitted that step on x86 if ideal nops where already placed at static_key branch points. Thus net_get_random_once branches not always became active. This patch switches net_get_random_once to the ordinary static_key api and thus places the kernel fast path in the - by gcc considered - unlikely path. Microbenchmarks on Intel and AMD x86-64 showed that the unlikely path actually beats the likely path in terms of cycle cost and that different nop patterns did not make much difference, thus this switch should not be noticeable. Fixes: a48e42920ff38b ("net: introduce new macro net_get_random_once") Reported-by: Tuomas Räsänen <tuomasjjrasanen@tjjr.fi> Cc: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/net.h')
-rw-r--r--include/linux/net.h15
1 files changed, 4 insertions, 11 deletions
diff --git a/include/linux/net.h b/include/linux/net.h
index 94734a6259a4..17d83393afcc 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -248,24 +248,17 @@ do { \
248bool __net_get_random_once(void *buf, int nbytes, bool *done, 248bool __net_get_random_once(void *buf, int nbytes, bool *done,
249 struct static_key *done_key); 249 struct static_key *done_key);
250 250
251#ifdef HAVE_JUMP_LABEL
252#define ___NET_RANDOM_STATIC_KEY_INIT ((struct static_key) \
253 { .enabled = ATOMIC_INIT(0), .entries = (void *)1 })
254#else /* !HAVE_JUMP_LABEL */
255#define ___NET_RANDOM_STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
256#endif /* HAVE_JUMP_LABEL */
257
258#define net_get_random_once(buf, nbytes) \ 251#define net_get_random_once(buf, nbytes) \
259 ({ \ 252 ({ \
260 bool ___ret = false; \ 253 bool ___ret = false; \
261 static bool ___done = false; \ 254 static bool ___done = false; \
262 static struct static_key ___done_key = \ 255 static struct static_key ___once_key = \
263 ___NET_RANDOM_STATIC_KEY_INIT; \ 256 STATIC_KEY_INIT_TRUE; \
264 if (!static_key_true(&___done_key)) \ 257 if (static_key_true(&___once_key)) \
265 ___ret = __net_get_random_once(buf, \ 258 ___ret = __net_get_random_once(buf, \
266 nbytes, \ 259 nbytes, \
267 &___done, \ 260 &___done, \
268 &___done_key); \ 261 &___once_key); \
269 ___ret; \ 262 ___ret; \
270 }) 263 })
271 264