hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/include/linux/once.h
....@@ -5,9 +5,17 @@
55 #include <linux/types.h>
66 #include <linux/jump_label.h>
77
8
+/* Helpers used from arbitrary contexts.
9
+ * Hard irqs are blocked, be cautious.
10
+ */
811 bool __do_once_start(bool *done, unsigned long *flags);
912 void __do_once_done(bool *done, struct static_key_true *once_key,
10
- unsigned long *flags, struct module *mod);
13
+ unsigned long *flags);
14
+
15
+/* Variant for process contexts only. */
16
+bool __do_once_slow_start(bool *done);
17
+void __do_once_slow_done(bool *done, struct static_key_true *once_key,
18
+ struct module *mod);
1119
1220 /* Call a function exactly once. The idea of DO_ONCE() is to perform
1321 * a function call such as initialization of random seeds, etc, only
....@@ -46,7 +54,24 @@
4654 if (unlikely(___ret)) { \
4755 func(__VA_ARGS__); \
4856 __do_once_done(&___done, &___once_key, \
49
- &___flags, THIS_MODULE); \
57
+ &___flags); \
58
+ } \
59
+ } \
60
+ ___ret; \
61
+ })
62
+
63
+/* Variant of DO_ONCE() for process/sleepable contexts. */
64
+#define DO_ONCE_SLOW(func, ...) \
65
+ ({ \
66
+ bool ___ret = false; \
67
+ static bool __section(".data.once") ___done = false; \
68
+ static DEFINE_STATIC_KEY_TRUE(___once_key); \
69
+ if (static_branch_unlikely(&___once_key)) { \
70
+ ___ret = __do_once_slow_start(&___done); \
71
+ if (unlikely(___ret)) { \
72
+ func(__VA_ARGS__); \
73
+ __do_once_slow_done(&___done, &___once_key, \
74
+ THIS_MODULE); \
5075 } \
5176 } \
5277 ___ret; \
....@@ -57,4 +82,7 @@
5782 #define get_random_once_wait(buf, nbytes) \
5883 DO_ONCE(get_random_bytes_wait, (buf), (nbytes)) \
5984
85
+#define get_random_slow_once(buf, nbytes) \
86
+ DO_ONCE_SLOW(get_random_bytes, (buf), (nbytes))
87
+
6088 #endif /* _LINUX_ONCE_H */