All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>
Cc: Metin Kaya <metikaya@amazon.com>
Subject: [PATCH kvm-unit-tests 13/13] x86: hyperv-v: Rewrite flaky hv_clock_test()
Date: Wed,  6 Mar 2024 18:18:23 +0100	[thread overview]
Message-ID: <20240306171823.761647-14-vkuznets@redhat.com> (raw)
In-Reply-To: <20240306171823.761647-1-vkuznets@redhat.com>

hv_clock_test() is reported to be flaky:
https://bugzilla.kernel.org/show_bug.cgi?id=217516

The test tries measuring the divergence between MSR based clock and TSC
page over one second and then expects delta to stay within the measured
range over another two seconds. This works well for a completely idle
system but if tasks get scheduled out, rescheduled to a different CPU,...
the test fails. Widening the expected range helps to certain extent but
even when the expected delta is "max_delta * 1024" sporadic failures still
occur.

Rewrite the test completely to make it stable. Check two things:
- MSR based and TSC page clocksources never go backwards.
- MSR based clocksource read between to TSC page reads stays within the
interval.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 x86/hyperv_clock.c | 55 +++++++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 22 deletions(-)

diff --git a/x86/hyperv_clock.c b/x86/hyperv_clock.c
index d0993bb75ac7..9061da8c6d2c 100644
--- a/x86/hyperv_clock.c
+++ b/x86/hyperv_clock.c
@@ -64,40 +64,51 @@ uint64_t loops[MAX_CPU];
 static void hv_clock_test(void *data)
 {
 	int i = (long)data;
-	uint64_t t = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
-	uint64_t end = t + 3 * TICKS_PER_SEC;
-	uint64_t msr_sample = t + TICKS_PER_SEC;
-	int min_delta = 123456, max_delta = -123456;
+	uint64_t t_msr_prev = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
+	uint64_t t_page_prev = hv_clock_read();
+	uint64_t end = t_page_prev + TICKS_PER_SEC;
 	bool got_drift = false;
-	bool got_warp = false;
+	bool got_warp_msr = false;
+	bool got_warp_page = false;
 
 	ok[i] = true;
 	do {
-		uint64_t now = hv_clock_read();
-		int delta = rdmsr(HV_X64_MSR_TIME_REF_COUNT) - now;
-
-		min_delta = delta < min_delta ? delta : min_delta;
-		if (t < msr_sample) {
-			max_delta = delta > max_delta ? delta: max_delta;
-		} else if (delta < 0 || delta > max_delta * 3 / 2) {
-			printf("suspecting drift on CPU %d? delta = %d, acceptable [0, %d)\n", i,
-			       delta, max_delta);
+		uint64_t t_page_1, t_page_2, t_msr;
+
+		t_page_1 = hv_clock_read();
+		barrier();
+		t_msr = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
+		barrier();
+		t_page_2 = hv_clock_read();
+
+		if (!got_drift && (t_msr < t_page_1 || t_msr > t_page_2)) {
+			printf("drift on CPU %d, MSR value = %ld, acceptable [%ld, %ld]\n", i,
+			       t_msr, t_page_1, t_page_2);
 			ok[i] = false;
 			got_drift = true;
-			max_delta *= 2;
 		}
 
-		if (now < t && !got_warp) {
-			printf("warp on CPU %d!\n", i);
+		if (!got_warp_msr && t_msr < t_msr_prev) {
+			printf("warp on CPU %d, MSR value = %ld prev MSR value = %ld!\n", i,
+			       t_msr, t_msr_prev);
 			ok[i] = false;
-			got_warp = true;
+			got_warp_msr = true;
 			break;
 		}
-		t = now;
-	} while(t < end);
 
-	if (!got_drift)
-		printf("delta on CPU %d was %d...%d\n", i, min_delta, max_delta);
+		if (!got_warp_page && t_page_1 < t_page_prev) {
+			printf("warp on CPU %d, TSC page value = %ld prev TSC page value = %ld!\n", i,
+			       t_page_1, t_page_prev);
+			ok[i] = false;
+			got_warp_page = true;
+			break;
+		}
+
+		t_page_prev = t_page_1;
+		t_msr_prev = t_msr;
+
+	} while(t_page_prev < end);
+
 	barrier();
 }
 
-- 
2.44.0


      parent reply	other threads:[~2024-03-06 17:18 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-06 17:18 [PATCH kvm-unit-tests 00/13] x86: hyperv-v: Various unmerged patches Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 01/13] x86: hyperv: Use correct macro in checking SynIC timer support Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 02/13] x86: hyperv: improve naming of stimer functions Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 03/13] x86: hyperv_clock: handle non-consecutive APIC IDs Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 04/13] x86: hyperv_clock: print sequence field of reference TSC page Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 05/13] x86: hyper-v: Use '-cpu host,hv_passhtrough' for Hyper-V tests Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 06/13] x86: hyper-v: Use report_skip() in hyperv_stimer when pre-requisites are not met Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 07/13] x86: hyper-v: Use 'goto' instead of putting the whole test in an 'if' branch in hyperv_synic Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 08/13] x86: hyper-v: Unify hyperv_clock with other Hyper-V tests Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 09/13] x86: hyperv_stimer: keep SINT number parameter in 'struct stimer' Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 10/13] x86: hyperv_stimer: define union hv_stimer_config Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 11/13] x86: hyperv_stimer: don't require hyperv-testdev Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 12/13] x86: hyperv_stimer: add direct mode tests Vitaly Kuznetsov
2024-03-06 17:18 ` Vitaly Kuznetsov [this message]

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=20240306171823.761647-14-vkuznets@redhat.com \
    --to=vkuznets@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=metikaya@amazon.com \
    --cc=pbonzini@redhat.com \
    /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.