From patchwork Wed Apr 4 09:51:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 10322323 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5D2EC60318 for ; Wed, 4 Apr 2018 09:52:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4534B28C80 for ; Wed, 4 Apr 2018 09:52:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3A0E328E1C; Wed, 4 Apr 2018 09:52:05 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID 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 9211728C80 for ; Wed, 4 Apr 2018 09:52:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E0426E081; Wed, 4 Apr 2018 09:52:04 +0000 (UTC) X-Original-To: Intel-gfx@lists.freedesktop.org Delivered-To: Intel-gfx@lists.freedesktop.org Received: from mail-wm0-x242.google.com (mail-wm0-x242.google.com [IPv6:2a00:1450:400c:c09::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6B2056E081 for ; Wed, 4 Apr 2018 09:52:03 +0000 (UTC) Received: by mail-wm0-x242.google.com with SMTP id x4so40691804wmh.5 for ; Wed, 04 Apr 2018 02:52:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ursulin-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ihYG38OP4lykgq0Hd0gE9oSPVcjDCPXqO1LqpYBYCMo=; b=O7UqdGeKrHODh9I9y4c57VtMvpXXmPDyxGomTL8R2DWZagkDxfaDN7+AI58LSav7FY QwgqOne6lX4AOkvVB4QAnP3kAe3NQMy22frUkiY3+ErORxpjcbasJ05Z+QbgkFswiLkP aK0Dl1ltMQ9EGerwgNJZ0+sW5G1wVBqHKGbv1R7XBwN1puAZgU7Q7rWkBXx+MZCwRCSH AsWmr99zz7x1IxoQGgqk/Tfu2HgF7YMg+SOOt9qq+uEfRqURZfyTVYyswvDWFEunguu6 dNkGXo37hf+0AQ50XyEfkGMiBKIeD8gWnpTB9T4lFxw8G7NcGJO12cla90bVpUQcx1TK j/fQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ihYG38OP4lykgq0Hd0gE9oSPVcjDCPXqO1LqpYBYCMo=; b=DfD5d2dc2HmDEiPjN6ZQeytScUjo/ISsBiLG192pg9TRkvaKlW8HiiVhkBiZOUY2+R MwyHEvenrKC0iPtwsKB9Kfd5HpbuMyLKiU2WOtGddmrFAFsCJeJbtSOGrkYIDDklOUp3 BAC+rjZk3cjKWH09k4Luwps6fmC73Hgssk53u992ESWrDEujkdfNQKnmUrp+BKkuyKJb +br312Qio5HaXxMLfSM5g8mF1a8h31azcN5jlB5/FmCetKbjvTlGgxiES7DwjdLpAPzx F5Hu6eudHotMwZwASKj3zyecs1rqPTSlvtoFjtSFdg/K0OifmQgweMsVJvMUuLxiziLE zm/Q== X-Gm-Message-State: ALQs6tDv2f3jpeL9WnQCvckQwQZZbwPyPEtXqjhzqHisSVvA3CvRwuEk ExprShgtmntCHiXBIa9Rq2hxow== X-Google-Smtp-Source: AIpwx482UMluTGLJNF7AQnLM0jJX0MCGyMbH2c7HFOh+Ra8VwY3kryXPlLORBD/W3f4HZJgmKVLNAA== X-Received: by 10.28.133.82 with SMTP id h79mr6202437wmd.56.1522835521999; Wed, 04 Apr 2018 02:52:01 -0700 (PDT) Received: from localhost.localdomain ([95.146.144.186]) by smtp.gmail.com with ESMTPSA id 90sm6283668wrl.10.2018.04.04.02.52.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Apr 2018 02:52:01 -0700 (PDT) From: Tvrtko Ursulin X-Google-Original-From: Tvrtko Ursulin To: igt-dev@lists.freedesktop.org Date: Wed, 4 Apr 2018 10:51:52 +0100 Message-Id: <20180404095152.5110-1-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180403163943.8425-1-tvrtko.ursulin@linux.intel.com> References: <20180403163943.8425-1-tvrtko.ursulin@linux.intel.com> Subject: [Intel-gfx] [PATCH i-g-t v4] tests/perf_pmu: Avoid RT thread for accuracy test 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: Intel-gfx@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Tvrtko Ursulin Realtime scheduling interferes with execlists submission (tasklet) so try to simplify the PWM loop in a few ways: * Drop RT. * Longer batches for smaller systematic error. * More truthful test duration calculation. * Less clock queries. * No self-adjust - instead just report the achieved cycle and let the parent check against it. * Report absolute cycle error. v2: * Bring back self-adjust. (Chris Wilson) (But slightly fixed version with no overflow.) v3: * Log average and mean calibration for each pass. v4: * Eliminate development leftovers. * Fix variance logging. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- tests/perf_pmu.c | 107 +++++++++++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c index 2273ddb9e684..590e6526b069 100644 --- a/tests/perf_pmu.c +++ b/tests/perf_pmu.c @@ -1497,12 +1497,6 @@ test_enable_race(int gem_fd, const struct intel_execution_engine2 *e) gem_quiescent_gpu(gem_fd); } -static double __error(double val, double ref) -{ - igt_assert(ref > 1e-5 /* smallval */); - return (100.0 * val / ref) - 100.0; -} - static void __rearm_spin_batch(igt_spin_t *spin) { const uint32_t mi_arb_chk = 0x5 << 23; @@ -1525,13 +1519,12 @@ static void accuracy(int gem_fd, const struct intel_execution_engine2 *e, unsigned long target_busy_pct) { - const unsigned int min_test_loops = 7; - const unsigned long min_test_us = 1e6; - unsigned long busy_us = 2500; + unsigned long busy_us = 10000 - 100 * (1 + abs(50 - target_busy_pct)); unsigned long idle_us = 100 * (busy_us - target_busy_pct * busy_us / 100) / target_busy_pct; - unsigned long pwm_calibration_us; - unsigned long test_us; + const unsigned long min_test_us = 1e6; + const unsigned long pwm_calibration_us = min_test_us; + const unsigned long test_us = min_test_us; double busy_r, expected; uint64_t val[2]; uint64_t ts[2]; @@ -1546,13 +1539,6 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e, idle_us *= 2; } - pwm_calibration_us = min_test_loops * (busy_us + idle_us); - while (pwm_calibration_us < min_test_us) - pwm_calibration_us += busy_us + idle_us; - test_us = min_test_loops * (idle_us + busy_us); - while (test_us < min_test_us) - test_us += busy_us + idle_us; - igt_info("calibration=%lums, test=%lums; ratio=%.2f%% (%luus/%luus)\n", pwm_calibration_us / 1000, test_us / 1000, (double)busy_us / (busy_us + idle_us) * 100.0, @@ -1565,20 +1551,11 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e, /* Emit PWM pattern on the engine from a child. */ igt_fork(child, 1) { - struct sched_param rt = { .sched_priority = 99 }; const unsigned long timeout[] = { pwm_calibration_us * 1000, test_us * 1000 }; - uint64_t total_busy_ns = 0, total_idle_ns = 0; + uint64_t total_busy_ns = 0, total_ns = 0; igt_spin_t *spin; - int ret; - - /* We need the best sleep accuracy we can get. */ - ret = sched_setscheduler(0, - SCHED_FIFO | SCHED_RESET_ON_FORK, - &rt); - if (ret) - igt_warn("Failed to set scheduling policy!\n"); /* Allocate our spin batch and idle it. */ spin = igt_spin_batch_new(gem_fd, 0, e2ring(gem_fd, e), 0); @@ -1587,42 +1564,62 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e, /* 1st pass is calibration, second pass is the test. */ for (int pass = 0; pass < ARRAY_SIZE(timeout); pass++) { - uint64_t busy_ns = -total_busy_ns; - uint64_t idle_ns = -total_idle_ns; - struct timespec test_start = { }; + unsigned int target_idle_us = idle_us; + uint64_t busy_ns = 0, idle_ns = 0; + struct timespec start = { }; + unsigned long pass_ns = 0; + double avg = 0.0, var = 0.0; + unsigned int n = 0; + + igt_nsec_elapsed(&start); - igt_nsec_elapsed(&test_start); do { - unsigned int target_idle_us, t_busy; + unsigned long loop_ns, loop_busy; + struct timespec _ts = { }; + double err, tmp; + + /* PWM idle sleep. */ + _ts.tv_nsec = target_idle_us * 1000; + nanosleep(&_ts, NULL); /* Restart the spinbatch. */ __rearm_spin_batch(spin); __submit_spin_batch(gem_fd, spin, e, 0); - /* - * Note that the submission may be delayed to a - * tasklet (ksoftirqd) which cannot run until we - * sleep as we hog the cpu (we are RT). - */ - - t_busy = measured_usleep(busy_us); + /* PWM busy sleep. */ + loop_busy = igt_nsec_elapsed(&start); + _ts.tv_nsec = busy_us * 1000; + nanosleep(&_ts, NULL); igt_spin_batch_end(spin); - gem_sync(gem_fd, spin->handle); - - total_busy_ns += t_busy; - - target_idle_us = - (100 * total_busy_ns / target_busy_pct - (total_busy_ns + total_idle_ns)) / 1000; - total_idle_ns += measured_usleep(target_idle_us); - } while (igt_nsec_elapsed(&test_start) < timeout[pass]); - - busy_ns += total_busy_ns; - idle_ns += total_idle_ns; - expected = (double)busy_ns / (busy_ns + idle_ns); - igt_info("%u: busy %"PRIu64"us, idle %"PRIu64"us: %.2f%% (target: %lu%%)\n", + /* Time accounting. */ + loop_ns = igt_nsec_elapsed(&start); + loop_busy = loop_ns - loop_busy; + loop_ns -= pass_ns; + + busy_ns += loop_busy; + total_busy_ns += loop_busy; + idle_ns += loop_ns - loop_busy; + pass_ns += loop_ns; + total_ns += loop_ns; + + /* Re-calibrate. */ + err = (double)total_busy_ns / total_ns - + (double)target_busy_pct / 100.0; + target_idle_us = (double)target_idle_us * + (1.0 + err); + + /* Running average and variance for debug. */ + err = 100.0 * total_busy_ns / total_ns; + tmp = avg; + avg += (err - avg) / ++n; + var += (err - avg) * (err - tmp); + } while (pass_ns < timeout[pass]); + + expected = (double)busy_ns / pass_ns; + igt_info("%u: busy %"PRIu64"us, idle %"PRIu64"us -> %.2f%% (target: %lu%%; average=%.2f, variance=%f)\n", pass, busy_ns / 1000, idle_ns / 1000, - 100 * expected, target_busy_pct); + 100 * expected, target_busy_pct, avg, var / n); write(link[1], &expected, sizeof(expected)); } @@ -1649,7 +1646,7 @@ accuracy(int gem_fd, const struct intel_execution_engine2 *e, busy_r = (double)(val[1] - val[0]) / (ts[1] - ts[0]); igt_info("error=%.2f%% (%.2f%% vs %.2f%%)\n", - __error(busy_r, expected), 100 * busy_r, 100 * expected); + (busy_r - expected) * 100, 100 * busy_r, 100 * expected); assert_within(100.0 * busy_r, 100.0 * expected, 2); }