| 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 |  | 
|---|
| 8 | /* Helpers used from arbitrary contexts. | 
|---|
| 9 | * Hard irqs are blocked, be cautious. | 
|---|
| 10 | */ | 
|---|
| 11 | bool __do_once_start(bool *done, unsigned long *flags); | 
|---|
| 12 | void __do_once_done(bool *done, struct static_key_true *once_key, | 
|---|
| 13 | unsigned long *flags, struct module *mod); | 
|---|
| 14 |  | 
|---|
| 15 | /* Variant for process contexts only. */ | 
|---|
| 16 | bool __do_once_sleepable_start(bool *done); | 
|---|
| 17 | void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, | 
|---|
| 18 | struct module *mod); | 
|---|
| 19 |  | 
|---|
| 20 | /* Call a function exactly once. The idea of DO_ONCE() is to perform | 
|---|
| 21 | * a function call such as initialization of random seeds, etc, only | 
|---|
| 22 | * once, where DO_ONCE() can live in the fast-path. After @func has | 
|---|
| 23 | * been called with the passed arguments, the static key will patch | 
|---|
| 24 | * out the condition into a nop. DO_ONCE() guarantees type safety of | 
|---|
| 25 | * arguments! | 
|---|
| 26 | * | 
|---|
| 27 | * Note that the following is not equivalent ... | 
|---|
| 28 | * | 
|---|
| 29 | *   DO_ONCE(func, arg); | 
|---|
| 30 | *   DO_ONCE(func, arg); | 
|---|
| 31 | * | 
|---|
| 32 | * ... to this version: | 
|---|
| 33 | * | 
|---|
| 34 | *   void foo(void) | 
|---|
| 35 | *   { | 
|---|
| 36 | *     DO_ONCE(func, arg); | 
|---|
| 37 | *   } | 
|---|
| 38 | * | 
|---|
| 39 | *   foo(); | 
|---|
| 40 | *   foo(); | 
|---|
| 41 | * | 
|---|
| 42 | * In case the one-time invocation could be triggered from multiple | 
|---|
| 43 | * places, then a common helper function must be defined, so that only | 
|---|
| 44 | * a single static key will be placed there! | 
|---|
| 45 | */ | 
|---|
| 46 | #define DO_ONCE(func, ...)						     \ | 
|---|
| 47 | ({								     \ | 
|---|
| 48 | bool ___ret = false;					     \ | 
|---|
| 49 | static bool __section(".data..do_once") ___done = false;     \ | 
|---|
| 50 | static DEFINE_STATIC_KEY_TRUE(___once_key);		     \ | 
|---|
| 51 | if (static_branch_unlikely(&___once_key)) {		     \ | 
|---|
| 52 | unsigned long ___flags;				     \ | 
|---|
| 53 | ___ret = __do_once_start(&___done, &___flags);	     \ | 
|---|
| 54 | if (unlikely(___ret)) {				     \ | 
|---|
| 55 | func(__VA_ARGS__);			     \ | 
|---|
| 56 | __do_once_done(&___done, &___once_key,	     \ | 
|---|
| 57 | &___flags, THIS_MODULE);	     \ | 
|---|
| 58 | }						     \ | 
|---|
| 59 | }							     \ | 
|---|
| 60 | ___ret;							     \ | 
|---|
| 61 | }) | 
|---|
| 62 |  | 
|---|
| 63 | /* Variant of DO_ONCE() for process/sleepable contexts. */ | 
|---|
| 64 | #define DO_ONCE_SLEEPABLE(func, ...)						\ | 
|---|
| 65 | ({									\ | 
|---|
| 66 | bool ___ret = false;						\ | 
|---|
| 67 | static bool __section(".data..do_once") ___done = false;	\ | 
|---|
| 68 | static DEFINE_STATIC_KEY_TRUE(___once_key);			\ | 
|---|
| 69 | if (static_branch_unlikely(&___once_key)) {			\ | 
|---|
| 70 | ___ret = __do_once_sleepable_start(&___done);		\ | 
|---|
| 71 | if (unlikely(___ret)) {					\ | 
|---|
| 72 | func(__VA_ARGS__);				\ | 
|---|
| 73 | __do_once_sleepable_done(&___done, &___once_key,\ | 
|---|
| 74 | THIS_MODULE);		\ | 
|---|
| 75 | }							\ | 
|---|
| 76 | }								\ | 
|---|
| 77 | ___ret;								\ | 
|---|
| 78 | }) | 
|---|
| 79 |  | 
|---|
| 80 | #define get_random_once(buf, nbytes)					     \ | 
|---|
| 81 | DO_ONCE(get_random_bytes, (buf), (nbytes)) | 
|---|
| 82 |  | 
|---|
| 83 | #define get_random_sleepable_once(buf, nbytes)				     \ | 
|---|
| 84 | DO_ONCE_SLEEPABLE(get_random_bytes, (buf), (nbytes)) | 
|---|
| 85 |  | 
|---|
| 86 | #endif /* _LINUX_ONCE_H */ | 
|---|
| 87 |  | 
|---|