* [PATCH 1/2] clocksource/hyperv: Untangle stimers and timesync from clocksources
2019-12-10 9:30 [PATCH 0/2] clocksource/hyperv: Miscellaneous changes Andrea Parri
@ 2019-12-10 9:30 ` Andrea Parri
2019-12-10 9:30 ` [PATCH 2/2] clocksource/hyperv: Set TSC clocksource as default w/ InvariantTSC Andrea Parri
2020-01-08 13:33 ` [PATCH 0/2] clocksource/hyperv: Miscellaneous changes Andrea Parri
2 siblings, 0 replies; 6+ messages in thread
From: Andrea Parri @ 2019-12-10 9:30 UTC (permalink / raw)
To: linux-kernel, linux-hyperv
Cc: K . Y . Srinivasan, Haiyang Zhang, Stephen Hemminger,
Sasha Levin, Daniel Lezcano, Thomas Gleixner, Michael Kelley,
Boqun Feng, Vitaly Kuznetsov, Andrea Parri
hyperv_timer.c exports hyperv_cs, which is used by stimers and the
timesync mechanism. However, the clocksource dependency is not
needed: these mechanisms only depend on the partition reference
counter (which can be read via a MSR or via the TSC Reference Page).
Introduce the (function) pointer hv_read_reference_counter, as an
embodiment of the partition reference counter read, and export it
in place of the hyperv_cs pointer. The latter can be removed.
This should clarify that there's no relationship between Hyper-V
stimers & timesync and the Linux clocksource abstractions. No
functional or semantic change.
Suggested-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
---
drivers/clocksource/hyperv_timer.c | 36 +++++++++++++++++++-----------
drivers/hv/hv_util.c | 8 +++----
include/clocksource/hyperv_timer.h | 2 +-
3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index b6ea3a2093c56..0eb528db4822d 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -66,7 +66,7 @@ static int hv_ce_set_next_event(unsigned long delta,
{
u64 current_tick;
- current_tick = hyperv_cs->read(NULL);
+ current_tick = hv_read_reference_counter();
current_tick += delta;
hv_init_timer(0, current_tick);
return 0;
@@ -304,8 +304,8 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
* Hyper-V and 32-bit x86. The TSC reference page version is preferred.
*/
-struct clocksource *hyperv_cs;
-EXPORT_SYMBOL_GPL(hyperv_cs);
+u64 (*hv_read_reference_counter)(void);
+EXPORT_SYMBOL_GPL(hv_read_reference_counter);
static union {
struct ms_hyperv_tsc_page page;
@@ -318,7 +318,7 @@ struct ms_hyperv_tsc_page *hv_get_tsc_page(void)
}
EXPORT_SYMBOL_GPL(hv_get_tsc_page);
-static u64 notrace read_hv_clock_tsc(struct clocksource *arg)
+static u64 notrace read_hv_clock_tsc(void)
{
u64 current_tick = hv_read_tsc_page(hv_get_tsc_page());
@@ -328,20 +328,25 @@ static u64 notrace read_hv_clock_tsc(struct clocksource *arg)
return current_tick;
}
+static u64 notrace read_hv_clock_tsc_cs(struct clocksource *arg)
+{
+ return read_hv_clock_tsc();
+}
+
static u64 read_hv_sched_clock_tsc(void)
{
- return read_hv_clock_tsc(NULL) - hv_sched_clock_offset;
+ return read_hv_clock_tsc() - hv_sched_clock_offset;
}
static struct clocksource hyperv_cs_tsc = {
.name = "hyperv_clocksource_tsc_page",
.rating = 400,
- .read = read_hv_clock_tsc,
+ .read = read_hv_clock_tsc_cs,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static u64 notrace read_hv_clock_msr(struct clocksource *arg)
+static u64 notrace read_hv_clock_msr(void)
{
u64 current_tick;
/*
@@ -353,15 +358,20 @@ static u64 notrace read_hv_clock_msr(struct clocksource *arg)
return current_tick;
}
+static u64 notrace read_hv_clock_msr_cs(struct clocksource *arg)
+{
+ return read_hv_clock_msr();
+}
+
static u64 read_hv_sched_clock_msr(void)
{
- return read_hv_clock_msr(NULL) - hv_sched_clock_offset;
+ return read_hv_clock_msr() - hv_sched_clock_offset;
}
static struct clocksource hyperv_cs_msr = {
.name = "hyperv_clocksource_msr",
.rating = 400,
- .read = read_hv_clock_msr,
+ .read = read_hv_clock_msr_cs,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -374,7 +384,7 @@ static bool __init hv_init_tsc_clocksource(void)
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
return false;
- hyperv_cs = &hyperv_cs_tsc;
+ hv_read_reference_counter = read_hv_clock_tsc;
phys_addr = virt_to_phys(hv_get_tsc_page());
/*
@@ -392,7 +402,7 @@ static bool __init hv_init_tsc_clocksource(void)
hv_set_clocksource_vdso(hyperv_cs_tsc);
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
- hv_sched_clock_offset = hyperv_cs->read(hyperv_cs);
+ hv_sched_clock_offset = hv_read_reference_counter();
hv_setup_sched_clock(read_hv_sched_clock_tsc);
return true;
@@ -414,10 +424,10 @@ void __init hv_init_clocksource(void)
if (!(ms_hyperv.features & HV_MSR_TIME_REF_COUNT_AVAILABLE))
return;
- hyperv_cs = &hyperv_cs_msr;
+ hv_read_reference_counter = read_hv_clock_msr;
clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
- hv_sched_clock_offset = hyperv_cs->read(hyperv_cs);
+ hv_sched_clock_offset = hv_read_reference_counter();
hv_setup_sched_clock(read_hv_sched_clock_msr);
}
EXPORT_SYMBOL_GPL(hv_init_clocksource);
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 766bd84573461..296f9098c9e46 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -211,7 +211,7 @@ static struct timespec64 hv_get_adj_host_time(void)
unsigned long flags;
spin_lock_irqsave(&host_ts.lock, flags);
- reftime = hyperv_cs->read(hyperv_cs);
+ reftime = hv_read_reference_counter();
newtime = host_ts.host_time + (reftime - host_ts.ref_time);
ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100);
spin_unlock_irqrestore(&host_ts.lock, flags);
@@ -250,7 +250,7 @@ static inline void adj_guesttime(u64 hosttime, u64 reftime, u8 adj_flags)
*/
spin_lock_irqsave(&host_ts.lock, flags);
- cur_reftime = hyperv_cs->read(hyperv_cs);
+ cur_reftime = hv_read_reference_counter();
host_ts.host_time = hosttime;
host_ts.ref_time = cur_reftime;
@@ -315,7 +315,7 @@ static void timesync_onchannelcallback(void *context)
sizeof(struct vmbuspipe_hdr) +
sizeof(struct icmsg_hdr)];
adj_guesttime(timedatap->parenttime,
- hyperv_cs->read(hyperv_cs),
+ hv_read_reference_counter(),
timedatap->flags);
}
}
@@ -524,7 +524,7 @@ static struct ptp_clock *hv_ptp_clock;
static int hv_timesync_init(struct hv_util_service *srv)
{
/* TimeSync requires Hyper-V clocksource. */
- if (!hyperv_cs)
+ if (!hv_read_reference_counter)
return -ENODEV;
spin_lock_init(&host_ts.lock);
diff --git a/include/clocksource/hyperv_timer.h b/include/clocksource/hyperv_timer.h
index 553e539469f04..34eef083c9882 100644
--- a/include/clocksource/hyperv_timer.h
+++ b/include/clocksource/hyperv_timer.h
@@ -30,7 +30,7 @@ extern void hv_stimer_global_cleanup(void);
extern void hv_stimer0_isr(void);
#ifdef CONFIG_HYPERV_TIMER
-extern struct clocksource *hyperv_cs;
+extern u64 (*hv_read_reference_counter)(void);
extern void hv_init_clocksource(void);
extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void);
--
2.24.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] clocksource/hyperv: Set TSC clocksource as default w/ InvariantTSC
2019-12-10 9:30 [PATCH 0/2] clocksource/hyperv: Miscellaneous changes Andrea Parri
2019-12-10 9:30 ` [PATCH 1/2] clocksource/hyperv: Untangle stimers and timesync from clocksources Andrea Parri
@ 2019-12-10 9:30 ` Andrea Parri
2020-01-08 13:33 ` [PATCH 0/2] clocksource/hyperv: Miscellaneous changes Andrea Parri
2 siblings, 0 replies; 6+ messages in thread
From: Andrea Parri @ 2019-12-10 9:30 UTC (permalink / raw)
To: linux-kernel, linux-hyperv
Cc: K . Y . Srinivasan, Haiyang Zhang, Stephen Hemminger,
Sasha Levin, Daniel Lezcano, Thomas Gleixner, Michael Kelley,
Boqun Feng, Vitaly Kuznetsov, Andrea Parri
Change the Hyper-V clocksource ratings to 250, below the TSC clocksource
rating of 300. In configurations where Hyper-V offers an InvariantTSC,
the TSC is not marked "unstable", so the TSC clocksource is available
and preferred. With the higher rating, it will be the default. On
older hardware and Hyper-V versions, the TSC is marked "unstable", so no
TSC clocksource is created and the selected Hyper-V clocksource will be
the default.
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
---
drivers/clocksource/hyperv_timer.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index 0eb528db4822d..6a92f945916d4 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -302,6 +302,14 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
* the other that uses the TSC reference page feature as defined in the
* TLFS. The MSR version is for compatibility with old versions of
* Hyper-V and 32-bit x86. The TSC reference page version is preferred.
+ *
+ * The Hyper-V clocksource ratings of 250 are chosen to be below the
+ * TSC clocksource rating of 300. In configurations where Hyper-V offers
+ * an InvariantTSC, the TSC is not marked "unstable", so the TSC clocksource
+ * is available and preferred. With the higher rating, it will be the
+ * default. On older hardware and Hyper-V versions, the TSC is marked
+ * "unstable", so no TSC clocksource is created and the selected Hyper-V
+ * clocksource will be the default.
*/
u64 (*hv_read_reference_counter)(void);
@@ -340,7 +348,7 @@ static u64 read_hv_sched_clock_tsc(void)
static struct clocksource hyperv_cs_tsc = {
.name = "hyperv_clocksource_tsc_page",
- .rating = 400,
+ .rating = 250,
.read = read_hv_clock_tsc_cs,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
@@ -370,7 +378,7 @@ static u64 read_hv_sched_clock_msr(void)
static struct clocksource hyperv_cs_msr = {
.name = "hyperv_clocksource_msr",
- .rating = 400,
+ .rating = 250,
.read = read_hv_clock_msr_cs,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
--
2.24.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] clocksource/hyperv: Miscellaneous changes
2019-12-10 9:30 [PATCH 0/2] clocksource/hyperv: Miscellaneous changes Andrea Parri
2019-12-10 9:30 ` [PATCH 1/2] clocksource/hyperv: Untangle stimers and timesync from clocksources Andrea Parri
2019-12-10 9:30 ` [PATCH 2/2] clocksource/hyperv: Set TSC clocksource as default w/ InvariantTSC Andrea Parri
@ 2020-01-08 13:33 ` Andrea Parri
2020-01-09 11:40 ` Daniel Lezcano
2 siblings, 1 reply; 6+ messages in thread
From: Andrea Parri @ 2020-01-08 13:33 UTC (permalink / raw)
To: linux-kernel, linux-hyperv
Cc: K . Y . Srinivasan, Haiyang Zhang, Stephen Hemminger,
Sasha Levin, Daniel Lezcano, Thomas Gleixner, Michael Kelley,
Boqun Feng, Vitaly Kuznetsov, Dexuan Cui
Thomas, Daniel,
On Tue, Dec 10, 2019 at 10:30:52AM +0100, Andrea Parri wrote:
> Provide some refactoring and adjustments to the Hyper-V clocksources
> code. Applies to -rc1 plus Boqun's:
>
> https://lkml.kernel.org/r/20191126021723.4710-1-boqun.feng@gmail.com
>
> Thanks,
> Andrea
>
> Andrea Parri (2):
> clocksource/hyperv: Untangle stimers and timesync from clocksources
> clocksource/hyperv: Set TSC clocksource as default w/ InvariantTSC
I'm wondering if you could route these patches via tip; for reference,
https://lkml.kernel.org/r/20191210093054.32230-1-parri.andrea@gmail.com
Both patches got Reviewed-by: Michael (even though I can't find his replies
on lore ATM).
Also, I realized that this series has a minor conflict with Dexuan's:
https://lkml.kernel.org/r/1578350617-130430-1-git-send-email-decui@microsoft.com
(added to Cc:); please let me know if a rebase/resend is needed.
Thanks,
Andrea
^ permalink raw reply [flat|nested] 6+ messages in thread