Factor out the guts of __get_random_u32_below into a new helper, so that callers with their own prng state can reuse this code.
Signed-off-by: Christoph Hellwig <[email protected]> --- drivers/char/random.c | 26 +++++++++++++++----------- include/linux/random.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 7ff4d29911fd..23b5addf02fb 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -544,18 +544,16 @@ DEFINE_BATCHED_ENTROPY(u16) DEFINE_BATCHED_ENTROPY(u32) DEFINE_BATCHED_ENTROPY(u64) -u32 __get_random_u32_below(u32 ceil) +/* + * This is the slow path for variable ceil. It is still fast, most of the time, + * by doing traditional reciprocal multiplication and opportunistically + * comparing the lower half to ceil itself, before falling back to computing a + * larger bound, and then rejecting samples whose lower half would indicate a + * range indivisible by ceil. The use of `-ceil % ceil` is analogous to `2^32 % + * ceil`, but is computable in 32-bits. + */ +u32 __limit_random_u32_below(u32 ceil, u32 rand) { - /* - * This is the slow path for variable ceil. It is still fast, most of - * the time, by doing traditional reciprocal multiplication and - * opportunistically comparing the lower half to ceil itself, before - * falling back to computing a larger bound, and then rejecting samples - * whose lower half would indicate a range indivisible by ceil. The use - * of `-ceil % ceil` is analogous to `2^32 % ceil`, but is computable - * in 32-bits. - */ - u32 rand = get_random_u32(); u64 mult; /* @@ -577,6 +575,12 @@ u32 __get_random_u32_below(u32 ceil) } return mult >> 32; } +EXPORT_SYMBOL_GPL(__limit_random_u32_below); + +u32 __get_random_u32_below(u32 ceil) +{ + return __limit_random_u32_below(ceil, get_random_u32()); +} EXPORT_SYMBOL(__get_random_u32_below); #ifdef CONFIG_SMP diff --git a/include/linux/random.h b/include/linux/random.h index 8a8064dc3970..54401dd53f68 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -50,6 +50,7 @@ static inline unsigned long get_random_long(void) #endif } +u32 __limit_random_u32_below(u32 ceil, u32 rand); u32 __get_random_u32_below(u32 ceil); /* -- 2.47.3
