Quoting Tvrtko Ursulin (2018-04-17 09:41:11) > From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> > > 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@xxxxxxxxx> > Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > --- > +/* > + * 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx