All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tursulin@ursulin.net>
To: igt-dev@lists.freedesktop.org
Cc: Intel-gfx@lists.freedesktop.org
Subject: [PATCH i-g-t v2] tests/perf_pmu: Avoid RT thread for accuracy test
Date: Tue,  3 Apr 2018 13:38:25 +0100	[thread overview]
Message-ID: <20180403123825.7341-1-tvrtko.ursulin@linux.intel.com> (raw)
In-Reply-To: <20180326105758.5211-1-tvrtko.ursulin@linux.intel.com>

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

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.)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 tests/perf_pmu.c | 97 +++++++++++++++++++++++++-------------------------------
 1 file changed, 43 insertions(+), 54 deletions(-)

diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
index f27b7ec7d2c2..0cfacd4a8fbe 100644
--- a/tests/perf_pmu.c
+++ b/tests/perf_pmu.c
@@ -1504,12 +1504,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;
@@ -1532,13 +1526,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];
@@ -1553,13 +1546,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,
@@ -1572,20 +1558,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);
@@ -1594,39 +1571,51 @@ 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;
+
+			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;
+
+				/* 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);
+				/* 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);
+			} while (pass_ns < timeout[pass]);
+
+			expected = (double)busy_ns / pass_ns;
 			igt_info("%u: busy %"PRIu64"us, idle %"PRIu64"us: %.2f%% (target: %lu%%)\n",
 				 pass, busy_ns / 1000, idle_ns / 1000,
 				 100 * expected, target_busy_pct);
@@ -1655,8 +1644,8 @@ 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);
+	igt_info("error=%.2f (%.2f%% vs %.2f%%)\n",
+		 (busy_r - expected) * 100, 100 * busy_r, 100 * expected);
 
 	assert_within(100.0 * busy_r, 100.0 * expected, 2);
 }
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: Tvrtko Ursulin <tursulin@ursulin.net>
To: igt-dev@lists.freedesktop.org
Cc: Intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH i-g-t v2] tests/perf_pmu: Avoid RT thread for accuracy test
Date: Tue,  3 Apr 2018 13:38:25 +0100	[thread overview]
Message-ID: <20180403123825.7341-1-tvrtko.ursulin@linux.intel.com> (raw)
In-Reply-To: <20180326105758.5211-1-tvrtko.ursulin@linux.intel.com>

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

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.)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 tests/perf_pmu.c | 97 +++++++++++++++++++++++++-------------------------------
 1 file changed, 43 insertions(+), 54 deletions(-)

diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
index f27b7ec7d2c2..0cfacd4a8fbe 100644
--- a/tests/perf_pmu.c
+++ b/tests/perf_pmu.c
@@ -1504,12 +1504,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;
@@ -1532,13 +1526,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];
@@ -1553,13 +1546,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,
@@ -1572,20 +1558,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);
@@ -1594,39 +1571,51 @@ 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;
+
+			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;
+
+				/* 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);
+				/* 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);
+			} while (pass_ns < timeout[pass]);
+
+			expected = (double)busy_ns / pass_ns;
 			igt_info("%u: busy %"PRIu64"us, idle %"PRIu64"us: %.2f%% (target: %lu%%)\n",
 				 pass, busy_ns / 1000, idle_ns / 1000,
 				 100 * expected, target_busy_pct);
@@ -1655,8 +1644,8 @@ 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);
+	igt_info("error=%.2f (%.2f%% vs %.2f%%)\n",
+		 (busy_r - expected) * 100, 100 * busy_r, 100 * expected);
 
 	assert_within(100.0 * busy_r, 100.0 * expected, 2);
 }
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2018-04-03 12:38 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-26 10:57 [CI i-g-t] tests/perf_pmu: Avoid RT thread for accuracy test Tvrtko Ursulin
2018-03-26 10:57 ` [Intel-gfx] " Tvrtko Ursulin
2018-03-26 11:17 ` [igt-dev] " Chris Wilson
2018-03-26 11:17   ` Chris Wilson
2018-03-26 12:40   ` Tvrtko Ursulin
2018-03-26 12:40     ` [igt-dev] [Intel-gfx] " Tvrtko Ursulin
2018-03-26 11:23 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork
2018-03-26 13:04 ` [igt-dev] ✗ Fi.CI.IGT: warning " Patchwork
2018-03-27 14:31 ` [igt-dev] ✗ Fi.CI.BAT: failure " Patchwork
2018-03-27 17:08 ` [igt-dev] ✗ Fi.CI.BAT: warning " Patchwork
2018-03-28  9:22 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2018-03-28 14:36 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2018-03-28 16:56   ` Tvrtko Ursulin
2018-03-28 17:10     ` Chris Wilson
2018-04-03 12:38 ` Tvrtko Ursulin [this message]
2018-04-03 12:38   ` [Intel-gfx] [PATCH i-g-t v2] " Tvrtko Ursulin
2018-04-03 13:10   ` Chris Wilson
2018-04-03 13:10     ` [igt-dev] [Intel-gfx] " Chris Wilson
2018-04-03 16:09     ` Tvrtko Ursulin
2018-04-03 16:09       ` [Intel-gfx] " Tvrtko Ursulin
2018-04-03 16:24       ` Chris Wilson
2018-04-03 16:24         ` [igt-dev] [Intel-gfx] " Chris Wilson
2018-04-03 16:39   ` [PATCH i-g-t v3] " Tvrtko Ursulin
2018-04-03 16:39     ` [igt-dev] " Tvrtko Ursulin
2018-04-04  9:51     ` [PATCH i-g-t v4] " Tvrtko Ursulin
2018-04-04  9:51       ` [Intel-gfx] " Tvrtko Ursulin
2018-04-11 13:23       ` Chris Wilson
2018-04-11 13:23         ` [igt-dev] [Intel-gfx] " Chris Wilson
2018-04-11 13:52         ` Tvrtko Ursulin
2018-04-11 13:52           ` [igt-dev] [Intel-gfx] " Tvrtko Ursulin
2018-04-14 11:35           ` Chris Wilson
2018-04-14 11:35             ` [igt-dev] [Intel-gfx] " Chris Wilson
2018-04-16  9:55             ` Tvrtko Ursulin
2018-04-16  9:55               ` [igt-dev] [Intel-gfx] " Tvrtko Ursulin
2018-04-16 10:08               ` Chris Wilson
2018-04-16 10:08                 ` [igt-dev] [Intel-gfx] " Chris Wilson
2018-04-03 14:23 ` [igt-dev] ✓ Fi.CI.BAT: success for tests/perf_pmu: Avoid RT thread for accuracy test (rev2) Patchwork
2018-04-03 16:41 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
2018-04-03 17:15 ` [igt-dev] ✓ Fi.CI.BAT: success for tests/perf_pmu: Avoid RT thread for accuracy test (rev3) Patchwork
2018-04-03 18:33 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
2018-04-04 11:13   ` Tvrtko Ursulin
2018-04-04 13:46 ` [igt-dev] ✓ Fi.CI.BAT: success for tests/perf_pmu: Avoid RT thread for accuracy test (rev4) Patchwork
2018-04-04 16:58 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180403123825.7341-1-tvrtko.ursulin@linux.intel.com \
    --to=tursulin@ursulin.net \
    --cc=Intel-gfx@lists.freedesktop.org \
    --cc=igt-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.