[Intel-gfx] [i-g-t PATCH v12 2/5] lib: add igt_dummyload

Chris Wilson chris at chris-wilson.co.uk
Fri Nov 25 09:17:50 UTC 2016


On Thu, Nov 24, 2016 at 12:16:11PM +0200, Abdiel Janulgue wrote:
> A lot of igt testcases need some GPU workload to make sure a race
> window is big enough. Unfortunately having a fixed amount of
> workload leads to spurious test failures or overly long runtimes
> on some fast/slow platforms. This library contains functionality
> to submit GPU workloads that should consume exactly a specific
> amount of time.
> 
> v2 : Add recursive batch feature from Chris
> v3 : Drop auto-tuned stuff. Add bo dependecy to recursive batch
>      by adding a dummy reloc to the bo as suggested by Ville.
> v4:  Fix dependency reloc as write instead of read (Ville).
>      Fix wrong handling of batchbuffer start on ILK causing
>      test failure
> v5:  Convert kms_busy to use this api
> v6:  Add this library to docs
> v7:  Document global use of batch, reuse defines
>      Minor code cleanups.
>      Rename igt_spin_batch and igt_post_spin_batch to
>      igt_spin_batch_new and igt_spin_batch_free
>      respectively (Tomeu Vizoso).
>      Fix error in dependency relocation handling in HSW causing
>      tests to fail.
> v8:  Restore correct order of objects in the execbuffer. Batch
>      object should always be last.
> v9 : Add helper to terminate batch manually
> v10: Split timeout function. Clarify function names (Chris)
> v11: From Chris:
>      * Add gem_quiescent_gpu exit handler
>      * Use gem_bo_busy
>      * Skip spin->handle > 0 checks
>      * Ensure terminate batch on free
>      * Remove igt_spin_batch_wait
>      * Remove single-ring limitation
> v12: Hook into gem_quiescent_gpu exit handler to idle the GPU if
>      the user terminates tests with ^C
> 
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: tomeu at tomeuvizoso.net
> Reviewed-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
> ---
> +/**
> + * igt_spin_batch_set_timeout:
> + * @spin: spin batch state from igt_spin_batch_new()
> + * @ns: amount of time in nanoseconds the batch continues to execute
> + *      before finishing.
> + *
> + * Specify a timeout. This ends the recursive batch associated with @spin after
> + * the timeout has elapsed.
> + */
> +void igt_spin_batch_set_timeout(igt_spin_t *spin, int64_t ns)
> +{
> +	timer_t timer;
> +	struct sigevent sev;
> +	struct sigaction act;
> +	struct itimerspec its;
> +
> +	igt_assert(ns > 0);
> +	if (!spin)
> +		return;
> +
> +	memset(&sev, 0, sizeof(sev));
> +	sev.sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID;
> +	sev.sigev_notify_thread_id = gettid();
> +	sev.sigev_signo = SIGRTMIN + 1;
> +	igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
> +	igt_assert(timer > 0);
> +
> +	memset(&act, 0, sizeof(act));
> +	act.sa_sigaction = exit_batch_handler;
> +	act.sa_flags = SA_SIGINFO;
> +	igt_assert(sigaction(SIGRTMIN + 1, &act, NULL) == 0);

Note that we can use multiple signals here and so have multiple spinners
with timeout in parallel now that we save the spinners in a global list.

We should probably check the returned oldact to confirm that the
signal was not in use previously.

> +	memset(&its, 0, sizeof(its));
> +	its.it_value.tv_sec = ns / NSEC_PER_SEC;
> +	its.it_value.tv_nsec = ns % NSEC_PER_SEC;
> +	igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
> +
> +	spin->timer = timer;
> +}
> +
> +/**
> + * igt_spin_batch_end:
> + * @spin: spin batch state from igt_spin_batch_new()
> + *
> + * End the recursive batch associated with @spin manually.
> + */
> +void igt_spin_batch_end(igt_spin_t *spin)
> +{
> +	if (!spin)
> +		return;
> +
> +	*spin->batch = MI_BATCH_BUFFER_END;
> +	__sync_synchronize();
> +}
> +
> +/**
> + * igt_spin_batch_free:
> + * @fd: open i915 drm file descriptor
> + * @spin: spin batch state from igt_spin_batch_new()
> + *
> + * This function does the necessary post-processing after starting a recursive
> + * batch with igt_spin_batch_new().
> + */
> +void igt_spin_batch_free(int fd, igt_spin_t *spin)
> +{
> +	if (!spin)
> +		return;
> +
> +	if (spin->timer > 0)
> +		timer_delete(spin->timer);
> +
> +	igt_spin_batch_end(spin);
> +	munmap(spin->batch, bo_size);
> +	gem_close(fd, spin->handle);
> +	free(spin);
> +
> +	num_spin_objects--;

This doesn't handle multiple spin objects correctly. If only we had a
nice circular list struct. We should also contemplate whether we want
this to support threading.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the Intel-gfx mailing list