once.h (1934B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _LINUX_ONCE_H 3#define _LINUX_ONCE_H 4 5#include <linux/types.h> 6#include <linux/jump_label.h> 7 8bool __do_once_start(bool *done, unsigned long *flags); 9void __do_once_done(bool *done, struct static_key_true *once_key, 10 unsigned long *flags, struct module *mod); 11 12/* Call a function exactly once. The idea of DO_ONCE() is to perform 13 * a function call such as initialization of random seeds, etc, only 14 * once, where DO_ONCE() can live in the fast-path. After @func has 15 * been called with the passed arguments, the static key will patch 16 * out the condition into a nop. DO_ONCE() guarantees type safety of 17 * arguments! 18 * 19 * Note that the following is not equivalent ... 20 * 21 * DO_ONCE(func, arg); 22 * DO_ONCE(func, arg); 23 * 24 * ... to this version: 25 * 26 * void foo(void) 27 * { 28 * DO_ONCE(func, arg); 29 * } 30 * 31 * foo(); 32 * foo(); 33 * 34 * In case the one-time invocation could be triggered from multiple 35 * places, then a common helper function must be defined, so that only 36 * a single static key will be placed there! 37 */ 38#define DO_ONCE(func, ...) \ 39 ({ \ 40 bool ___ret = false; \ 41 static bool __section(".data.once") ___done = false; \ 42 static DEFINE_STATIC_KEY_TRUE(___once_key); \ 43 if (static_branch_unlikely(&___once_key)) { \ 44 unsigned long ___flags; \ 45 ___ret = __do_once_start(&___done, &___flags); \ 46 if (unlikely(___ret)) { \ 47 func(__VA_ARGS__); \ 48 __do_once_done(&___done, &___once_key, \ 49 &___flags, THIS_MODULE); \ 50 } \ 51 } \ 52 ___ret; \ 53 }) 54 55#define get_random_once(buf, nbytes) \ 56 DO_ONCE(get_random_bytes, (buf), (nbytes)) 57#define get_random_once_wait(buf, nbytes) \ 58 DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \ 59 60#endif /* _LINUX_ONCE_H */