once.h 2.7 KB

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