diff mbox series

[v2,10/38] clocksource: hyper-v: Don't save/restore TSC offset when using HV sched_clock

Message ID 20250227021855.3257188-11-seanjc@google.com (mailing list archive)
State New
Headers show
Series x86: Try to wrangle PV clocks vs. TSC | expand

Commit Message

Sean Christopherson Feb. 27, 2025, 2:18 a.m. UTC
Now that Hyper-V overrides the sched_clock save/restore hooks if and only
sched_clock itself is set to the Hyper-V timer, drop the invocation of the
"old" save/restore callbacks.  When the registration of the PV sched_clock
was done separate from overriding the save/restore hooks, it was possible
for Hyper-V to clobber the TSC save/restore callbacks without actually
switching to the Hyper-V timer.

Enabling a PV sched_clock is a one-way street, i.e. the kernel will never
revert to using TSC for sched_clock, and so there is no need to invoke the
TSC save/restore hooks (and if there was, it belongs in common PV code).

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 drivers/clocksource/hyperv_timer.c | 10 ----------
 1 file changed, 10 deletions(-)

Comments

Michael Kelley March 4, 2025, 4:17 a.m. UTC | #1
From: Sean Christopherson <seanjc@google.com> Sent: Wednesday, February 26, 2025 6:18 PM
> 
> Now that Hyper-V overrides the sched_clock save/restore hooks if and only
> sched_clock itself is set to the Hyper-V timer, drop the invocation of the
> "old" save/restore callbacks.  When the registration of the PV sched_clock
> was done separate from overriding the save/restore hooks, it was possible
> for Hyper-V to clobber the TSC save/restore callbacks without actually
> switching to the Hyper-V timer.

Terminology again.

> 
> Enabling a PV sched_clock is a one-way street, i.e. the kernel will never
> revert to using TSC for sched_clock, and so there is no need to invoke the
> TSC save/restore hooks (and if there was, it belongs in common PV code).
> 
> Signed-off-by: Sean Christopherson <seanjc@google.com>

I've tested the full patch series in a Hyper-V guest on x86 with
and without the Hyper-V TSC_INVARIANT option. In both cases,
the sched_clock is correctly maintained across hibernation and
resume from hibernation, and the "flags" in /proc/cpuinfo are
as expected. I also compiled hyperv_timer.c on arm64, and that is
clean with no errors. So all is good.

Modulo the terminology used in the commit message,

Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>

> ---
>  drivers/clocksource/hyperv_timer.c | 10 ----------
>  1 file changed, 10 deletions(-)
> 
> diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
> index 5a52d0acf31f..4a21874e91b9 100644
> --- a/drivers/clocksource/hyperv_timer.c
> +++ b/drivers/clocksource/hyperv_timer.c
> @@ -524,9 +524,6 @@ static __always_inline void hv_setup_sched_clock(void
> *sched_clock)
>  }
>  #elif defined CONFIG_PARAVIRT
>  static u64 hv_ref_counter_at_suspend;
> -static void (*old_save_sched_clock_state)(void);
> -static void (*old_restore_sched_clock_state)(void);
> -
>  /*
>   * Hyper-V clock counter resets during hibernation. Save and restore clock
>   * offset during suspend/resume, while also considering the time passed
> @@ -536,8 +533,6 @@ static void (*old_restore_sched_clock_state)(void);
>   */
>  static void hv_save_sched_clock_state(void)
>  {
> -	old_save_sched_clock_state();
> -
>  	hv_ref_counter_at_suspend = hv_read_reference_counter();
>  }
> 
> @@ -550,8 +545,6 @@ static void hv_restore_sched_clock_state(void)
>  	 *                - reference counter (time) now.
>  	 */
>  	hv_sched_clock_offset -= (hv_ref_counter_at_suspend - hv_read_reference_counter());
> -
> -	old_restore_sched_clock_state();
>  }
> 
>  static __always_inline void hv_setup_sched_clock(void *sched_clock)
> @@ -559,10 +552,7 @@ static __always_inline void hv_setup_sched_clock(void
> *sched_clock)
>  	/* We're on x86/x64 *and* using PV ops */
>  	paravirt_set_sched_clock(sched_clock);
> 
> -	old_save_sched_clock_state = x86_platform.save_sched_clock_state;
>  	x86_platform.save_sched_clock_state = hv_save_sched_clock_state;
> -
> -	old_restore_sched_clock_state = x86_platform.restore_sched_clock_state;
>  	x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state;
>  }
>  #else /* !CONFIG_GENERIC_SCHED_CLOCK && !CONFIG_PARAVIRT */
> --
> 2.48.1.711.g2feabab25a-goog
>
diff mbox series

Patch

diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index 5a52d0acf31f..4a21874e91b9 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -524,9 +524,6 @@  static __always_inline void hv_setup_sched_clock(void *sched_clock)
 }
 #elif defined CONFIG_PARAVIRT
 static u64 hv_ref_counter_at_suspend;
-static void (*old_save_sched_clock_state)(void);
-static void (*old_restore_sched_clock_state)(void);
-
 /*
  * Hyper-V clock counter resets during hibernation. Save and restore clock
  * offset during suspend/resume, while also considering the time passed
@@ -536,8 +533,6 @@  static void (*old_restore_sched_clock_state)(void);
  */
 static void hv_save_sched_clock_state(void)
 {
-	old_save_sched_clock_state();
-
 	hv_ref_counter_at_suspend = hv_read_reference_counter();
 }
 
@@ -550,8 +545,6 @@  static void hv_restore_sched_clock_state(void)
 	 *                - reference counter (time) now.
 	 */
 	hv_sched_clock_offset -= (hv_ref_counter_at_suspend - hv_read_reference_counter());
-
-	old_restore_sched_clock_state();
 }
 
 static __always_inline void hv_setup_sched_clock(void *sched_clock)
@@ -559,10 +552,7 @@  static __always_inline void hv_setup_sched_clock(void *sched_clock)
 	/* We're on x86/x64 *and* using PV ops */
 	paravirt_set_sched_clock(sched_clock);
 
-	old_save_sched_clock_state = x86_platform.save_sched_clock_state;
 	x86_platform.save_sched_clock_state = hv_save_sched_clock_state;
-
-	old_restore_sched_clock_state = x86_platform.restore_sched_clock_state;
 	x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state;
 }
 #else /* !CONFIG_GENERIC_SCHED_CLOCK && !CONFIG_PARAVIRT */