Skip to content

Commit e0cd2fc

Browse files
kelleymhtyhicks
authored andcommitted
clocksource/drivers/hyper-v: Set clocksource rating based on Hyper-V feature
On x86/x64, the TSC clocksource is available in a Hyper-V VM only if Hyper-V provides the TSC_INVARIANT flag. The rating on the Hyper-V Reference TSC page clocksource is currently set so that it will not override the TSC clocksource in this case. Alternatively, if the TSC clocksource is not available, then the Hyper-V clocksource is used. But on ARM64, the Hyper-V Reference TSC page clocksource should override the ARM arch counter, since the Hyper-V clocksource provides scaling and offsetting during live migrations that is not provided for the ARM arch counter. To get the needed behavior for both x86/x64 and ARM64, tweak the logic by defaulting the Hyper-V Reference TSC page clocksource rating to a large value that will always override. If the Hyper-V TSC_INVARIANT flag is set, then reduce the rating so that it will not override the TSC. While the logic for getting there is slightly different, the net result in the normal cases is no functional change. Signed-off-by: Michael Kelley <mikelley@microsoft.com> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/1614721102-2241-10-git-send-email-mikelley@microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org> (cherry picked from commit 4c78738) Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
1 parent 4980a30 commit e0cd2fc

1 file changed

Lines changed: 13 additions & 10 deletions

File tree

drivers/clocksource/hyperv_timer.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,6 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
302302
* the other that uses the TSC reference page feature as defined in the
303303
* TLFS. The MSR version is for compatibility with old versions of
304304
* Hyper-V and 32-bit x86. The TSC reference page version is preferred.
305-
*
306-
* The Hyper-V clocksource ratings of 250 are chosen to be below the
307-
* TSC clocksource rating of 300. In configurations where Hyper-V offers
308-
* an InvariantTSC, the TSC is not marked "unstable", so the TSC clocksource
309-
* is available and preferred. With the higher rating, it will be the
310-
* default. On older hardware and Hyper-V versions, the TSC is marked
311-
* "unstable", so no TSC clocksource is created and the selected Hyper-V
312-
* clocksource will be the default.
313305
*/
314306

315307
u64 (*hv_read_reference_counter)(void);
@@ -380,7 +372,7 @@ static int hv_cs_enable(struct clocksource *cs)
380372

381373
static struct clocksource hyperv_cs_tsc = {
382374
.name = "hyperv_clocksource_tsc_page",
383-
.rating = 250,
375+
.rating = 500,
384376
.read = read_hv_clock_tsc_cs,
385377
.mask = CLOCKSOURCE_MASK(64),
386378
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
@@ -417,7 +409,7 @@ static u64 notrace read_hv_sched_clock_msr(void)
417409

418410
static struct clocksource hyperv_cs_msr = {
419411
.name = "hyperv_clocksource_msr",
420-
.rating = 250,
412+
.rating = 500,
421413
.read = read_hv_clock_msr_cs,
422414
.mask = CLOCKSOURCE_MASK(64),
423415
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
@@ -455,6 +447,17 @@ static bool __init hv_init_tsc_clocksource(void)
455447
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
456448
return false;
457449

450+
/*
451+
* If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly
452+
* handles frequency and offset changes due to live migration,
453+
* pause/resume, and other VM management operations. So lower the
454+
* Hyper-V Reference TSC rating, causing the generic TSC to be used.
455+
* TSC_INVARIANT is not offered on ARM64, so the Hyper-V Reference
456+
* TSC will be preferred over the virtualized ARM64 arch counter.
457+
*/
458+
if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT)
459+
hyperv_cs_tsc.rating = 250;
460+
458461
hv_read_reference_counter = read_hv_clock_tsc;
459462
phys_addr = virt_to_phys(hv_get_tsc_page());
460463

0 commit comments

Comments
 (0)