From patchwork Fri Aug 10 11:01:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10562627 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8A421157B for ; Fri, 10 Aug 2018 11:19:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B53B2B795 for ; Fri, 10 Aug 2018 11:19:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F73E2B7B4; Fri, 10 Aug 2018 11:19:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0CECC2B795 for ; Fri, 10 Aug 2018 11:19:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 768C16E8AE; Fri, 10 Aug 2018 11:19:01 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2F7F86E86E; Fri, 10 Aug 2018 11:18:57 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 12776894-1500050 for multiple; Fri, 10 Aug 2018 12:01:52 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 10 Aug 2018 12:01:48 +0100 Message-Id: <20180810110149.10771-2-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180810110149.10771-1-chris@chris-wilson.co.uk> References: <20180810110149.10771-1-chris@chris-wilson.co.uk> Subject: [Intel-gfx] [PATCH i-g-t 2/3] gem_sync: Measure wakeup latency while also scheduling the next batch X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP More variants on stress waits to serve the dual purpose of investigating different aspects of the latency (this time while also serving execlists interrupts) while also checking that we never miss the wakeup. Signed-off-by: Chris Wilson --- tests/gem_sync.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/tests/gem_sync.c b/tests/gem_sync.c index 495ca3b53..c697220ad 100644 --- a/tests/gem_sync.c +++ b/tests/gem_sync.c @@ -294,6 +294,144 @@ wakeup_ring(int fd, unsigned ring, int timeout, int wlen) igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0); } +static void +active_wakeup_ring(int fd, unsigned ring, int timeout, int wlen) +{ + unsigned engines[16]; + const char *names[16]; + int num_engines = 0; + + if (ring == ALL_ENGINES) { + for_each_physical_engine(fd, ring) { + if (!gem_can_store_dword(fd, ring)) + continue; + + names[num_engines] = e__->name; + engines[num_engines++] = ring; + if (num_engines == ARRAY_SIZE(engines)) + break; + } + igt_require(num_engines); + } else { + gem_require_ring(fd, ring); + igt_require(gem_can_store_dword(fd, ring)); + names[num_engines] = NULL; + engines[num_engines++] = ring; + } + + intel_detect_and_clear_missed_interrupts(fd); + igt_fork(child, num_engines) { + const uint32_t bbe = MI_BATCH_BUFFER_END; + struct drm_i915_gem_exec_object2 object; + struct drm_i915_gem_execbuffer2 execbuf; + double end, this, elapsed, now, baseline; + unsigned long cycles; + igt_spin_t *spin[2]; + uint32_t cmd; + + memset(&object, 0, sizeof(object)); + object.handle = gem_create(fd, 4096); + gem_write(fd, object.handle, 0, &bbe, sizeof(bbe)); + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(&object); + execbuf.buffer_count = 1; + execbuf.flags = engines[child % num_engines]; + + spin[0] = __igt_spin_batch_new(fd, + .engine = execbuf.flags, + .flags = (IGT_SPIN_POLL_RUN | + IGT_SPIN_FAST)); + igt_assert(spin[0]->running); + cmd = *spin[0]->batch; + + spin[1] = __igt_spin_batch_new(fd, + .engine = execbuf.flags, + .flags = (IGT_SPIN_POLL_RUN | + IGT_SPIN_FAST)); + + gem_execbuf(fd, &execbuf); + + igt_spin_batch_end(spin[1]); + igt_spin_batch_end(spin[0]); + gem_sync(fd, object.handle); + + for (int warmup = 0; warmup <= 1; warmup++) { + *spin[0]->batch = cmd; + *spin[0]->running = 0; + gem_execbuf(fd, &spin[0]->execbuf); + + end = gettime() + timeout/10.; + elapsed = 0; + cycles = 0; + do { + while (!READ_ONCE(*spin[0]->running)) + ; + + *spin[1]->batch = cmd; + *spin[1]->running = 0; + gem_execbuf(fd, &spin[1]->execbuf); + + this = gettime(); + igt_spin_batch_end(spin[0]); + gem_sync(fd, spin[0]->handle); + now = gettime(); + + elapsed += now - this; + cycles++; + igt_swap(spin[0], spin[1]); + } while (now < end); + igt_spin_batch_end(spin[0]); + baseline = elapsed / cycles; + } + igt_info("%s%saseline %ld cycles: %.3f us\n", + names[child % num_engines] ?: "", + names[child % num_engines] ? " b" : "B", + cycles, elapsed*1e6/cycles); + + *spin[0]->batch = cmd; + *spin[0]->running = 0; + gem_execbuf(fd, &spin[0]->execbuf); + + end = gettime() + timeout; + elapsed = 0; + cycles = 0; + do { + while (!READ_ONCE(*spin[0]->running)) + ; + + for (int n = 0; n < wlen; n++) + gem_execbuf(fd, &execbuf); + + *spin[1]->batch = cmd; + *spin[1]->running = 0; + gem_execbuf(fd, &spin[1]->execbuf); + + this = gettime(); + igt_spin_batch_end(spin[0]); + gem_sync(fd, object.handle); + now = gettime(); + + elapsed += now - this; + cycles++; + igt_swap(spin[0], spin[1]); + } while (now < end); + igt_spin_batch_end(spin[0]); + elapsed -= cycles * baseline; + + igt_info("%s%sompleted %ld cycles: %.3f + %.3f us\n", + names[child % num_engines] ?: "", + names[child % num_engines] ? " c" : "C", + cycles, 1e6*baseline, elapsed*1e6/cycles); + + igt_spin_batch_free(fd, spin[1]); + igt_spin_batch_free(fd, spin[0]); + gem_close(fd, object.handle); + } + igt_waitchildren_timeout(2*timeout, NULL); + igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0); +} + static void store_ring(int fd, unsigned ring, int num_children, int timeout) { @@ -1018,6 +1156,8 @@ igt_main idle_ring(fd, e->exec_id | e->flags, 150); igt_subtest_f("wakeup-%s", e->name) wakeup_ring(fd, e->exec_id | e->flags, 150, 1); + igt_subtest_f("active-wakeup-%s", e->name) + active_wakeup_ring(fd, e->exec_id | e->flags, 150, 1); igt_subtest_f("double-wakeup-%s", e->name) wakeup_ring(fd, e->exec_id | e->flags, 150, 2); igt_subtest_f("store-%s", e->name) @@ -1050,6 +1190,8 @@ igt_main store_ring(fd, ALL_ENGINES, ncpus, 150); igt_subtest("wakeup-each") wakeup_ring(fd, ALL_ENGINES, 150, 1); + igt_subtest("active-wakeup-each") + active_wakeup_ring(fd, ALL_ENGINES, 150, 1); igt_subtest("double-wakeup-each") wakeup_ring(fd, ALL_ENGINES, 150, 2);