When testing, we want a random but yet reproducible order in which to process elements. Here we create an array which is a random (using the Tausworthe PRNG) permutation of the order in which to execute. v2: Tidier code by David Herrmann Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: David Herrmann <dh.herrmann@xxxxxxxxx> --- drivers/gpu/drm/Kconfig | 6 ++++++ drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/lib/drm_random.c | 41 ++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/lib/drm_random.h | 21 ++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 drivers/gpu/drm/lib/drm_random.c create mode 100644 drivers/gpu/drm/lib/drm_random.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index d1363d21d3d1..2e6ae95459e4 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -52,6 +52,7 @@ config DRM_DEBUG_MM_SELFTEST tristate "kselftests for DRM range manager (struct drm_mm)" depends on DRM depends on DEBUG_KERNEL + select DRM_LIB_RANDOM default n help This option provides a kernel module that can be used to test @@ -334,3 +335,8 @@ config DRM_SAVAGE chipset. If M is selected the module will be called savage. endif # DRM_LEGACY + +config DRM_LIB_RANDOM + bool + default n + diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index c8aed3688b20..0fa16275fdae 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_RANDOM) += lib/drm_random.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_random.c b/drivers/gpu/drm/lib/drm_random.c new file mode 100644 index 000000000000..507e72721b6f --- /dev/null +++ b/drivers/gpu/drm/lib/drm_random.c @@ -0,0 +1,41 @@ +#include <linux/bitops.h> +#include <linux/kernel.h> +#include <linux/random.h> +#include <linux/slab.h> +#include <linux/types.h> + +#include "drm_random.h" + +static inline u32 prandom_u32_max_state(u32 ep_ro, struct rnd_state *state) +{ + return upper_32_bits((u64)prandom_u32_state(state) * ep_ro); +} + +void drm_random_reorder(unsigned int *order, unsigned int count, + struct rnd_state *state) +{ + unsigned int i, j; + + for (i = 0; i < count; ++i) { + BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32)); + j = prandom_u32_max_state(count, state); + swap(order[i], order[j]); + } +} +EXPORT_SYMBOL(drm_random_reorder); + +unsigned int *drm_random_order(unsigned int count, struct rnd_state *state) +{ + unsigned int *order, i; + + order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY); + if (!order) + return order; + + for (i = 0; i < count; i++) + order[i] = i; + + drm_random_reorder(order, count, state); + return order; +} +EXPORT_SYMBOL(drm_random_order); diff --git a/drivers/gpu/drm/lib/drm_random.h b/drivers/gpu/drm/lib/drm_random.h new file mode 100644 index 000000000000..931c8f4a261d --- /dev/null +++ b/drivers/gpu/drm/lib/drm_random.h @@ -0,0 +1,21 @@ +#ifndef __DRM_RANDOM_H__ +#define __DRM_RANDOM_H + +#include <linux/random.h> + +#define RND_STATE_INITIALIZER(seed__) ({ \ + struct rnd_state state__; \ + prandom_seed_state(&state__, (seed__)); \ + state__; \ +}) + +#define RND_STATE(name__, seed__) \ + struct rnd_state name__ = RND_STATE_INITIALIZER(seed__) + +unsigned int *drm_random_order(unsigned int count, + struct rnd_state *state); +void drm_random_reorder(unsigned int *order, + unsigned int count, + struct rnd_state *state); + +#endif /* __DRM_RANDOM_H__ */ -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx