[Intel-gfx] [PATCH 06/34] drm: Add a simple linear congruent generator PRNG

David Herrmann dh.herrmann at gmail.com
Tue Dec 13 15:16:41 UTC 2016


Hey Chris

On Mon, Dec 12, 2016 at 12:53 PM, Chris Wilson <chris at chris-wilson.co.uk> wrote:
> For testing, we want a reproducible PRNG, a plain linear congruent
> generator is suitable for our very limited selftests.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/Kconfig        |  5 +++++
>  drivers/gpu/drm/Makefile       |  1 +
>  drivers/gpu/drm/lib/drm_rand.c | 51 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/lib/drm_rand.h |  9 ++++++++
>  4 files changed, 66 insertions(+)
>  create mode 100644 drivers/gpu/drm/lib/drm_rand.c
>  create mode 100644 drivers/gpu/drm/lib/drm_rand.h
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index fd341ab69c46..04d1d0a32c5c 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -48,10 +48,15 @@ config DRM_DEBUG_MM
>
>           If in doubt, say "N".
>
> +config DRM_LIB_RAND
> +       bool
> +       default n
> +
>  config DRM_DEBUG_MM_SELFTEST
>         tristate "kselftests for DRM range manager (struct drm_mm)"
>         depends on DRM
>         depends on DEBUG_KERNEL
> +       select DRM_LIB_RAND
>         default n
>         help
>           This option provides a kernel module that can be used to test
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index c8aed3688b20..363eb1a23151 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -18,6 +18,7 @@ drm-y       :=        drm_auth.o drm_bufs.o drm_cache.o \
>                 drm_plane.o drm_color_mgmt.o drm_print.o \
>                 drm_dumb_buffers.o drm_mode_config.o
>
> +drm-$(CONFIG_DRM_LIB_RAND) += lib/drm_rand.o
>  obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/test-drm_mm.o
>
>  drm-$(CONFIG_COMPAT) += drm_ioc32.o
> diff --git a/drivers/gpu/drm/lib/drm_rand.c b/drivers/gpu/drm/lib/drm_rand.c
> new file mode 100644
> index 000000000000..f203c47bb525
> --- /dev/null
> +++ b/drivers/gpu/drm/lib/drm_rand.c
> @@ -0,0 +1,51 @@
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#include "drm_rand.h"
> +
> +u32 drm_lcg_random(u32 *state)
> +{
> +       u32 s = *state;
> +
> +#define rol(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
> +       s = (s ^ rol(s, 5) ^ rol(s, 24)) + 0x37798849;
> +#undef rol

#include <linux/bitops.h>

static inline __u32 rol32(__u32 word, unsigned int shift);

Allows you to get rid of "rol()" and the temporary "u32 s;".

> +
> +       *state = s;
> +       return s;
> +}
> +EXPORT_SYMBOL(drm_lcg_random);
> +
> +int *drm_random_reorder(int *order, int count, u32 *state)
> +{
> +       int n;
> +
> +       for (n = count-1; n > 1; n--) {
> +               int r = drm_lcg_random(state) % (n + 1);
> +               if (r != n) {

Why not drop that condition? No harm in doing the self-swap, is there?
Makes the code shorter.

> +                       int tmp = order[n];
> +                       order[n] = order[r];
> +                       order[r] = tmp;

swap() in <linux/kernel.h>

> +               }
> +       }

Is there a specific reason to do it that way? How about:

for (i = 0; i < count; ++i)
        swap(order[i], order[drm_lcg_random(state) % count]);

Much simpler and I cannot see why it wouldn't work.

> +
> +       return order;

You sure that return value serves any purpose? Is that convenience so
you can use the function in a combined statement?

> +}
> +EXPORT_SYMBOL(drm_random_reorder);
> +
> +int *drm_random_order(int count, u32 *state)
> +{
> +       int *order;
> +       int n;
> +
> +       order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY);
> +       if (!order)
> +               return order;
> +
> +       for (n = 0; n < count; n++)
> +               order[n] = n;
> +
> +       return drm_random_reorder(order, count, state);

Why "signed int"? We very often use "size_t" to count things. By
making the order signed you just keep running into "comparing signed
vs unsigned" warnings, don't you?

> +}
> +EXPORT_SYMBOL(drm_random_order);
> diff --git a/drivers/gpu/drm/lib/drm_rand.h b/drivers/gpu/drm/lib/drm_rand.h
> new file mode 100644
> index 000000000000..a3f22d115aac
> --- /dev/null
> +++ b/drivers/gpu/drm/lib/drm_rand.h
> @@ -0,0 +1,9 @@
> +#ifndef __DRM_RAND_H__
> +#define __DRM_RAND_H
> +
> +u32 drm_lcg_random(u32 *state);
> +
> +int *drm_random_reorder(int *order, int count, u32 *state);
> +int *drm_random_order(int count, u32 *state);
> +
> +#endif /* __DRM_RAND_H__ */

"random.h". Why the abbreviation?

Looks good to me. Only nitpicks, so feel free to ignore.

Thanks
David

> --
> 2.11.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the Intel-gfx mailing list