From patchwork Tue Apr 3 16:39:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 10321537 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 7B6BF60390 for ; Tue, 3 Apr 2018 16:39:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6978228779 for ; Tue, 3 Apr 2018 16:39:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5D85428BC0; Tue, 3 Apr 2018 16:39:57 +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 C84EE28779 for ; Tue, 3 Apr 2018 16:39:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CA8546E2DC; Tue, 3 Apr 2018 16:39:55 +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 5BED36E2DC for ; Tue, 3 Apr 2018 16:39:54 +0000 (UTC) Received: by mail-wm0-x242.google.com with SMTP id g8so11083230wmd.2 for ; Tue, 03 Apr 2018 09:39:54 -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=lYL5KYx5YJW6skvFVp0TlIMIOEaVDgHtruSZbFIV1Uc=; b=Qlsuy2rVZSee8/EXn68UoL21e5KdIxFJOXZwvfvrNnTrloniod4bx5U54dkMawXidN 4H7/FTpPHhoGQcVMI3yRf4Pr5cXboeT1xHvxr87vtuDHpibnwRJFV8KsBJZwkDhWmqpk 3pzJ81MhlV7jHTUpSL+GApEs5Jo4d4a9SWzNI8Eqxb0KyqcW3t9qTOdM//xBjvEhfGvN fKZaJffRR2eEudrXjczmIBN5VsmDqEU+VR1Mcjs46/G5Pc+WDniP3ovT4B9dytT2MY4u 9wSv5ozx2tIjEMgEFK8Ca92ZqIs80dCGqWwsP7/sdD15/Tfe3McfTnLBXObnjbtVBNhe OEEw== 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=lYL5KYx5YJW6skvFVp0TlIMIOEaVDgHtruSZbFIV1Uc=; b=nmUzjU2HOlilV5gOZOZmhToJf/gkO1QJPwCGNR2btlUxcnnGiLruaSSF4uQaequy1X SwpFN69F+/rzhSRNjqGdKLnuUK9dQ1t8iZd62qcy8CqJEK3KLA8QfEd2qDLEgoN6Q+WT VslT/15Dl8KozrExWQ+N7MClQDliFEqjg5WK1fffDDsMIOBbezsxXx4h81OBNYUpQQM0 e004IL0tPmi8OYt69ngZjzO4L7KCvCfWwHDH1gw/W0Oqu7SiTjOSy0Gh+tvPoZ0fv+Rp oBMDt4IEQDYsovbhkm9cy8v+WZ1hOYRvFHQl9Ndi3GPO7b2pAno77yJSJT+y8FbSWmyG tYRA== X-Gm-Message-State: AElRT7E2lxM7EzVFrRkl8b7kcEc0dRMfRiwUEDvcacuySkdwL/Gwh3T+ YkUp0yJnCeuMuzmEywOaiwxMYw== X-Google-Smtp-Source: AIpwx4/T2hoR+Sf+bJAkgNkdbdZsnI5UCjyu6ljxTqYUvUs3Bzk2kilBIYttDpmApMCcqnniGCND5Q== X-Received: by 10.28.142.1 with SMTP id q1mr5406011wmd.0.1522773592888; Tue, 03 Apr 2018 09:39:52 -0700 (PDT) Received: from localhost.localdomain ([95.146.144.186]) by smtp.gmail.com with ESMTPSA id n47sm3766594wrf.41.2018.04.03.09.39.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Apr 2018 09:39:52 -0700 (PDT) From: Tvrtko Ursulin X-Google-Original-From: Tvrtko Ursulin To: igt-dev@lists.freedesktop.org Date: Tue, 3 Apr 2018 17:39:43 +0100 Message-Id: <20180403163943.8425-1-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180403123825.7341-1-tvrtko.ursulin@linux.intel.com> References: <20180403123825.7341-1-tvrtko.ursulin@linux.intel.com> Subject: [Intel-gfx] [PATCH i-g-t v3] 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. Signed-off-by: Tvrtko Ursulin --- tests/perf_pmu.c | 108 +++++++++++++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c index 2273ddb9e684..697008c855fd 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,63 @@ 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); +// printf("%f * %f = %f\n", err - avg, err - tmp, (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); write(link[1], &expected, sizeof(expected)); } @@ -1649,7 +1647,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); }