[igt-dev] [PATCH i-g-t 1/2] lib/i915/gem_engine_topology: add iterator for choosing one random engine from each class

Petri Latvala petri.latvala at intel.com
Mon Mar 21 09:52:24 UTC 2022


On Fri, Mar 18, 2022 at 05:04:44PM +0100, Kamil Konieczny wrote:
> In new GPUs there are many engines so tests with fixed timeout
> which iterate over all engines can take much longer than on older
> gens. Add new iterator for_one_random_cfg_ctx_engine, which will
> iterate over each class of engines and will choose one from each
> class at random.
> 
> Cc: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
> Signed-off-by: Kamil Konieczny <kamil.konieczny at linux.intel.com>
> ---
>  lib/i915/gem_engine_topology.c | 64 ++++++++++++++++++++++++++++++++++
>  lib/i915/gem_engine_topology.h | 19 ++++++++++
>  2 files changed, 83 insertions(+)
> 
> diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
> index ca3333c2..52a2f3ef 100644
> --- a/lib/i915/gem_engine_topology.c
> +++ b/lib/i915/gem_engine_topology.c
> @@ -208,6 +208,70 @@ void intel_next_engine(struct intel_engine_data *ed)
>  	}
>  }
>  
> +static void __intel_random_init(void)
> +{
> +	struct timespec start;
> +
> +	clock_gettime(CLOCK_MONOTONIC, &start);
> +	igt_debug("seed %d\n", (int)start.tv_nsec);
> +	srand((int)start.tv_nsec);
> +}

I don't like randomness for testing, but it sure is sometimes needed.

We have quite a bit of rand()-using tests and some of them have a
--seed parameter so their results can be reproduced. Currently there's
no overlap in sight with them and this thing, but if testing ever
expands that way, mixing RNGs might break reproduceability. Can this
instead use another RNG stream that's self-contained, like maybe
rand_r() or such? Or the one implemented in lib/igt_rand.


-- 
Petri Latvala



> +
> +static void __intel_find_random_engine(struct intel_engine_data *ed)
> +{
> +	struct intel_execution_engine2 *ce = ed->current_engine;
> +	struct intel_execution_engine2 *next = ce;
> +	uint16_t class = ce->class;
> +	uint32_t i;
> +	uint32_t n;
> +
> +	n = ed->n;
> +	while (class == next->class && n < ed->nengines) {
> +		++next;
> +		++n;
> +	}
> +
> +	i = n - ed->n;
> +	if (i > 1)
> +		ed->n += rand() % i;
> +
> +	ed->current_engine = &ed->engines[ed->n];
> +}
> +
> +struct intel_execution_engine2 *
> +intel_get_random_engine(struct intel_engine_data *ed)
> +{
> +	if (!ed->n) {
> +		__intel_random_init();
> +		ed->current_engine = &ed->engines[0];
> +		__intel_find_random_engine(ed);
> +	}
> +
> +	return ed->current_engine;
> +}
> +
> +void intel_next_random_engine(struct intel_engine_data *ed)
> +{
> +	struct intel_execution_engine2 *ce = ed->current_engine;
> +	uint16_t class;
> +
> +	if (!ce)
> +		return;
> +
> +	class = ce->class;
> +	while (ce->class == class && ed->n < ed->nengines) {
> +		ed->n++;
> +		++ce;
> +	}
> +
> +	if (ed->n == ed->nengines)
> +		ed->current_engine = NULL;
> +	else {
> +		ed->current_engine = ce;
> +		__intel_find_random_engine(ed);
> +	}
> +}
> +
>  struct intel_execution_engine2 *
>  intel_get_current_physical_engine(struct intel_engine_data *ed)
>  {
> diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
> index 987f2bf9..cad5b46b 100644
> --- a/lib/i915/gem_engine_topology.h
> +++ b/lib/i915/gem_engine_topology.h
> @@ -61,6 +61,10 @@ intel_get_current_physical_engine(struct intel_engine_data *ed);
>  
>  void intel_next_engine(struct intel_engine_data *ed);
>  
> +struct intel_execution_engine2 *
> +intel_get_random_engine(struct intel_engine_data *ed);
> +void intel_next_random_engine(struct intel_engine_data *ed);
> +
>  bool gem_engine_is_equal(const struct intel_execution_engine2 *e1,
>  			 const struct intel_execution_engine2 *e2);
>  
> @@ -89,6 +93,21 @@ struct intel_execution_engine2 gem_eb_flags_to_engine(unsigned int flags);
>  	     ((e__) = intel_get_current_engine(&i__##e__)); \
>  	     intel_next_engine(&i__##e__))
>  
> +/**
> + * for_one_random_ctx_cfg_engine
> + * @fd__: open i915 drm file descriptor
> + * @ctx_cfg__: Intel context config
> + * @e__: struct intel_execution_engine2 iterator
> + *
> + * Choose one random engine from each class of physical engine in the context
> + * config
> + */
> +#define for_one_random_ctx_cfg_engine(fd__, ctx_cfg__, e__) \
> +	for (struct intel_engine_data i__##e__ = \
> +		intel_engine_list_for_ctx_cfg(fd__, ctx_cfg__); \
> +	     ((e__) = intel_get_random_engine(&i__##e__)); \
> +	     intel_next_random_engine(&i__##e__))
> +
>  /**
>   * for_each_ctx_engine
>   * @fd__: open i915 drm file descriptor
> -- 
> 2.32.0
> 


More information about the igt-dev mailing list