[igt-dev] [PATCH i-g-t 2/2] amdgpu/info: add a timestamp test
Martin Peres
martin.peres at mupuf.org
Tue Feb 16 12:32:36 UTC 2021
This test makes sure:
* the clock is running at the expected rate
* (potential) power gating has no effect on the clock
v2:
- use signed integer for the gpu timestamp diff (Bas)
Cc: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Signed-off-by: Martin Peres <martin.peres at mupuf.org>
---
tests/amdgpu/amd_info.c | 81 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/tests/amdgpu/amd_info.c b/tests/amdgpu/amd_info.c
index fe113e14..41f79dec 100644
--- a/tests/amdgpu/amd_info.c
+++ b/tests/amdgpu/amd_info.c
@@ -44,6 +44,84 @@ static void query_firmware_version_test(void)
igt_assert_eq(r, 0);
}
+static float query_timestamp_test_sample(uint32_t sleep_time, int sample_count)
+{
+ struct amdgpu_gpu_info gpu_info = {};
+ float *samples, average_factor = 0.0, sum_factors = 0.0, ns_per_tick;
+ int i;
+
+ /* figure out how many nanoseconds each gpu timestamp tick represents */
+ igt_assert_eq(amdgpu_query_gpu_info(dev, &gpu_info), 0);
+ igt_assert_lt(0, gpu_info.gpu_counter_freq);
+ ns_per_tick = 1e9 / (gpu_info.gpu_counter_freq * 1000.0);
+
+ samples = calloc(sample_count, sizeof(float));
+ for (i = 0; i < sample_count; i++) {
+ uint64_t ts_start, ts_end, cpu_delta;
+ int64_t gpu_delta;
+ float corrected_gpu_delta;
+ struct timespec ts_cpu;
+ int r;
+
+ igt_assert_eq(igt_gettime(&ts_cpu), 0);
+
+ r = amdgpu_query_info(dev, AMDGPU_INFO_TIMESTAMP, 8, &ts_start);
+ igt_assert_eq(r, 0);
+
+ usleep(sleep_time);
+
+ r = amdgpu_query_info(dev, AMDGPU_INFO_TIMESTAMP, 8, &ts_end);
+ igt_assert_eq(r, 0);
+
+ /* get the GPU and CPU deltas */
+ cpu_delta = igt_nsec_elapsed(&ts_cpu);
+ gpu_delta = ts_end - ts_start;
+ corrected_gpu_delta = gpu_delta * ns_per_tick;
+
+ /* make sure the GPU timestamps are ordered */
+ igt_assert_lt_s64(0, gpu_delta);
+
+ samples[i] = corrected_gpu_delta / cpu_delta;
+ sum_factors += samples[i];
+ }
+
+ /* check that all the samples are close to the average factor to detect
+ * clock skews.
+ */
+ average_factor = sum_factors / sample_count;
+ for (i = 0; i < sample_count; i++) {
+ float diff = average_factor - samples[i];
+ igt_assert_f(fabs(diff) < 0.01,
+ "Sample %i/%i exceeded the 1%% deviance from "
+ "average. Difference = %.2f%%\n", i, sample_count,
+ diff * 100.0);
+ }
+
+ return average_factor;
+}
+
+static void query_timestamp_test(void)
+{
+ float factor_short, factor_long;
+
+ /* check a small time factor repeatedly to check for stability */
+ factor_short = query_timestamp_test_sample(100000, 10);
+
+ /* check that time elapses as fast on the CPU as on the GPU */
+ igt_assert_f(fabs(1.0 - factor_short) < 0.01,
+ "The GPU time elapses at %.2f%% of the CPU's speed. "
+ "Correction factor: x%.6f\n", factor_short * 100.0,
+ 1.0 / factor_short);
+
+ /* check that time also elapses at the same rate, after the GPU has been
+ * idle for a while, as power gating may have stopped the clock.
+ * Assuming a 5s power gating delay as a worst case scenario.
+ */
+ factor_long = query_timestamp_test_sample(7000000, 1);
+ igt_assert_f(fabs(1.0 - factor_long) < 0.01,
+ "The GPU clock stopped ticking while the GPU was idle\n");
+}
+
igt_main
{
int fd = -1;
@@ -64,6 +142,9 @@ igt_main
igt_subtest("query-firmware-version")
query_firmware_version_test();
+ igt_subtest("query-timestamp")
+ query_timestamp_test();
+
igt_fixture {
amdgpu_device_deinitialize(dev);
close(fd);
--
2.30.1
More information about the igt-dev
mailing list