[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