On Mon, Aug 03, 2020 at 08:12:51PM -0700, Linus Torvalds wrote: > On Mon, Aug 3, 2020 at 8:01 PM Guenter Roeck <linux@xxxxxxxxxxxx> wrote: > > > > The bisect log below applies to both the sparc and the powerpc build > > failures. > > Does the attached fix it? > > Linus > From 780c8591bce09bbdd2908b7c07b3baba883a1ce6 Mon Sep 17 00:00:00 2001 > From: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> > Date: Fri, 31 Jul 2020 07:51:14 +0200 > Subject: [PATCH] random32: move the pseudo-random 32-bit definitions to prandom.h > > The addition of percpu.h to the list of includes in random.h revealed > some circular dependencies on arm64 and possibly other platforms. This > include was added solely for the pseudo-random definitions, which have > nothing to do with the rest of the definitions in this file but are > still there for legacy reasons. > > This patch moves the pseudo-random parts to linux/prandom.h and the > percpu.h include with it, which is now guarded by _LINUX_PRANDOM_H and > protected against recursive inclusion. > > A further cleanup step would be to remove this from <linux/random.h> > entirely, and make people who use the prandom infrastructure include > just the new header file. That's a bit of a churn patch, but grepping > for "prandom_" and "next_pseudo_random32" should catch most users. > > Acked-by: Willy Tarreau <w@xxxxxx> > Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> With this patch applied on top of v5.8: Build results: total: 151 pass: 151 fail: 0 Qemu test results: total: 430 pass: 430 fail: 0 Tested-by: Guenter Roeck <linux@xxxxxxxxxxxx> Thanks, Guenter > --- > include/linux/prandom.h | 78 +++++++++++++++++++++++++++++++++++++++++ > include/linux/random.h | 66 +++------------------------------- > 2 files changed, 82 insertions(+), 62 deletions(-) > create mode 100644 include/linux/prandom.h > > diff --git a/include/linux/prandom.h b/include/linux/prandom.h > new file mode 100644 > index 000000000000..968c4287a277 > --- /dev/null > +++ b/include/linux/prandom.h > @@ -0,0 +1,78 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * include/linux/prandom.h > + * > + * Include file for the fast pseudo-random 32-bit > + * generation. > + */ > +#ifndef _LINUX_PRANDOM_H > +#define _LINUX_PRANDOM_H > + > +#include <linux/types.h> > +#include <linux/percpu.h> > + > +u32 prandom_u32(void); > +void prandom_bytes(void *buf, size_t nbytes); > +void prandom_seed(u32 seed); > +void prandom_reseed_late(void); > + > +struct rnd_state { > + __u32 s1, s2, s3, s4; > +}; > + > +DECLARE_PER_CPU(struct rnd_state, net_rand_state); > + > +u32 prandom_u32_state(struct rnd_state *state); > +void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes); > +void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state); > + > +#define prandom_init_once(pcpu_state) \ > + DO_ONCE(prandom_seed_full_state, (pcpu_state)) > + > +/** > + * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro) > + * @ep_ro: right open interval endpoint > + * > + * Returns a pseudo-random number that is in interval [0, ep_ro). Note > + * that the result depends on PRNG being well distributed in [0, ~0U] > + * u32 space. Here we use maximally equidistributed combined Tausworthe > + * generator, that is, prandom_u32(). This is useful when requesting a > + * random index of an array containing ep_ro elements, for example. > + * > + * Returns: pseudo-random number in interval [0, ep_ro) > + */ > +static inline u32 prandom_u32_max(u32 ep_ro) > +{ > + return (u32)(((u64) prandom_u32() * ep_ro) >> 32); > +} > + > +/* > + * Handle minimum values for seeds > + */ > +static inline u32 __seed(u32 x, u32 m) > +{ > + return (x < m) ? x + m : x; > +} > + > +/** > + * prandom_seed_state - set seed for prandom_u32_state(). > + * @state: pointer to state structure to receive the seed. > + * @seed: arbitrary 64-bit value to use as a seed. > + */ > +static inline void prandom_seed_state(struct rnd_state *state, u64 seed) > +{ > + u32 i = (seed >> 32) ^ (seed << 10) ^ seed; > + > + state->s1 = __seed(i, 2U); > + state->s2 = __seed(i, 8U); > + state->s3 = __seed(i, 16U); > + state->s4 = __seed(i, 128U); > +} > + > +/* Pseudo random number generator from numerical recipes. */ > +static inline u32 next_pseudo_random32(u32 seed) > +{ > + return seed * 1664525 + 1013904223; > +} > + > +#endif > diff --git a/include/linux/random.h b/include/linux/random.h > index 9ab7443bd91b..f45b8be3e3c4 100644 > --- a/include/linux/random.h > +++ b/include/linux/random.h > @@ -11,7 +11,6 @@ > #include <linux/kernel.h> > #include <linux/list.h> > #include <linux/once.h> > -#include <asm/percpu.h> > > #include <uapi/linux/random.h> > > @@ -111,63 +110,12 @@ declare_get_random_var_wait(long) > > unsigned long randomize_page(unsigned long start, unsigned long range); > > -u32 prandom_u32(void); > -void prandom_bytes(void *buf, size_t nbytes); > -void prandom_seed(u32 seed); > -void prandom_reseed_late(void); > - > -struct rnd_state { > - __u32 s1, s2, s3, s4; > -}; > - > -DECLARE_PER_CPU(struct rnd_state, net_rand_state); > - > -u32 prandom_u32_state(struct rnd_state *state); > -void prandom_bytes_state(struct rnd_state *state, void *buf, size_t nbytes); > -void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state); > - > -#define prandom_init_once(pcpu_state) \ > - DO_ONCE(prandom_seed_full_state, (pcpu_state)) > - > -/** > - * prandom_u32_max - returns a pseudo-random number in interval [0, ep_ro) > - * @ep_ro: right open interval endpoint > - * > - * Returns a pseudo-random number that is in interval [0, ep_ro). Note > - * that the result depends on PRNG being well distributed in [0, ~0U] > - * u32 space. Here we use maximally equidistributed combined Tausworthe > - * generator, that is, prandom_u32(). This is useful when requesting a > - * random index of an array containing ep_ro elements, for example. > - * > - * Returns: pseudo-random number in interval [0, ep_ro) > - */ > -static inline u32 prandom_u32_max(u32 ep_ro) > -{ > - return (u32)(((u64) prandom_u32() * ep_ro) >> 32); > -} > - > /* > - * Handle minimum values for seeds > - */ > -static inline u32 __seed(u32 x, u32 m) > -{ > - return (x < m) ? x + m : x; > -} > - > -/** > - * prandom_seed_state - set seed for prandom_u32_state(). > - * @state: pointer to state structure to receive the seed. > - * @seed: arbitrary 64-bit value to use as a seed. > + * This is designed to be standalone for just prandom > + * users, but for now we include it from <linux/random.h> > + * for legacy reasons. > */ > -static inline void prandom_seed_state(struct rnd_state *state, u64 seed) > -{ > - u32 i = (seed >> 32) ^ (seed << 10) ^ seed; > - > - state->s1 = __seed(i, 2U); > - state->s2 = __seed(i, 8U); > - state->s3 = __seed(i, 16U); > - state->s4 = __seed(i, 128U); > -} > +#include <linux/prandom.h> > > #ifdef CONFIG_ARCH_RANDOM > # include <asm/archrandom.h> > @@ -210,10 +158,4 @@ static inline bool __init arch_get_random_long_early(unsigned long *v) > } > #endif > > -/* Pseudo random number generator from numerical recipes. */ > -static inline u32 next_pseudo_random32(u32 seed) > -{ > - return seed * 1664525 + 1013904223; > -} > - > #endif /* _LINUX_RANDOM_H */ > -- > 2.28.0.4.g1bac1770cd >