Re: [PATCH 5.7 000/120] 5.7.13-rc1 review
From: Guenter Roeck
Date: Tue Aug 04 2020 - 01:59:03 EST
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
>