All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: bigeasy@linutronix.de
Cc: mark.rutland@arm.com, maz@kernel.org, catalin.marinas@arm.com,
	will@kernel.org, chenhuacai@kernel.org, kernel@xen0n.name,
	hca@linux.ibm.com, gor@linux.ibm.com, agordeev@linux.ibm.com,
	borntraeger@linux.ibm.com, svens@linux.ibm.com,
	pbonzini@redhat.com, wanpengli@tencent.com, vkuznets@redhat.com,
	tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com,
	jgross@suse.com, boris.ostrovsky@oracle.com,
	daniel.lezcano@linaro.org, kys@microsoft.com,
	haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com,
	rafael@kernel.org, peterz@infradead.org, longman@redhat.com,
	boqun.feng@gmail.com, pmladek@suse.com, senozhatsky@chromium.org,
	rostedt@goodmis.org, john.ogness@linutronix.de,
	juri.lelli@redhat.com, vincent.guittot@linaro.org,
	dietmar.eggemann@arm.com, bsegall@google.com, mgorman@suse.de,
	bristot@redhat.com, vschneid@redhat.com, jstultz@google.com,
	sboyd@kernel.org, linux-kernel@vger.kernel.org,
	loongarch@lists.linux.dev, linux-s390@vger.kernel.org,
	kvm@vger.kernel.org, linux-hyperv@vger.kernel.org,
	linux-pm@vger.kernel.org
Subject: [PATCH v2 09/13] clocksource: hyper-v: Adjust hv_read_tsc_page_tsc() to avoid special casing U64_MAX
Date: Fri, 19 May 2023 12:21:07 +0200	[thread overview]
Message-ID: <20230519102715.775630881@infradead.org> (raw)
In-Reply-To: 20230519102058.581557770@infradead.org

Currently hv_read_tsc_page_tsc() (ab)uses the (valid) time value of
U64_MAX as an error return. This breaks the clean wrap-around of the
clock.

Modify the function signature to return a boolean state and provide
another u64 pointer to store the actual time on success. This obviates
the need to steal one time value and restores the full counter width.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/include/asm/vdso/gettimeofday.h |   10 ++++++----
 arch/x86/kvm/x86.c                       |    7 +++----
 drivers/clocksource/hyperv_timer.c       |   16 +++++++++++-----
 include/clocksource/hyperv_timer.h       |   24 +++++++++---------------
 4 files changed, 29 insertions(+), 28 deletions(-)

--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -238,10 +238,12 @@ static u64 vread_pvclock(void)
 #ifdef CONFIG_HYPERV_TIMER
 static u64 vread_hvclock(void)
 {
-	u64 ret = hv_read_tsc_page(&hvclock_page);
-	if (likely(ret != U64_MAX))
-		ret &= S64_MAX;
-	return ret;
+	u64 tsc, time;
+
+	if (hv_read_tsc_page_tsc(&hvclock_page, &tsc, &time))
+		return time & S64_MAX;
+
+	return U64_MAX;
 }
 #endif
 
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2799,14 +2799,13 @@ static u64 read_tsc(void)
 static inline u64 vgettsc(struct pvclock_clock *clock, u64 *tsc_timestamp,
 			  int *mode)
 {
-	long v;
 	u64 tsc_pg_val;
+	long v;
 
 	switch (clock->vclock_mode) {
 	case VDSO_CLOCKMODE_HVCLOCK:
-		tsc_pg_val = hv_read_tsc_page_tsc(hv_get_tsc_page(),
-						  tsc_timestamp);
-		if (tsc_pg_val != U64_MAX) {
+		if (hv_read_tsc_page_tsc(hv_get_tsc_page(),
+					 tsc_timestamp, &tsc_pg_val)) {
 			/* TSC page valid */
 			*mode = VDSO_CLOCKMODE_HVCLOCK;
 			v = (tsc_pg_val - clock->cycle_last) &
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -393,14 +393,20 @@ struct ms_hyperv_tsc_page *hv_get_tsc_pa
 }
 EXPORT_SYMBOL_GPL(hv_get_tsc_page);
 
-static u64 notrace read_hv_clock_tsc(void)
+static notrace u64 read_hv_clock_tsc(void)
 {
-	u64 current_tick = hv_read_tsc_page(hv_get_tsc_page());
+	u64 cur_tsc, time;
 
-	if (current_tick == U64_MAX)
-		current_tick = hv_get_register(HV_REGISTER_TIME_REF_COUNT);
+	/*
+	 * The Hyper-V Top-Level Function Spec (TLFS), section Timers,
+	 * subsection Refererence Counter, guarantees that the TSC and MSR
+	 * times are in sync and monotonic. Therefore we can fall back
+	 * to the MSR in case the TSC page indicates unavailability.
+	 */
+	if (!hv_read_tsc_page_tsc(tsc_page, &cur_tsc, &time))
+		time = hv_get_register(HV_REGISTER_TIME_REF_COUNT);
 
-	return current_tick;
+	return time;
 }
 
 static u64 notrace read_hv_clock_tsc_cs(struct clocksource *arg)
--- a/include/clocksource/hyperv_timer.h
+++ b/include/clocksource/hyperv_timer.h
@@ -38,8 +38,9 @@ extern void hv_remap_tsc_clocksource(voi
 extern unsigned long hv_get_tsc_pfn(void);
 extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
 
-static inline notrace u64
-hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc)
+static __always_inline bool
+hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg,
+		     u64 *cur_tsc, u64 *time)
 {
 	u64 scale, offset;
 	u32 sequence;
@@ -63,7 +64,7 @@ hv_read_tsc_page_tsc(const struct ms_hyp
 	do {
 		sequence = READ_ONCE(tsc_pg->tsc_sequence);
 		if (!sequence)
-			return U64_MAX;
+			return false;
 		/*
 		 * Make sure we read sequence before we read other values from
 		 * TSC page.
@@ -82,15 +83,8 @@ hv_read_tsc_page_tsc(const struct ms_hyp
 
 	} while (READ_ONCE(tsc_pg->tsc_sequence) != sequence);
 
-	return mul_u64_u64_shr(*cur_tsc, scale, 64) + offset;
-}
-
-static inline notrace u64
-hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg)
-{
-	u64 cur_tsc;
-
-	return hv_read_tsc_page_tsc(tsc_pg, &cur_tsc);
+	*time = mul_u64_u64_shr(*cur_tsc, scale, 64) + offset;
+	return true;
 }
 
 #else /* CONFIG_HYPERV_TIMER */
@@ -104,10 +98,10 @@ static inline struct ms_hyperv_tsc_page
 	return NULL;
 }
 
-static inline u64 hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg,
-				       u64 *cur_tsc)
+static __always_inline bool
+hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc, u64 *time)
 {
-	return U64_MAX;
+	return false;
 }
 
 static inline int hv_stimer_cleanup(unsigned int cpu) { return 0; }



  parent reply	other threads:[~2023-05-19 10:33 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-19 10:20 [PATCH v2 00/13] local_clock() vs noinstr Peter Zijlstra
2023-05-19 10:20 ` [PATCH v2 01/13] seqlock/latch: Provide raw_read_seqcount_latch_retry() Peter Zijlstra
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 02/13] time/sched_clock: Provide sched_clock_noinstr() Peter Zijlstra
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 03/13] arm64/io: Always inline all of __raw_{read,write}[bwlq]() Peter Zijlstra
2023-05-24 16:40   ` Valentin Schneider
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 04/13] arm64/arch_timer: Provide noinstr sched_clock_read() functions Peter Zijlstra
2023-05-24 16:40   ` Valentin Schneider
2023-06-02 11:54     ` Peter Zijlstra
2023-06-07  8:58       ` Valentin Schneider
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-06-06  8:06     ` Peter Zijlstra
2023-06-06  8:13       ` Mark Rutland
2023-06-09  7:55       ` [tip: sched/core] arm64/arch_timer: Fix MMIO byteswap tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 05/13] loongarch: Provide noinstr sched_clock_read() Peter Zijlstra
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 06/13] s390/time: Provide sched_clock_noinstr() Peter Zijlstra
2023-05-22 14:18   ` Heiko Carstens
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 07/13] math64: Always inline u128 version of mul_u64_u64_shr() Peter Zijlstra
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 08/13] x86/vdso: Fix gettimeofday masking Peter Zijlstra
2023-05-31 15:27   ` Thomas Gleixner
2023-05-31 22:46     ` Thomas Gleixner
2023-05-31 22:46   ` Thomas Gleixner
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` Peter Zijlstra [this message]
2023-05-19 18:38   ` [PATCH v2 09/13] clocksource: hyper-v: Adjust hv_read_tsc_page_tsc() to avoid special casing U64_MAX Michael Kelley (LINUX)
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 10/13] clocksource: hyper-v: Provide noinstr sched_clock() Peter Zijlstra
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 11/13] x86/tsc: Provide sched_clock_noinstr() Peter Zijlstra
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 12/13] sched/clock: Provide local_clock_noinstr() Peter Zijlstra
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 10:21 ` [PATCH v2 13/13] cpuidle: Use local_clock_noinstr() Peter Zijlstra
2023-05-19 14:13   ` Rafael J. Wysocki
2023-06-05 19:16   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2023-05-19 18:48 ` [PATCH v2 00/13] local_clock() vs noinstr Michael Kelley (LINUX)

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=20230519102715.775630881@infradead.org \
    --to=peterz@infradead.org \
    --cc=agordeev@linux.ibm.com \
    --cc=bigeasy@linutronix.de \
    --cc=boqun.feng@gmail.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=bp@alien8.de \
    --cc=bristot@redhat.com \
    --cc=bsegall@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=chenhuacai@kernel.org \
    --cc=daniel.lezcano@linaro.org \
    --cc=dave.hansen@linux.intel.com \
    --cc=decui@microsoft.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=gor@linux.ibm.com \
    --cc=haiyangz@microsoft.com \
    --cc=hca@linux.ibm.com \
    --cc=hpa@zytor.com \
    --cc=jgross@suse.com \
    --cc=john.ogness@linutronix.de \
    --cc=jstultz@google.com \
    --cc=juri.lelli@redhat.com \
    --cc=kernel@xen0n.name \
    --cc=kvm@vger.kernel.org \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=loongarch@lists.linux.dev \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=pmladek@suse.com \
    --cc=rafael@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=sboyd@kernel.org \
    --cc=senozhatsky@chromium.org \
    --cc=svens@linux.ibm.com \
    --cc=tglx@linutronix.de \
    --cc=vincent.guittot@linaro.org \
    --cc=vkuznets@redhat.com \
    --cc=vschneid@redhat.com \
    --cc=wanpengli@tencent.com \
    --cc=wei.liu@kernel.org \
    --cc=will@kernel.org \
    --cc=x86@kernel.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.