[igt-dev] [CI i-g-t 1/2] tests/gem_exec_latency: New subtests for checking submission from RT tasks
Chris Wilson
chris at chris-wilson.co.uk
Wed Apr 18 08:17:35 UTC 2018
Quoting Tvrtko Ursulin (2018-04-17 09:41:11)
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>
> We want to make sure RT tasks which use a lot of CPU times can submit
> batch buffers with roughly the same latency (and certainly not worse)
> compared to normal tasks.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> ---
> +/*
> + * Test whether RT thread which hogs the CPU a lot can submit work with
> + * reasonable latency.
> + */
> +static void
> +rthog_latency_on_ring(int fd, unsigned int ring, const char *name)
> +{
> + const char *passname[] = { "warmup", "normal", "rt" };
> + struct rt_pkt res[3];
> + unsigned int i;
> + int link[2];
> + int ret;
> +
> + igt_require(gem_can_store_dword(fd, ring));
> +
> + igt_assert(pipe(link) == 0);
> +
> + memset(res, 0, sizeof(res));
> +
> + igt_fork(child, 1) {
> + unsigned int pass = 0; /* Three passes: warmup, normal, rt. */
> +
> + do {
> + struct rt_pkt msg = { };
> + igt_spin_t *spin;
> +
> + igt_mean_init(&msg.mean);
> +
> + if (pass == 2) {
> + struct sched_param rt =
> + { .sched_priority = 99 };
> +
> + ret = sched_setscheduler(0,
> + SCHED_FIFO | SCHED_RESET_ON_FORK,
> + &rt);
> + if (ret) {
> + igt_warn("Failed to set scheduling policy!\n");
> + msg.status = RT_FAIL;
> + write(link[1], &msg, sizeof(msg));
> + exit(1);
> + }
> + }
> +
> + spin = __igt_spin_batch_new_poll(fd, 0, ring);
> + if (!spin) {
> + igt_warn("Failed to create spinner! (%s)\n",
> + passname[pass]);
> + msg.status = RT_FAIL;
> + write(link[1], &msg, sizeof(msg));
> + exit(1);
> + }
> + igt_spin_busywait_until_running(spin);
> +
> + igt_until_timeout(pass > 0 ? 5 : 2) {
> + double t;
> +
> + igt_spin_batch_end(spin);
> + gem_sync(fd, spin->handle);
> +
> + __rearm_spin_batch(spin);
> + __submit_spin_batch(fd, spin, ring);
> +
> + __spin_wait(&msg, spin, &t);
> + if (msg.status != RT_OK) {
> + igt_warn("Wait timeout! (%s)\n",
> + passname[pass]);
> + write(link[1], &msg, sizeof(msg));
> + exit(1);
> + }
> +
> + if (t > msg.max)
> + msg.max = t;
> +
> + igt_mean_add(&msg.mean, t);
> + }
> +
> + igt_spin_batch_free(fd, spin);
> +
> + igt_info("%10s: mean=%.2fus variance=%.2fus max=%.2fus (n=%lu)\n",
> + passname[pass],
> + igt_mean_get(&msg.mean) * 1e6,
> + igt_mean_get_variance(&msg.mean) * 1e6,
> + msg.max * 1e6,
> + msg.mean.count);
> +
> + write(link[1], &msg, sizeof(msg));
> + } while (++pass < 3);
> +
> + exit(0);
> + }
> +
> + for (i = 0; i < 3; i++) {
> + ret = read(link[0], &res[i], sizeof(res[0]));
> + igt_assert_eq(ret, sizeof(res[0]));
> +
> + igt_assert_eq(res[i].status, RT_OK);
> + }
> +
> + close(link[0]);
> + close(link[1]);
> +
> + igt_waitchildren();
> +
> + /*
> + * Check that the submission latency variance for a task with RT
> + * priority is no larger than three times the same of a normal task.
> + */
> + igt_assert(igt_mean_get_variance(&res[2].mean) <
> + igt_mean_get_variance(&res[1].mean) * 3);
> +}
Fwiw, I think we should go full on ministat here, use igt_stats_t to
record every result then print the overlapping histograms so we can see
the distribution.
I was pondering a simple metric to warn about long tails. I was
wondering if the sum of values above the median would be interesting,
but really it boils down to wanting 99% to be within a smidgen of each
other.
-Chris
More information about the igt-dev
mailing list