From 619c99de4be8f0618e7c4cb65039de2aa1e2536c Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Tue, 27 Jun 2023 19:45:40 -0400 Subject: get_random_u32_below() Signed-off-by: Kent Overstreet --- include/linux/random.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/linux/random.h b/include/linux/random.h index ea101d53..3203d13c 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef SYS_getrandom static inline int getrandom(void *buf, size_t buflen, unsigned int flags) @@ -40,7 +41,30 @@ static inline type get_random_##type(void) \ get_random_type(int); get_random_type(long); +get_random_type(u8); +get_random_type(u16); get_random_type(u32); get_random_type(u64); +static inline u32 get_random_u32_below(u32 ceil) +{ + if (ceil <= 1) + return 0; + for (;;) { + if (ceil <= 1U << 8) { + u32 mult = ceil * get_random_u8(); + if (likely(is_power_of_2(ceil) || (u8)mult >= (1U << 8) % ceil)) + return mult >> 8; + } else if (ceil <= 1U << 16) { + u32 mult = ceil * get_random_u16(); + if (likely(is_power_of_2(ceil) || (u16)mult >= (1U << 16) % ceil)) + return mult >> 16; + } else { + u64 mult = (u64)ceil * get_random_u32(); + if (likely(is_power_of_2(ceil) || (u32)mult >= -ceil % ceil)) + return mult >> 32; + } + } +} + #endif /* _LINUX_RANDOM_H */ -- cgit v1.2.3