diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-05-26 17:13:41 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-05-26 21:15:33 +0100 |
commit | cc5f9f1a4f630c7b7f8bbdc835d21181551012fb (patch) | |
tree | 6a3735b832f48f169c2138d54acf85eeae2c6a89 | |
parent | f1e62e330a6e2de7b3cbf7cf02d71ae00cc6adcc (diff) |
i915/gem_exec_schedule: Fix measurement of ring size to use right engine
gem_ring_measure_inflight() uses the legacy ring idx, whereas
gem_exec_schedule is using the new dynamic ctx->engine[] indices.
Mismatch and hanging tests ensue.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
-rw-r--r-- | lib/i915/gem_submission.c | 115 | ||||
-rw-r--r-- | lib/i915/gem_submission.h | 2 | ||||
-rw-r--r-- | tests/i915/gem_busy.c | 2 | ||||
-rw-r--r-- | tests/i915/gem_exec_fence.c | 2 | ||||
-rw-r--r-- | tests/i915/gem_exec_schedule.c | 7 | ||||
-rw-r--r-- | tests/perf_pmu.c | 2 |
6 files changed, 123 insertions, 7 deletions
diff --git a/lib/i915/gem_submission.c b/lib/i915/gem_submission.c index 6bea6aa3d..e5deb6cea 100644 --- a/lib/i915/gem_submission.c +++ b/lib/i915/gem_submission.c @@ -23,8 +23,10 @@ #include <errno.h> #include <fcntl.h> +#include <signal.h> #include <stdbool.h> #include <sys/ioctl.h> +#include <sys/time.h> #include <i915_drm.h> @@ -278,3 +280,116 @@ bool gem_engine_has_mutable_submission(int i915, unsigned int engine) return gem_class_has_mutable_submission(i915, gem_execbuf_flags_to_engine_class(engine)); } + +static int __execbuf(int i915, struct drm_i915_gem_execbuffer2 *execbuf) +{ + int err; + + err = 0; + if (ioctl(i915, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf)) { + err = -errno; + igt_assume(err); + } + + errno = 0; + return err; +} + +static void alarm_handler(int sig) +{ +} + +static unsigned int +__measure_ringsize(int i915, unsigned int engine) +{ + struct sigaction old_sa, sa = { .sa_handler = alarm_handler }; + struct drm_i915_gem_exec_object2 obj[2]; + struct drm_i915_gem_execbuffer2 execbuf; + const uint32_t bbe = MI_BATCH_BUFFER_END; + unsigned int last[2]= { -1, -1 }, count; + struct itimerval itv; + IGT_CORK_HANDLE(cork); + + memset(obj, 0, sizeof(obj)); + obj[1].handle = gem_create(i915, 4096); + gem_write(i915, obj[1].handle, 0, &bbe, sizeof(bbe)); + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(&obj[1]); + execbuf.buffer_count = 1; + execbuf.flags = engine; + gem_execbuf(i915, &execbuf); + + obj[0].handle = igt_cork_plug(&cork, i915); + + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 2; + + sigaction(SIGALRM, &sa, &old_sa); + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 1000; + itv.it_value.tv_sec = 0; + itv.it_value.tv_usec = 10000; + setitimer(ITIMER_REAL, &itv, NULL); + + count = 0; + do { + int err = __execbuf(i915, &execbuf); + + if (err == 0) { + count++; + continue; + } + + if (err == -EWOULDBLOCK) + break; + + if (last[1] == count) + break; + + /* sleep until the next timer interrupt (woken on signal) */ + pause(); + last[1] = last[0]; + last[0] = count; + } while (1); + igt_assert(count > 2); + + memset(&itv, 0, sizeof(itv)); + setitimer(ITIMER_REAL, &itv, NULL); + sigaction(SIGALRM, &old_sa, NULL); + + igt_cork_unplug(&cork); + gem_close(i915, obj[0].handle); + gem_close(i915, obj[1].handle); + + /* Be conservative, expect relocations, in case we must wrap later */ + return count / 2 - 1; +} + +unsigned int gem_submission_measure(int i915, unsigned int engine) +{ + unsigned int size; + bool nonblock; + + nonblock = fcntl(i915, F_GETFD) & O_NONBLOCK; + if (!nonblock) + fcntl(i915, F_SETFD, fcntl(i915, F_GETFD) | O_NONBLOCK); + + if (engine == ALL_ENGINES) { + struct intel_execution_engine2 *e; + + size = -1; + __for_each_physical_engine(i915, e) { + unsigned int this = __measure_ringsize(i915, e->flags); + if (this < size) + size = this; + } + } else { + size = __measure_ringsize(i915, engine); + } + + if (!nonblock) + fcntl(i915, F_SETFD, fcntl(i915, F_GETFD) & ~O_NONBLOCK); + + return size; +} diff --git a/lib/i915/gem_submission.h b/lib/i915/gem_submission.h index b030ed9fc..773e7b516 100644 --- a/lib/i915/gem_submission.h +++ b/lib/i915/gem_submission.h @@ -46,6 +46,8 @@ static inline bool gem_has_cmdparser(int i915, uint32_t engine) bool gem_has_blitter(int i915); void gem_require_blitter(int i915); +unsigned int gem_submission_measure(int i915, unsigned int engine); + void gem_test_engine(int fd, unsigned int engine); #endif /* GEM_SUBMISSION_H */ diff --git a/tests/i915/gem_busy.c b/tests/i915/gem_busy.c index a3cff23fc..ee6a5ca0e 100644 --- a/tests/i915/gem_busy.c +++ b/tests/i915/gem_busy.c @@ -232,7 +232,7 @@ static void xchg_u32(void *array, unsigned i, unsigned j) static void close_race(int fd) { const unsigned int ncpus = sysconf(_SC_NPROCESSORS_ONLN); - const unsigned int nhandles = gem_measure_ring_inflight(fd, ALL_ENGINES, 0) / 2; + const unsigned int nhandles = gem_submission_measure(fd, ALL_ENGINES); const struct intel_execution_engine2 *e; unsigned int engines[16], nengine; unsigned long *control; diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c index 4140bff24..ad22f9f57 100644 --- a/tests/i915/gem_exec_fence.c +++ b/tests/i915/gem_exec_fence.c @@ -1756,7 +1756,7 @@ igt_main long ring_size = 0; igt_fixture { - ring_size = gem_measure_ring_inflight(i915, ALL_ENGINES, 0) - 1; + ring_size = gem_submission_measure(i915, ALL_ENGINES); igt_info("Ring size: %ld batches\n", ring_size); igt_require(ring_size); diff --git a/tests/i915/gem_exec_schedule.c b/tests/i915/gem_exec_schedule.c index c551e23ea..c5390493b 100644 --- a/tests/i915/gem_exec_schedule.c +++ b/tests/i915/gem_exec_schedule.c @@ -1651,7 +1651,7 @@ static void deep(int fd, unsigned ring) ctx[n] = gem_context_clone_with_engines(fd, 0); } - nreq = gem_measure_ring_inflight(fd, ring, 0) / (4 * XS) * MAX_CONTEXTS; + nreq = gem_submission_measure(fd, ring) / (4 * XS) * MAX_CONTEXTS; if (nreq > max_req) nreq = max_req; igt_info("Using %d requests (prio range %d)\n", nreq, max_req); @@ -1796,9 +1796,8 @@ static int __execbuf(int fd, struct drm_i915_gem_execbuffer2 *execbuf) static void wide(int fd, unsigned ring) { + const unsigned int ring_size = gem_submission_measure(fd, ring); struct timespec tv = {}; - unsigned int ring_size = gem_measure_ring_inflight(fd, ring, MEASURE_RING_NEW_CTX); - IGT_CORK_FENCE(cork); uint32_t result; uint32_t result_read[MAX_CONTEXTS]; @@ -1842,12 +1841,12 @@ static void wide(int fd, unsigned ring) static void reorder_wide(int fd, unsigned ring) { + const unsigned int ring_size = gem_submission_measure(fd, ring); const int gen = intel_gen(intel_get_drm_devid(fd)); struct drm_i915_gem_relocation_entry reloc; struct drm_i915_gem_exec_object2 obj[2]; struct drm_i915_gem_execbuffer2 execbuf; struct timespec tv = {}; - unsigned int ring_size = gem_measure_ring_inflight(fd, ring, MEASURE_RING_NEW_CTX); IGT_CORK_FENCE(cork); uint32_t result, target; uint32_t result_read[1024]; diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c index e80f730cf..f4db3c10a 100644 --- a/tests/perf_pmu.c +++ b/tests/perf_pmu.c @@ -1287,7 +1287,7 @@ static void cpu_hotplug(int gem_fd) static int target_num_interrupts(int i915) { - return min(gem_measure_ring_inflight(i915, I915_EXEC_DEFAULT, 0), 30); + return min(gem_submission_measure(i915, I915_EXEC_DEFAULT), 30); } static void |