* [patch 01/15] lib/vdso: Make __arch_update_vdso_data() logic understandable
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-17 15:07 ` [tip: timers/urgent] " tip-bot2 for Thomas Gleixner
2020-01-14 18:52 ` [patch 02/15] lib/vdso: Update coarse timekeeper unconditionally Thomas Gleixner
` (13 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
The function name suggests that this is a boolean checking whether the
architecture asks for an update of the VDSO data, but it works the other
way round. To spare further confusion invert the logic.
Fixes: 44f57d788e7d ("timekeeping: Provide a generic update_vsyscall() implementation")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/arm/include/asm/vdso/vsyscall.h | 4 ++--
include/asm-generic/vdso/vsyscall.h | 4 ++--
kernel/time/vsyscall.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
--- a/arch/arm/include/asm/vdso/vsyscall.h
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -34,9 +34,9 @@ struct vdso_data *__arm_get_k_vdso_data(
#define __arch_get_k_vdso_data __arm_get_k_vdso_data
static __always_inline
-int __arm_update_vdso_data(void)
+bool __arm_update_vdso_data(void)
{
- return !cntvct_ok;
+ return cntvct_ok;
}
#define __arch_update_vdso_data __arm_update_vdso_data
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -12,9 +12,9 @@ static __always_inline struct vdso_data
#endif /* __arch_get_k_vdso_data */
#ifndef __arch_update_vdso_data
-static __always_inline int __arch_update_vdso_data(void)
+static __always_inline bool __arch_update_vdso_data(void)
{
- return 0;
+ return true;
}
#endif /* __arch_update_vdso_data */
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -84,7 +84,7 @@ void update_vsyscall(struct timekeeper *
struct vdso_timestamp *vdso_ts;
u64 nsec;
- if (__arch_update_vdso_data()) {
+ if (!__arch_update_vdso_data()) {
/*
* Some architectures might want to skip the update of the
* data page.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [tip: timers/urgent] lib/vdso: Make __arch_update_vdso_data() logic understandable
2020-01-14 18:52 ` [patch 01/15] lib/vdso: Make __arch_update_vdso_data() logic understandable Thomas Gleixner
@ 2020-01-17 15:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2020-01-17 15:07 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, x86, LKML
The following commit has been merged into the timers/urgent branch of tip:
Commit-ID: 9a6b55ac4a44060bcb782baf002859b2a2c63267
Gitweb: https://git.kernel.org/tip/9a6b55ac4a44060bcb782baf002859b2a2c63267
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 14 Jan 2020 19:52:38 +01:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 17 Jan 2020 15:53:50 +01:00
lib/vdso: Make __arch_update_vdso_data() logic understandable
The function name suggests that this is a boolean checking whether the
architecture asks for an update of the VDSO data, but it works the other
way round. To spare further confusion invert the logic.
Fixes: 44f57d788e7d ("timekeeping: Provide a generic update_vsyscall() implementation")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20200114185946.656652824@linutronix.de
---
arch/arm/include/asm/vdso/vsyscall.h | 4 ++--
include/asm-generic/vdso/vsyscall.h | 4 ++--
kernel/time/vsyscall.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/include/asm/vdso/vsyscall.h b/arch/arm/include/asm/vdso/vsyscall.h
index c4166f3..cff87d8 100644
--- a/arch/arm/include/asm/vdso/vsyscall.h
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -34,9 +34,9 @@ struct vdso_data *__arm_get_k_vdso_data(void)
#define __arch_get_k_vdso_data __arm_get_k_vdso_data
static __always_inline
-int __arm_update_vdso_data(void)
+bool __arm_update_vdso_data(void)
{
- return !cntvct_ok;
+ return cntvct_ok;
}
#define __arch_update_vdso_data __arm_update_vdso_data
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
index ce41032..cec543d 100644
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -12,9 +12,9 @@ static __always_inline struct vdso_data *__arch_get_k_vdso_data(void)
#endif /* __arch_get_k_vdso_data */
#ifndef __arch_update_vdso_data
-static __always_inline int __arch_update_vdso_data(void)
+static __always_inline bool __arch_update_vdso_data(void)
{
- return 0;
+ return true;
}
#endif /* __arch_update_vdso_data */
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index 5ee0f77..f0aab61 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -84,7 +84,7 @@ void update_vsyscall(struct timekeeper *tk)
struct vdso_timestamp *vdso_ts;
u64 nsec;
- if (__arch_update_vdso_data()) {
+ if (!__arch_update_vdso_data()) {
/*
* Some architectures might want to skip the update of the
* data page.
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [patch 02/15] lib/vdso: Update coarse timekeeper unconditionally
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
2020-01-14 18:52 ` [patch 01/15] lib/vdso: Make __arch_update_vdso_data() logic understandable Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-17 15:07 ` [tip: timers/urgent] " tip-bot2 for Thomas Gleixner
2020-01-14 18:52 ` [patch 03/15] ARM: vdso: Remove unused function Thomas Gleixner
` (12 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
The low resolution parts of the VDSO, i.e.:
clock_gettime(CLOCK_*_COARSE)
clock_getres()
time()
can be used even if there is no VDSO capable clocksource. But if an
architecture opts out of the VDSO data update then this information
becomes stale. This affects ARM when there is no architected timer
available. The lack of update causes userspace to use stale data
forever.
Make the update of the low resolution parts unconditional and only
prevent the update of the high resolution parts if the architecture
requests it.
Fixes: 44f57d788e7d ("timekeeping: Provide a generic update_vsyscall() implementation")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/time/vsyscall.c | 37 +++++++++++++++++--------------------
1 file changed, 17 insertions(+), 20 deletions(-)
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -28,11 +28,6 @@ static inline void update_vdso_data(stru
vdata[CS_RAW].mult = tk->tkr_raw.mult;
vdata[CS_RAW].shift = tk->tkr_raw.shift;
- /* CLOCK_REALTIME */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
- vdso_ts->sec = tk->xtime_sec;
- vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
-
/* CLOCK_MONOTONIC */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
@@ -70,12 +65,6 @@ static inline void update_vdso_data(stru
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI];
vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset;
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
-
- /*
- * Read without the seqlock held by clock_getres().
- * Note: No need to have a second copy.
- */
- WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
}
void update_vsyscall(struct timekeeper *tk)
@@ -84,20 +73,17 @@ void update_vsyscall(struct timekeeper *
struct vdso_timestamp *vdso_ts;
u64 nsec;
- if (!__arch_update_vdso_data()) {
- /*
- * Some architectures might want to skip the update of the
- * data page.
- */
- return;
- }
-
/* copy vsyscall data */
vdso_write_begin(vdata);
vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
+ /* CLOCK_REALTIME also required for time() */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
+ vdso_ts->sec = tk->xtime_sec;
+ vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
+
/* CLOCK_REALTIME_COARSE */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE];
vdso_ts->sec = tk->xtime_sec;
@@ -110,7 +96,18 @@ void update_vsyscall(struct timekeeper *
nsec = nsec + tk->wall_to_monotonic.tv_nsec;
vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &vdso_ts->nsec);
- update_vdso_data(vdata, tk);
+ /*
+ * Read without the seqlock held by clock_getres().
+ * Note: No need to have a second copy.
+ */
+ WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
+
+ /*
+ * Architectures can opt out of updating the high resolution part
+ * of the VDSO.
+ */
+ if (__arch_update_vdso_data())
+ update_vdso_data(vdata, tk);
__arch_update_vsyscall(vdata, tk);
^ permalink raw reply [flat|nested] 25+ messages in thread
* [tip: timers/urgent] lib/vdso: Update coarse timekeeper unconditionally
2020-01-14 18:52 ` [patch 02/15] lib/vdso: Update coarse timekeeper unconditionally Thomas Gleixner
@ 2020-01-17 15:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2020-01-17 15:07 UTC (permalink / raw)
To: linux-tip-commits; +Cc: Thomas Gleixner, x86, LKML
The following commit has been merged into the timers/urgent branch of tip:
Commit-ID: 9f24c540f7f8eb3a981528da9a9a636a5bdf5987
Gitweb: https://git.kernel.org/tip/9f24c540f7f8eb3a981528da9a9a636a5bdf5987
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 14 Jan 2020 19:52:39 +01:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 17 Jan 2020 15:53:50 +01:00
lib/vdso: Update coarse timekeeper unconditionally
The low resolution parts of the VDSO, i.e.:
clock_gettime(CLOCK_*_COARSE), clock_getres(), time()
can be used even if there is no VDSO capable clocksource.
But if an architecture opts out of the VDSO data update then this
information becomes stale. This affects ARM when there is no architected
timer available. The lack of update causes userspace to use stale data
forever.
Make the update of the low resolution parts unconditional and only skip
the update of the high resolution parts if the architecture requests it.
Fixes: 44f57d788e7d ("timekeeping: Provide a generic update_vsyscall() implementation")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20200114185946.765577901@linutronix.de
---
kernel/time/vsyscall.c | 37 +++++++++++++++++--------------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index f0aab61..9577c89 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -28,11 +28,6 @@ static inline void update_vdso_data(struct vdso_data *vdata,
vdata[CS_RAW].mult = tk->tkr_raw.mult;
vdata[CS_RAW].shift = tk->tkr_raw.shift;
- /* CLOCK_REALTIME */
- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
- vdso_ts->sec = tk->xtime_sec;
- vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
-
/* CLOCK_MONOTONIC */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec;
@@ -70,12 +65,6 @@ static inline void update_vdso_data(struct vdso_data *vdata,
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI];
vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset;
vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
-
- /*
- * Read without the seqlock held by clock_getres().
- * Note: No need to have a second copy.
- */
- WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
}
void update_vsyscall(struct timekeeper *tk)
@@ -84,20 +73,17 @@ void update_vsyscall(struct timekeeper *tk)
struct vdso_timestamp *vdso_ts;
u64 nsec;
- if (!__arch_update_vdso_data()) {
- /*
- * Some architectures might want to skip the update of the
- * data page.
- */
- return;
- }
-
/* copy vsyscall data */
vdso_write_begin(vdata);
vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
+ /* CLOCK_REALTIME also required for time() */
+ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
+ vdso_ts->sec = tk->xtime_sec;
+ vdso_ts->nsec = tk->tkr_mono.xtime_nsec;
+
/* CLOCK_REALTIME_COARSE */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE];
vdso_ts->sec = tk->xtime_sec;
@@ -110,7 +96,18 @@ void update_vsyscall(struct timekeeper *tk)
nsec = nsec + tk->wall_to_monotonic.tv_nsec;
vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &vdso_ts->nsec);
- update_vdso_data(vdata, tk);
+ /*
+ * Read without the seqlock held by clock_getres().
+ * Note: No need to have a second copy.
+ */
+ WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
+
+ /*
+ * Architectures can opt out of updating the high resolution part
+ * of the VDSO.
+ */
+ if (__arch_update_vdso_data())
+ update_vdso_data(vdata, tk);
__arch_update_vsyscall(vdata, tk);
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [patch 03/15] ARM: vdso: Remove unused function
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
2020-01-14 18:52 ` [patch 01/15] lib/vdso: Make __arch_update_vdso_data() logic understandable Thomas Gleixner
2020-01-14 18:52 ` [patch 02/15] lib/vdso: Update coarse timekeeper unconditionally Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 04/15] lib/vdso: Allow the high resolution parts to be compiled out Thomas Gleixner
` (11 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
The function is nowhere used. Aside of that this check should only cover
the high resolution parts of the VDSO which require a VDSO capable
clocksource and not the complete functionality as the name suggests. Will
be replaced with something more useful.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/arm/include/asm/vdso/vsyscall.h | 7 -------
1 file changed, 7 deletions(-)
--- a/arch/arm/include/asm/vdso/vsyscall.h
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -50,13 +50,6 @@ int __arm_get_clock_mode(struct timekeep
#define __arch_get_clock_mode __arm_get_clock_mode
static __always_inline
-int __arm_use_vsyscall(struct vdso_data *vdata)
-{
- return vdata[CS_HRES_COARSE].clock_mode;
-}
-#define __arch_use_vsyscall __arm_use_vsyscall
-
-static __always_inline
void __arm_sync_vdso_data(struct vdso_data *vdata)
{
flush_dcache_page(virt_to_page(vdata));
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 04/15] lib/vdso: Allow the high resolution parts to be compiled out
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (2 preceding siblings ...)
2020-01-14 18:52 ` [patch 03/15] ARM: vdso: Remove unused function Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 05/15] ARM: vdso: Compile high resolution parts conditionally Thomas Gleixner
` (10 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
If the architecture knows at compile time that there is no VDSO capable
clocksource supported it makes sense to optimize the guts of the high
resolution parts of the VDSO out at build time. Add a helper function to
check whether the VDSO should be high resolution capable and provide a stub
which can be overridden by an architecture.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
lib/vdso/gettimeofday.c | 11 +++++++++++
1 file changed, 11 insertions(+)
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -38,6 +38,13 @@ u64 vdso_calc_delta(u64 cycles, u64 last
}
#endif
+#ifndef __arch_vdso_hres_capable
+static inline bool __arch_vdso_hres_capable(void)
+{
+ return true;
+}
+#endif
+
#ifdef CONFIG_TIME_NS
static int do_hres_timens(const struct vdso_data *vdns, clockid_t clk,
struct __kernel_timespec *ts)
@@ -101,6 +108,10 @@ static __always_inline int do_hres(const
u64 cycles, last, sec, ns;
u32 seq;
+ /* Allows to compile the high resilution parts out */
+ if (!__arch_vdso_hres_capable())
+ return -1;
+
do {
/*
* Open coded to handle VCLOCK_TIMENS. Time namespace
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 05/15] ARM: vdso: Compile high resolution parts conditionally
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (3 preceding siblings ...)
2020-01-14 18:52 ` [patch 04/15] lib/vdso: Allow the high resolution parts to be compiled out Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 06/15] MIPS: " Thomas Gleixner
` (9 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
If the architected timer is disabled in the kernel configuration then let
the core VDSO code drop the high resolution parts at compile time.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/arm/include/asm/vdso/gettimeofday.h | 6 ++++++
1 file changed, 6 insertions(+)
--- a/arch/arm/include/asm/vdso/gettimeofday.h
+++ b/arch/arm/include/asm/vdso/gettimeofday.h
@@ -106,6 +106,12 @@ static __always_inline int clock_getres3
return ret;
}
+static inline bool arm_vdso_hres_capable(void)
+{
+ return IS_ENABLED(CONFIG_ARM_ARCH_TIMER);
+}
+#define __arch_vdso_hres_capable arm_vdso_hres_capable
+
static __always_inline u64 __arch_get_hw_counter(int clock_mode)
{
#ifdef CONFIG_ARM_ARCH_TIMER
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 06/15] MIPS: vdso: Compile high resolution parts conditionally
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (4 preceding siblings ...)
2020-01-14 18:52 ` [patch 05/15] ARM: vdso: Compile high resolution parts conditionally Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 07/15] clocksource: Cleanup struct clocksource and documentation Thomas Gleixner
` (8 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
If neither the R4K nor the GIC timer is enabled in the kernel configuration
then let the core VDSO code drop the high resolution parts at compile time.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/mips/include/asm/vdso/gettimeofday.h | 7 +++++++
1 file changed, 7 insertions(+)
--- a/arch/mips/include/asm/vdso/gettimeofday.h
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -199,6 +199,13 @@ static __always_inline u64 __arch_get_hw
return cycle_now;
}
+static inline bool mips_vdso_hres_capable(void)
+{
+ return IS_ENABLED(CONFIG_CSRC_R4K) ||
+ IS_ENABLED(CONFIG_CLKSRC_MIPS_GIC);
+}
+#define __arch_vdso_hres_capable mips_vdso_hres_capable
+
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
{
return get_vdso_data();
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 07/15] clocksource: Cleanup struct clocksource and documentation
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (5 preceding siblings ...)
2020-01-14 18:52 ` [patch 06/15] MIPS: " Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 08/15] x86/vdso: Move VDSO clocksource state tracking to callback Thomas Gleixner
` (7 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
Reformat the struct definition, add missing member documentation.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/clocksource.h | 87 +++++++++++++++++++++++---------------------
1 file changed, 47 insertions(+), 40 deletions(-)
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -32,9 +32,19 @@ struct module;
* Provides mostly state-free accessors to the underlying hardware.
* This is the structure used for system time.
*
- * @name: ptr to clocksource name
- * @list: list head for registration
- * @rating: rating value for selection (higher is better)
+ * @read: Returns a cycle value, passes clocksource as argument
+ * @mask: Bitmask for two's complement
+ * subtraction of non 64 bit counters
+ * @mult: Cycle to nanosecond multiplier
+ * @shift: Cycle to nanosecond divisor (power of two)
+ * @max_idle_ns: Maximum idle time permitted by the clocksource (nsecs)
+ * @maxadj: Maximum adjustment value to mult (~11%)
+ * @archdata: Optional arch-specific data
+ * @max_cycles: Maximum safe cycle value which won't overflow on
+ * multiplication
+ * @name: Pointer to clocksource name
+ * @list: List head for registration (internal)
+ * @rating: Rating value for selection (higher is better)
* To avoid rating inflation the following
* list should give you a guide as to how
* to assign your clocksource a rating
@@ -49,27 +59,23 @@ struct module;
* 400-499: Perfect
* The ideal clocksource. A must-use where
* available.
- * @read: returns a cycle value, passes clocksource as argument
- * @enable: optional function to enable the clocksource
- * @disable: optional function to disable the clocksource
- * @mask: bitmask for two's complement
- * subtraction of non 64 bit counters
- * @mult: cycle to nanosecond multiplier
- * @shift: cycle to nanosecond divisor (power of two)
- * @max_idle_ns: max idle time permitted by the clocksource (nsecs)
- * @maxadj: maximum adjustment value to mult (~11%)
- * @max_cycles: maximum safe cycle value which won't overflow on multiplication
- * @flags: flags describing special properties
- * @archdata: arch-specific data
- * @suspend: suspend function for the clocksource, if necessary
- * @resume: resume function for the clocksource, if necessary
+ * @flags: Flags describing special properties
+ * @enable: Optional function to enable the clocksource
+ * @disable: Optional function to disable the clocksource
+ * @suspend: Optional suspend function for the clocksource
+ * @resume: Optional resume function for the clocksource
* @mark_unstable: Optional function to inform the clocksource driver that
* the watchdog marked the clocksource unstable
- * @owner: module reference, must be set by clocksource in modules
+ * @tick_stable: Optional function called periodically from the watchdog
+ * code to provide stable syncrhonization points
+ * @wd_list: List head to enqueue into the watchdog list (internal)
+ * @cs_last: Last clocksource value for clocksource watchdog
+ * @wd_last: Last watchdog value corresponding to @cs_last
+ * @owner: Module reference, must be set by clocksource in modules
*
* Note: This struct is not used in hotpathes of the timekeeping code
* because the timekeeper caches the hot path fields in its own data
- * structure, so no line cache alignment is required,
+ * structure, so no cache line alignment is required,
*
* The pointer to the clocksource itself is handed to the read
* callback. If you need extra information there you can wrap struct
@@ -78,35 +84,36 @@ struct module;
* structure.
*/
struct clocksource {
- u64 (*read)(struct clocksource *cs);
- u64 mask;
- u32 mult;
- u32 shift;
- u64 max_idle_ns;
- u32 maxadj;
+ u64 (*read)(struct clocksource *cs);
+ u64 mask;
+ u32 mult;
+ u32 shift;
+ u64 max_idle_ns;
+ u32 maxadj;
#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
struct arch_clocksource_data archdata;
#endif
- u64 max_cycles;
- const char *name;
- struct list_head list;
- int rating;
- int (*enable)(struct clocksource *cs);
- void (*disable)(struct clocksource *cs);
- unsigned long flags;
- void (*suspend)(struct clocksource *cs);
- void (*resume)(struct clocksource *cs);
- void (*mark_unstable)(struct clocksource *cs);
- void (*tick_stable)(struct clocksource *cs);
+ u64 max_cycles;
+ const char *name;
+ struct list_head list;
+ int rating;
+ unsigned long flags;
+
+ int (*enable)(struct clocksource *cs);
+ void (*disable)(struct clocksource *cs);
+ void (*suspend)(struct clocksource *cs);
+ void (*resume)(struct clocksource *cs);
+ void (*mark_unstable)(struct clocksource *cs);
+ void (*tick_stable)(struct clocksource *cs);
/* private: */
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
/* Watchdog related data, used by the framework */
- struct list_head wd_list;
- u64 cs_last;
- u64 wd_last;
+ struct list_head wd_list;
+ u64 cs_last;
+ u64 wd_last;
#endif
- struct module *owner;
+ struct module *owner;
};
/*
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 08/15] x86/vdso: Move VDSO clocksource state tracking to callback
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (6 preceding siblings ...)
2020-01-14 18:52 ` [patch 07/15] clocksource: Cleanup struct clocksource and documentation Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-15 5:56 ` Jürgen Groß
2020-01-20 1:42 ` Michael Kelley
2020-01-14 18:52 ` [patch 09/15] clocksource: Add common vdso clock mode storage Thomas Gleixner
` (6 subsequent siblings)
14 siblings, 2 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
All architectures which use the generic VDSO code have their own storage
for the VDSO clock mode. That's pointless and just requires duplicate code.
X86 abuses the function which retrieves the architecture specific clock
mode storage to mark the clocksource as used in the VDSO. That's silly
because this is invoked on every tick when the VDSO data is updated.
Move this functionality to the clocksource::enable() callback so it gets
invoked once when the clocksource is installed. This allows to make the
clock mode storage generic.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Sasha Levin <sashal@kernel.org>
---
arch/x86/entry/vdso/vma.c | 4 ++++
arch/x86/include/asm/clocksource.h | 12 ++++++++++++
arch/x86/include/asm/mshyperv.h | 2 ++
arch/x86/include/asm/vdso/vsyscall.h | 10 +---------
arch/x86/include/asm/vgtod.h | 6 ------
arch/x86/kernel/kvmclock.c | 7 +++++++
arch/x86/kernel/tsc.c | 32 ++++++++++++++++++++------------
arch/x86/xen/time.c | 17 ++++++++++++-----
drivers/clocksource/hyperv_timer.c | 7 +++++++
9 files changed, 65 insertions(+), 32 deletions(-)
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -38,6 +38,8 @@ struct vdso_data *arch_get_vdso_data(voi
}
#undef EMIT_VVAR
+unsigned int vclocks_used __read_mostly;
+
#if defined(CONFIG_X86_64)
unsigned int __read_mostly vdso64_enabled = 1;
#endif
@@ -445,6 +447,8 @@ static __init int vdso_setup(char *s)
static int __init init_vdso(void)
{
+ BUILD_BUG_ON(VCLOCK_MAX >= 32);
+
init_vdso_image(&vdso_image_64);
#ifdef CONFIG_X86_X32_ABI
--- a/arch/x86/include/asm/clocksource.h
+++ b/arch/x86/include/asm/clocksource.h
@@ -14,4 +14,16 @@ struct arch_clocksource_data {
int vclock_mode;
};
+extern unsigned int vclocks_used;
+
+static inline bool vclock_was_used(int vclock)
+{
+ return READ_ONCE(vclocks_used) & (1U << vclock);
+}
+
+static inline void vclocks_set_used(unsigned int which)
+{
+ WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << which));
+}
+
#endif /* _ASM_X86_CLOCKSOURCE_H */
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -47,6 +47,8 @@ typedef int (*hyperv_fill_flush_list_fun
wrmsrl(HV_X64_MSR_REFERENCE_TSC, val)
#define hv_set_clocksource_vdso(val) \
((val).archdata.vclock_mode = VCLOCK_HVCLOCK)
+#define hv_enable_vdso_clocksource() \
+ vclocks_set_used(VCLOCK_HVCLOCK);
#define hv_get_raw_timer() rdtsc_ordered()
void hyperv_callback_vector(void);
--- a/arch/x86/include/asm/vdso/vsyscall.h
+++ b/arch/x86/include/asm/vdso/vsyscall.h
@@ -10,8 +10,6 @@
#include <asm/vgtod.h>
#include <asm/vvar.h>
-int vclocks_used __read_mostly;
-
DEFINE_VVAR(struct vdso_data, _vdso_data);
/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
@@ -26,13 +24,7 @@ struct vdso_data *__x86_get_k_vdso_data(
static __always_inline
int __x86_get_clock_mode(struct timekeeper *tk)
{
- int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
-
- /* Mark the new vclock used. */
- BUILD_BUG_ON(VCLOCK_MAX >= 32);
- WRITE_ONCE(vclocks_used, READ_ONCE(vclocks_used) | (1 << vclock_mode));
-
- return vclock_mode;
+ return tk->tkr_mono.clock->archdata.vclock_mode;
}
#define __arch_get_clock_mode __x86_get_clock_mode
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -15,10 +15,4 @@ typedef u64 gtod_long_t;
typedef unsigned long gtod_long_t;
#endif
-extern int vclocks_used;
-static inline bool vclock_was_used(int vclock)
-{
- return READ_ONCE(vclocks_used) & (1 << vclock);
-}
-
#endif /* _ASM_X86_VGTOD_H */
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -159,12 +159,19 @@ bool kvm_check_and_clear_guest_paused(vo
return ret;
}
+static int kvm_cs_enable(struct clocksource *cs)
+{
+ vclocks_set_used(VCLOCK_PVCLOCK);
+ return 0;
+}
+
struct clocksource kvm_clock = {
.name = "kvm-clock",
.read = kvm_clock_get_cycles,
.rating = 400,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .enable = kvm_cs_enable,
};
EXPORT_SYMBOL_GPL(kvm_clock);
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1108,17 +1108,24 @@ static void tsc_cs_tick_stable(struct cl
sched_clock_tick_stable();
}
+static int tsc_cs_enable(struct clocksource *cs)
+{
+ vclocks_set_used(VCLOCK_TSC);
+ return 0;
+}
+
/*
* .mask MUST be CLOCKSOURCE_MASK(64). See comment above read_tsc()
*/
static struct clocksource clocksource_tsc_early = {
- .name = "tsc-early",
- .rating = 299,
- .read = read_tsc,
- .mask = CLOCKSOURCE_MASK(64),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS |
+ .name = "tsc-early",
+ .rating = 299,
+ .read = read_tsc,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS |
CLOCK_SOURCE_MUST_VERIFY,
- .archdata = { .vclock_mode = VCLOCK_TSC },
+ .archdata = { .vclock_mode = VCLOCK_TSC },
+ .enable = tsc_cs_enable,
.resume = tsc_resume,
.mark_unstable = tsc_cs_mark_unstable,
.tick_stable = tsc_cs_tick_stable,
@@ -1131,14 +1138,15 @@ static struct clocksource clocksource_ts
* been found good.
*/
static struct clocksource clocksource_tsc = {
- .name = "tsc",
- .rating = 300,
- .read = read_tsc,
- .mask = CLOCKSOURCE_MASK(64),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS |
+ .name = "tsc",
+ .rating = 300,
+ .read = read_tsc,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS |
CLOCK_SOURCE_VALID_FOR_HRES |
CLOCK_SOURCE_MUST_VERIFY,
- .archdata = { .vclock_mode = VCLOCK_TSC },
+ .archdata = { .vclock_mode = VCLOCK_TSC },
+ .enable = tsc_cs_enable,
.resume = tsc_resume,
.mark_unstable = tsc_cs_mark_unstable,
.tick_stable = tsc_cs_tick_stable,
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -145,12 +145,19 @@ static struct notifier_block xen_pvclock
.notifier_call = xen_pvclock_gtod_notify,
};
+static int xen_cs_enable(struct clocksource *cs)
+{
+ vclocks_set_used(VCLOCK_PVCLOCK);
+ return 0;
+}
+
static struct clocksource xen_clocksource __read_mostly = {
- .name = "xen",
- .rating = 400,
- .read = xen_clocksource_get_cycles,
- .mask = ~0,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .name = "xen",
+ .rating = 400,
+ .read = xen_clocksource_get_cycles,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .enable = xen_cs_enable,
};
/*
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -330,12 +330,19 @@ static u64 read_hv_sched_clock_tsc(void)
return read_hv_clock_tsc(NULL) - hv_sched_clock_offset;
}
+static int hv_cs_enable(struct clocksource *cs)
+{
+ hv_enable_vdso_clocksource();
+ return 0;
+}
+
static struct clocksource hyperv_cs_tsc = {
.name = "hyperv_clocksource_tsc_page",
.rating = 400,
.read = read_hv_clock_tsc,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .enable = hv_cs_enable,
};
static u64 notrace read_hv_clock_msr(struct clocksource *arg)
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch 08/15] x86/vdso: Move VDSO clocksource state tracking to callback
2020-01-14 18:52 ` [patch 08/15] x86/vdso: Move VDSO clocksource state tracking to callback Thomas Gleixner
@ 2020-01-15 5:56 ` Jürgen Groß
2020-01-20 1:42 ` Michael Kelley
1 sibling, 0 replies; 25+ messages in thread
From: Jürgen Groß @ 2020-01-15 5:56 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Haiyang Zhang,
Sasha Levin, Ralf Baechle, Paul Burton, James Hogan,
Russell King, Catalin Marinas, Will Deacon, Mark Rutland,
Marc Zyngier
On 14.01.20 19:52, Thomas Gleixner wrote:
> All architectures which use the generic VDSO code have their own storage
> for the VDSO clock mode. That's pointless and just requires duplicate code.
>
> X86 abuses the function which retrieves the architecture specific clock
> mode storage to mark the clocksource as used in the VDSO. That's silly
> because this is invoked on every tick when the VDSO data is updated.
>
> Move this functionality to the clocksource::enable() callback so it gets
> invoked once when the clocksource is installed. This allows to make the
> clock mode storage generic.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Juergen Gross <jgross@suse.com> (Xen parts)
Juergen
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [patch 08/15] x86/vdso: Move VDSO clocksource state tracking to callback
2020-01-14 18:52 ` [patch 08/15] x86/vdso: Move VDSO clocksource state tracking to callback Thomas Gleixner
2020-01-15 5:56 ` Jürgen Groß
@ 2020-01-20 1:42 ` Michael Kelley
1 sibling, 0 replies; 25+ messages in thread
From: Michael Kelley @ 2020-01-20 1:42 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
From: Thomas Gleixner <tglx@linutronix.de> Sent: Tuesday, January 14, 2020 10:53 AM
>
> All architectures which use the generic VDSO code have their own storage
> for the VDSO clock mode. That's pointless and just requires duplicate code.
>
> X86 abuses the function which retrieves the architecture specific clock
> mode storage to mark the clocksource as used in the VDSO. That's silly
> because this is invoked on every tick when the VDSO data is updated.
>
> Move this functionality to the clocksource::enable() callback so it gets
> invoked once when the clocksource is installed. This allows to make the
> clock mode storage generic.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Michael Kelley <mikelley@microsoft.com> (Hyper-V parts)
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 09/15] clocksource: Add common vdso clock mode storage
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (7 preceding siblings ...)
2020-01-14 18:52 ` [patch 08/15] x86/vdso: Move VDSO clocksource state tracking to callback Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-15 5:50 ` Christophe Leroy
2020-01-14 18:52 ` [patch 10/15] x86/vdso: Use generic VDSO " Thomas Gleixner
` (5 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
All architectures which use the generic VDSO code have their own storage
for the VDSO clock mode. That's pointless and just requires duplicate code.
Provide generic storage for it. The new Kconfig symbol is intermediate and
will be removed once all architectures are converted over.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/clocksource.h | 12 +++++++++++-
kernel/time/clocksource.c | 9 +++++++++
kernel/time/vsyscall.c | 7 +++++++
lib/vdso/Kconfig | 3 +++
lib/vdso/gettimeofday.c | 13 +++++++++++--
5 files changed, 41 insertions(+), 3 deletions(-)
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -23,10 +23,19 @@
struct clocksource;
struct module;
-#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
+#if defined(CONFIG_ARCH_CLOCKSOURCE_DATA) || \
+ defined(CONFIG_GENERIC_VDSO_CLOCK_MODE)
#include <asm/clocksource.h>
#endif
+enum vdso_clock_mode {
+ VDSO_CLOCKMODE_NONE,
+#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
+ VDSO_ARCH_CLOCKMODES,
+#endif
+ VDSO_CLOCKMODE_MAX,
+};
+
/**
* struct clocksource - hardware abstraction for a free running counter
* Provides mostly state-free accessors to the underlying hardware.
@@ -97,6 +106,7 @@ struct clocksource {
const char *name;
struct list_head list;
int rating;
+ enum vdso_clock_mode vdso_clock_mode;
unsigned long flags;
int (*enable)(struct clocksource *cs);
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -921,6 +921,15 @@ int __clocksource_register_scale(struct
clocksource_arch_init(cs);
+#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
+ if (cs->vdso_clock_mode < 0 ||
+ cs->vdso_clock_mode >= VDSO_CLOCKMODE_MAX) {
+ pr_warn("clocksource %s registered with invalid VDSO mode %d. Disabling VDSO support.\n",
+ cs->name, cs->vdso_clock_mode);
+ cs->vdso_clock_mode = VDSO_CLOCKMODE_NONE;
+ }
+#endif
+
/* Initialize mult/shift and max_idle_ns */
__clocksource_update_freq_scale(cs, scale, freq);
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -72,12 +72,19 @@ void update_vsyscall(struct timekeeper *
struct vdso_data *vdata = __arch_get_k_vdso_data();
struct vdso_timestamp *vdso_ts;
u64 nsec;
+ s32 mode;
/* copy vsyscall data */
vdso_write_begin(vdata);
+#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
+ mode = tk->tkr_mono.clock->vdso_clock_mode;
+ vdata[CS_HRES_COARSE].clock_mode = mode;
+ vdata[CS_RAW].clock_mode = mode;
+#else
vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
+#endif
/* CLOCK_REALTIME also required for time() */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
--- a/lib/vdso/Kconfig
+++ b/lib/vdso/Kconfig
@@ -30,4 +30,7 @@ config GENERIC_VDSO_TIME_NS
Selected by architectures which support time namespaces in the
VDSO
+config GENERIC_VDSO_CLOCK_MODE
+ bool
+
endif
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -7,6 +7,7 @@
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/hrtimer_defs.h>
+#include <linux/clocksource.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
@@ -64,10 +65,14 @@ static int do_hres_timens(const struct v
do {
seq = vdso_read_begin(vd);
+ if (IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
+ vd->clock_mode == VDSO_CLOCKMODE_NONE)
+ return -1;
cycles = __arch_get_hw_counter(vd->clock_mode);
ns = vdso_ts->nsec;
last = vd->cycle_last;
- if (unlikely((s64)cycles < 0))
+ if (!IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
+ unlikely((s64)cycles < 0))
return -1;
ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
@@ -132,10 +137,14 @@ static __always_inline int do_hres(const
}
smp_rmb();
+ if (IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
+ vd->clock_mode == VDSO_CLOCKMODE_NONE)
+ return -1;
cycles = __arch_get_hw_counter(vd->clock_mode);
ns = vdso_ts->nsec;
last = vd->cycle_last;
- if (unlikely((s64)cycles < 0))
+ if (!IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
+ unlikely((s64)cycles < 0))
return -1;
ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch 09/15] clocksource: Add common vdso clock mode storage
2020-01-14 18:52 ` [patch 09/15] clocksource: Add common vdso clock mode storage Thomas Gleixner
@ 2020-01-15 5:50 ` Christophe Leroy
2020-01-15 7:59 ` Thomas Gleixner
0 siblings, 1 reply; 25+ messages in thread
From: Christophe Leroy @ 2020-01-15 5:50 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Paolo Bonzini, Boris Ostrovsky, Juergen Gross, Haiyang Zhang,
Sasha Levin, Ralf Baechle, Paul Burton, James Hogan,
Russell King, Catalin Marinas, Will Deacon, Mark Rutland,
Marc Zyngier
Le 14/01/2020 à 19:52, Thomas Gleixner a écrit :
> All architectures which use the generic VDSO code have their own storage
> for the VDSO clock mode. That's pointless and just requires duplicate code.
>
> Provide generic storage for it. The new Kconfig symbol is intermediate and
> will be removed once all architectures are converted over.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> include/linux/clocksource.h | 12 +++++++++++-
> kernel/time/clocksource.c | 9 +++++++++
> kernel/time/vsyscall.c | 7 +++++++
> lib/vdso/Kconfig | 3 +++
> lib/vdso/gettimeofday.c | 13 +++++++++++--
> 5 files changed, 41 insertions(+), 3 deletions(-)
>
> --- a/include/linux/clocksource.h
> +++ b/include/linux/clocksource.h
> @@ -23,10 +23,19 @@
> struct clocksource;
> struct module;
>
> -#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
> +#if defined(CONFIG_ARCH_CLOCKSOURCE_DATA) || \
> + defined(CONFIG_GENERIC_VDSO_CLOCK_MODE)
> #include <asm/clocksource.h>
> #endif
>
> +enum vdso_clock_mode {
> + VDSO_CLOCKMODE_NONE,
> +#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
> + VDSO_ARCH_CLOCKMODES,
> +#endif
> + VDSO_CLOCKMODE_MAX,
> +};
> +
> /**
> * struct clocksource - hardware abstraction for a free running counter
> * Provides mostly state-free accessors to the underlying hardware.
> @@ -97,6 +106,7 @@ struct clocksource {
> const char *name;
> struct list_head list;
> int rating;
> + enum vdso_clock_mode vdso_clock_mode;
> unsigned long flags;
>
> int (*enable)(struct clocksource *cs);
> --- a/kernel/time/clocksource.c
> +++ b/kernel/time/clocksource.c
> @@ -921,6 +921,15 @@ int __clocksource_register_scale(struct
>
> clocksource_arch_init(cs);
>
> +#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
> + if (cs->vdso_clock_mode < 0 ||
> + cs->vdso_clock_mode >= VDSO_CLOCKMODE_MAX) {
> + pr_warn("clocksource %s registered with invalid VDSO mode %d. Disabling VDSO support.\n",
> + cs->name, cs->vdso_clock_mode);
> + cs->vdso_clock_mode = VDSO_CLOCKMODE_NONE;
> + }
> +#endif
> +
> /* Initialize mult/shift and max_idle_ns */
> __clocksource_update_freq_scale(cs, scale, freq);
>
> --- a/kernel/time/vsyscall.c
> +++ b/kernel/time/vsyscall.c
> @@ -72,12 +72,19 @@ void update_vsyscall(struct timekeeper *
> struct vdso_data *vdata = __arch_get_k_vdso_data();
> struct vdso_timestamp *vdso_ts;
> u64 nsec;
> + s32 mode;
gcc will claim 'mode' is unused when CONFIG_GENERIC_VDSO_CLOCK_MODE is
not defined.
>
> /* copy vsyscall data */
> vdso_write_begin(vdata);
>
> +#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
> + mode = tk->tkr_mono.clock->vdso_clock_mode;
> + vdata[CS_HRES_COARSE].clock_mode = mode;
> + vdata[CS_RAW].clock_mode = mode;
> +#else
> vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
> vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
> +#endif
Can we do :
#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
mode = tk->tkr_mono.clock->vdso_clock_mode;
#else
mode = __arch_get_clock_mode(tk);
#endif
vdata[CS_HRES_COARSE].clock_mode = mode;
vdata[CS_RAW].clock_mode = mode;
Christophe
>
> /* CLOCK_REALTIME also required for time() */
> vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
> --- a/lib/vdso/Kconfig
> +++ b/lib/vdso/Kconfig
> @@ -30,4 +30,7 @@ config GENERIC_VDSO_TIME_NS
> Selected by architectures which support time namespaces in the
> VDSO
>
> +config GENERIC_VDSO_CLOCK_MODE
> + bool
> +
> endif
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -7,6 +7,7 @@
> #include <linux/time.h>
> #include <linux/kernel.h>
> #include <linux/hrtimer_defs.h>
> +#include <linux/clocksource.h>
> #include <vdso/datapage.h>
> #include <vdso/helpers.h>
>
> @@ -64,10 +65,14 @@ static int do_hres_timens(const struct v
>
> do {
> seq = vdso_read_begin(vd);
> + if (IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
> + vd->clock_mode == VDSO_CLOCKMODE_NONE)
> + return -1;
> cycles = __arch_get_hw_counter(vd->clock_mode);
> ns = vdso_ts->nsec;
> last = vd->cycle_last;
> - if (unlikely((s64)cycles < 0))
> + if (!IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
> + unlikely((s64)cycles < 0))
> return -1;
>
> ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
> @@ -132,10 +137,14 @@ static __always_inline int do_hres(const
> }
> smp_rmb();
>
> + if (IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
> + vd->clock_mode == VDSO_CLOCKMODE_NONE)
> + return -1;
> cycles = __arch_get_hw_counter(vd->clock_mode);
> ns = vdso_ts->nsec;
> last = vd->cycle_last;
> - if (unlikely((s64)cycles < 0))
> + if (!IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
> + unlikely((s64)cycles < 0))
> return -1;
>
> ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch 09/15] clocksource: Add common vdso clock mode storage
2020-01-15 5:50 ` Christophe Leroy
@ 2020-01-15 7:59 ` Thomas Gleixner
0 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-15 7:59 UTC (permalink / raw)
To: Christophe Leroy, LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Paolo Bonzini, Boris Ostrovsky, Juergen Gross, Haiyang Zhang,
Sasha Levin, Ralf Baechle, Paul Burton, James Hogan,
Russell King, Catalin Marinas, Will Deacon, Mark Rutland,
Marc Zyngier
Christophe Leroy <christophe.leroy@c-s.fr> writes:
>> --- a/kernel/time/vsyscall.c
>> +++ b/kernel/time/vsyscall.c
>> @@ -72,12 +72,19 @@ void update_vsyscall(struct timekeeper *
>> struct vdso_data *vdata = __arch_get_k_vdso_data();
>> struct vdso_timestamp *vdso_ts;
>> u64 nsec;
>> + s32 mode;
>
> gcc will claim 'mode' is unused when CONFIG_GENERIC_VDSO_CLOCK_MODE is
> not defined.
I know. It's intermediate and goes away a few patches later, but yes I
can fix it up.
Thanks,
tglx
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 10/15] x86/vdso: Use generic VDSO clock mode storage
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (8 preceding siblings ...)
2020-01-14 18:52 ` [patch 09/15] clocksource: Add common vdso clock mode storage Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-15 5:57 ` Jürgen Groß
2020-01-14 18:52 ` [patch 11/15] mips: vdso: " Thomas Gleixner
` (4 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
Switch to the generic VDSO clock mode storage.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Sasha Levin <sashal@kernel.org>
---
arch/x86/Kconfig | 2 +-
arch/x86/entry/vdso/vma.c | 6 +++---
arch/x86/include/asm/clocksource.h | 13 ++++---------
arch/x86/include/asm/mshyperv.h | 4 ++--
arch/x86/include/asm/vdso/gettimeofday.h | 6 +++---
arch/x86/include/asm/vdso/vsyscall.h | 7 -------
arch/x86/kernel/kvmclock.c | 4 ++--
arch/x86/kernel/pvclock.c | 2 +-
arch/x86/kernel/time.c | 12 +++---------
arch/x86/kernel/tsc.c | 6 +++---
arch/x86/kvm/trace.h | 4 ++--
arch/x86/kvm/x86.c | 22 +++++++++++-----------
arch/x86/xen/time.c | 21 +++++++++++----------
13 files changed, 46 insertions(+), 63 deletions(-)
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -57,7 +57,6 @@ config X86
select ACPI_LEGACY_TABLES_LOOKUP if ACPI
select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
select ARCH_32BIT_OFF_T if X86_32
- select ARCH_CLOCKSOURCE_DATA
select ARCH_CLOCKSOURCE_INIT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_DEBUG_VIRTUAL
@@ -124,6 +123,7 @@ config X86
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
+ select GENERIC_VDSO_CLOCK_MODE
select GENERIC_VDSO_TIME_NS
select GUP_GET_PTE_LOW_HIGH if X86_PAE
select HARDLOCKUP_CHECK_TIMESTAMP if X86_64
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -221,7 +221,7 @@ static vm_fault_t vvar_fault(const struc
} else if (sym_offset == image->sym_pvclock_page) {
struct pvclock_vsyscall_time_info *pvti =
pvclock_get_pvti_cpu0_va();
- if (pvti && vclock_was_used(VCLOCK_PVCLOCK)) {
+ if (pvti && vclock_was_used(VDSO_CLOCKMODE_PVCLOCK)) {
return vmf_insert_pfn_prot(vma, vmf->address,
__pa(pvti) >> PAGE_SHIFT,
pgprot_decrypted(vma->vm_page_prot));
@@ -229,7 +229,7 @@ static vm_fault_t vvar_fault(const struc
} else if (sym_offset == image->sym_hvclock_page) {
struct ms_hyperv_tsc_page *tsc_pg = hv_get_tsc_page();
- if (tsc_pg && vclock_was_used(VCLOCK_HVCLOCK))
+ if (tsc_pg && vclock_was_used(VDSO_CLOCKMODE_HVCLOCK))
return vmf_insert_pfn(vma, vmf->address,
virt_to_phys(tsc_pg) >> PAGE_SHIFT);
} else if (sym_offset == image->sym_timens_page) {
@@ -447,7 +447,7 @@ static __init int vdso_setup(char *s)
static int __init init_vdso(void)
{
- BUILD_BUG_ON(VCLOCK_MAX >= 32);
+ BUILD_BUG_ON(VDSO_CLOCKMODE_MAX >= 32);
init_vdso_image(&vdso_image_64);
--- a/arch/x86/include/asm/clocksource.h
+++ b/arch/x86/include/asm/clocksource.h
@@ -4,15 +4,10 @@
#ifndef _ASM_X86_CLOCKSOURCE_H
#define _ASM_X86_CLOCKSOURCE_H
-#define VCLOCK_NONE 0 /* No vDSO clock available. */
-#define VCLOCK_TSC 1 /* vDSO should use vread_tsc. */
-#define VCLOCK_PVCLOCK 2 /* vDSO should use vread_pvclock. */
-#define VCLOCK_HVCLOCK 3 /* vDSO should use vread_hvclock. */
-#define VCLOCK_MAX 3
-
-struct arch_clocksource_data {
- int vclock_mode;
-};
+#define VDSO_ARCH_CLOCKMODES \
+ VDSO_CLOCKMODE_TSC, \
+ VDSO_CLOCKMODE_PVCLOCK, \
+ VDSO_CLOCKMODE_HVCLOCK
extern unsigned int vclocks_used;
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -46,9 +46,9 @@ typedef int (*hyperv_fill_flush_list_fun
#define hv_set_reference_tsc(val) \
wrmsrl(HV_X64_MSR_REFERENCE_TSC, val)
#define hv_set_clocksource_vdso(val) \
- ((val).archdata.vclock_mode = VCLOCK_HVCLOCK)
+ ((val).vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK)
#define hv_enable_vdso_clocksource() \
- vclocks_set_used(VCLOCK_HVCLOCK);
+ vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK);
#define hv_get_raw_timer() rdtsc_ordered()
void hyperv_callback_vector(void);
--- a/arch/x86/include/asm/vdso/gettimeofday.h
+++ b/arch/x86/include/asm/vdso/gettimeofday.h
@@ -243,7 +243,7 @@ static u64 vread_hvclock(void)
static inline u64 __arch_get_hw_counter(s32 clock_mode)
{
- if (clock_mode == VCLOCK_TSC)
+ if (clock_mode == VDSO_CLOCKMODE_TSC)
return (u64)rdtsc_ordered();
/*
* For any memory-mapped vclock type, we need to make sure that gcc
@@ -252,13 +252,13 @@ static inline u64 __arch_get_hw_counter(
* question isn't enabled, which will segfault. Hence the barriers.
*/
#ifdef CONFIG_PARAVIRT_CLOCK
- if (clock_mode == VCLOCK_PVCLOCK) {
+ if (clock_mode == VDSO_CLOCKMODE_PVCLOCK) {
barrier();
return vread_pvclock();
}
#endif
#ifdef CONFIG_HYPERV_TIMER
- if (clock_mode == VCLOCK_HVCLOCK) {
+ if (clock_mode == VDSO_CLOCKMODE_HVCLOCK) {
barrier();
return vread_hvclock();
}
--- a/arch/x86/include/asm/vdso/vsyscall.h
+++ b/arch/x86/include/asm/vdso/vsyscall.h
@@ -21,13 +21,6 @@ struct vdso_data *__x86_get_k_vdso_data(
}
#define __arch_get_k_vdso_data __x86_get_k_vdso_data
-static __always_inline
-int __x86_get_clock_mode(struct timekeeper *tk)
-{
- return tk->tkr_mono.clock->archdata.vclock_mode;
-}
-#define __arch_get_clock_mode __x86_get_clock_mode
-
/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -161,7 +161,7 @@ bool kvm_check_and_clear_guest_paused(vo
static int kvm_cs_enable(struct clocksource *cs)
{
- vclocks_set_used(VCLOCK_PVCLOCK);
+ vclocks_set_used(VDSO_CLOCKMODE_PVCLOCK);
return 0;
}
@@ -279,7 +279,7 @@ static int __init kvm_setup_vsyscall_tim
if (!(flags & PVCLOCK_TSC_STABLE_BIT))
return 0;
- kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK;
+ kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK;
#endif
kvmclock_init_mem();
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -145,7 +145,7 @@ void pvclock_read_wallclock(struct pvclo
void pvclock_set_pvti_cpu0_va(struct pvclock_vsyscall_time_info *pvti)
{
- WARN_ON(vclock_was_used(VCLOCK_PVCLOCK));
+ WARN_ON(vclock_was_used(VDSO_CLOCKMODE_PVCLOCK));
pvti_cpu0_va = pvti;
}
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -114,18 +114,12 @@ void __init time_init(void)
*/
void clocksource_arch_init(struct clocksource *cs)
{
- if (cs->archdata.vclock_mode == VCLOCK_NONE)
+ if (cs->vdso_clock_mode == VDSO_CLOCKMODE_NONE)
return;
- if (cs->archdata.vclock_mode > VCLOCK_MAX) {
- pr_warn("clocksource %s registered with invalid vclock_mode %d. Disabling vclock.\n",
- cs->name, cs->archdata.vclock_mode);
- cs->archdata.vclock_mode = VCLOCK_NONE;
- }
-
if (cs->mask != CLOCKSOURCE_MASK(64)) {
- pr_warn("clocksource %s registered with invalid mask %016llx. Disabling vclock.\n",
+ pr_warn("clocksource %s registered with invalid mask %016llx for VDSO. Disabling VDSO support.\n",
cs->name, cs->mask);
- cs->archdata.vclock_mode = VCLOCK_NONE;
+ cs->vdso_clock_mode = VDSO_CLOCKMODE_NONE;
}
}
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1110,7 +1110,7 @@ static void tsc_cs_tick_stable(struct cl
static int tsc_cs_enable(struct clocksource *cs)
{
- vclocks_set_used(VCLOCK_TSC);
+ vclocks_set_used(VDSO_CLOCKMODE_TSC);
return 0;
}
@@ -1124,7 +1124,7 @@ static struct clocksource clocksource_ts
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
CLOCK_SOURCE_MUST_VERIFY,
- .archdata = { .vclock_mode = VCLOCK_TSC },
+ .vdso_clock_mode = VDSO_CLOCKMODE_TSC,
.enable = tsc_cs_enable,
.resume = tsc_resume,
.mark_unstable = tsc_cs_mark_unstable,
@@ -1145,7 +1145,7 @@ static struct clocksource clocksource_ts
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
CLOCK_SOURCE_VALID_FOR_HRES |
CLOCK_SOURCE_MUST_VERIFY,
- .archdata = { .vclock_mode = VCLOCK_TSC },
+ .vdso_clock_mode = VDSO_CLOCKMODE_TSC,
.enable = tsc_cs_enable,
.resume = tsc_resume,
.mark_unstable = tsc_cs_mark_unstable,
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -815,8 +815,8 @@ TRACE_EVENT(kvm_write_tsc_offset,
#ifdef CONFIG_X86_64
#define host_clocks \
- {VCLOCK_NONE, "none"}, \
- {VCLOCK_TSC, "tsc"} \
+ {VDSO_CLOCKMODE_NONE, "none"}, \
+ {VDSO_CLOCKMODE_TSC, "tsc"} \
TRACE_EVENT(kvm_update_master_clock,
TP_PROTO(bool use_master_clock, unsigned int host_clock, bool offset_matched),
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1573,13 +1573,13 @@ static void update_pvclock_gtod(struct t
write_seqcount_begin(&vdata->seq);
/* copy pvclock gtod data */
- vdata->clock.vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode;
+ vdata->clock.vclock_mode = tk->tkr_mono.clock->vdso_clock_mode;
vdata->clock.cycle_last = tk->tkr_mono.cycle_last;
vdata->clock.mask = tk->tkr_mono.mask;
vdata->clock.mult = tk->tkr_mono.mult;
vdata->clock.shift = tk->tkr_mono.shift;
- vdata->raw_clock.vclock_mode = tk->tkr_raw.clock->archdata.vclock_mode;
+ vdata->raw_clock.vclock_mode = tk->tkr_raw.clock->vdso_clock_mode;
vdata->raw_clock.cycle_last = tk->tkr_raw.cycle_last;
vdata->raw_clock.mask = tk->tkr_raw.mask;
vdata->raw_clock.mult = tk->tkr_raw.mult;
@@ -1775,7 +1775,7 @@ static u64 compute_guest_tsc(struct kvm_
static inline int gtod_is_based_on_tsc(int mode)
{
- return mode == VCLOCK_TSC || mode == VCLOCK_HVCLOCK;
+ return mode == VDSO_CLOCKMODE_TSC || mode == VDSO_CLOCKMODE_HVCLOCK;
}
static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
@@ -1868,7 +1868,7 @@ static inline bool kvm_check_tsc_unstabl
* TSC is marked unstable when we're running on Hyper-V,
* 'TSC page' clocksource is good.
*/
- if (pvclock_gtod_data.clock.vclock_mode == VCLOCK_HVCLOCK)
+ if (pvclock_gtod_data.clock.vclock_mode == VDSO_CLOCKMODE_HVCLOCK)
return false;
#endif
return check_tsc_unstable();
@@ -2023,30 +2023,30 @@ static inline u64 vgettsc(struct pvclock
u64 tsc_pg_val;
switch (clock->vclock_mode) {
- case VCLOCK_HVCLOCK:
+ case VDSO_CLOCKMODE_HVCLOCK:
tsc_pg_val = hv_read_tsc_page_tsc(hv_get_tsc_page(),
tsc_timestamp);
if (tsc_pg_val != U64_MAX) {
/* TSC page valid */
- *mode = VCLOCK_HVCLOCK;
+ *mode = VDSO_CLOCKMODE_HVCLOCK;
v = (tsc_pg_val - clock->cycle_last) &
clock->mask;
} else {
/* TSC page invalid */
- *mode = VCLOCK_NONE;
+ *mode = VDSO_CLOCKMODE_NONE;
}
break;
- case VCLOCK_TSC:
- *mode = VCLOCK_TSC;
+ case VDSO_CLOCKMODE_TSC:
+ *mode = VDSO_CLOCKMODE_TSC;
*tsc_timestamp = read_tsc();
v = (*tsc_timestamp - clock->cycle_last) &
clock->mask;
break;
default:
- *mode = VCLOCK_NONE;
+ *mode = VDSO_CLOCKMODE_NONE;
}
- if (*mode == VCLOCK_NONE)
+ if (*mode == VDSO_CLOCKMODE_NONE)
*tsc_timestamp = v = 0;
return v * clock->mult;
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -147,7 +147,7 @@ static struct notifier_block xen_pvclock
static int xen_cs_enable(struct clocksource *cs)
{
- vclocks_set_used(VCLOCK_PVCLOCK);
+ vclocks_set_used(VDSO_CLOCKMODE_PVCLOCK);
return 0;
}
@@ -419,12 +419,13 @@ void xen_restore_time_memory_area(void)
ret = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_time_memory_area, 0, &t);
/*
- * We don't disable VCLOCK_PVCLOCK entirely if it fails to register the
- * secondary time info with Xen or if we migrated to a host without the
- * necessary flags. On both of these cases what happens is either
- * process seeing a zeroed out pvti or seeing no PVCLOCK_TSC_STABLE_BIT
- * bit set. Userspace checks the latter and if 0, it discards the data
- * in pvti and fallbacks to a system call for a reliable timestamp.
+ * We don't disable VDSO_CLOCKMODE_PVCLOCK entirely if it fails to
+ * register the secondary time info with Xen or if we migrated to a
+ * host without the necessary flags. On both of these cases what
+ * happens is either process seeing a zeroed out pvti or seeing no
+ * PVCLOCK_TSC_STABLE_BIT bit set. Userspace checks the latter and
+ * if 0, it discards the data in pvti and fallbacks to a system
+ * call for a reliable timestamp.
*/
if (ret != 0)
pr_notice("Cannot restore secondary vcpu_time_info (err %d)",
@@ -450,7 +451,7 @@ static void xen_setup_vsyscall_time_info
ret = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_time_memory_area, 0, &t);
if (ret) {
- pr_notice("xen: VCLOCK_PVCLOCK not supported (err %d)\n", ret);
+ pr_notice("xen: VDSO_CLOCKMODE_PVCLOCK not supported (err %d)\n", ret);
free_page((unsigned long)ti);
return;
}
@@ -467,14 +468,14 @@ static void xen_setup_vsyscall_time_info
if (!ret)
free_page((unsigned long)ti);
- pr_notice("xen: VCLOCK_PVCLOCK not supported (tsc unstable)\n");
+ pr_notice("xen: VDSO_CLOCKMODE_PVCLOCK not supported (tsc unstable)\n");
return;
}
xen_clock = ti;
pvclock_set_pvti_cpu0_va(xen_clock);
- xen_clocksource.archdata.vclock_mode = VCLOCK_PVCLOCK;
+ xen_clocksource.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK;
}
static void __init xen_time_init(void)
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch 10/15] x86/vdso: Use generic VDSO clock mode storage
2020-01-14 18:52 ` [patch 10/15] x86/vdso: Use generic VDSO " Thomas Gleixner
@ 2020-01-15 5:57 ` Jürgen Groß
0 siblings, 0 replies; 25+ messages in thread
From: Jürgen Groß @ 2020-01-15 5:57 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Haiyang Zhang,
Sasha Levin, Ralf Baechle, Paul Burton, James Hogan,
Russell King, Catalin Marinas, Will Deacon, Mark Rutland,
Marc Zyngier
On 14.01.20 19:52, Thomas Gleixner wrote:
> Switch to the generic VDSO clock mode storage.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Juergen Gross <jgross@suse.com> (Xen parts)
Juergen
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 11/15] mips: vdso: Use generic VDSO clock mode storage
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (9 preceding siblings ...)
2020-01-14 18:52 ` [patch 10/15] x86/vdso: Use generic VDSO " Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 12/15] ARM/arm64: vdso: Use common vdso " Thomas Gleixner
` (3 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Ralf Baechle, Paul Burton, James Hogan,
Paolo Bonzini, Boris Ostrovsky, Juergen Gross, Haiyang Zhang,
Sasha Levin, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
Switch to the generic VDSO clock mode storage.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paulburton@kernel.org>
Cc: James Hogan <jhogan@kernel.org>
---
arch/mips/Kconfig | 2 +-
arch/mips/include/asm/clocksource.h | 18 +++---------------
arch/mips/include/asm/vdso/gettimeofday.h | 24 ++++++------------------
arch/mips/include/asm/vdso/vsyscall.h | 9 ---------
arch/mips/kernel/csrc-r4k.c | 2 +-
drivers/clocksource/mips-gic-timer.c | 8 ++++----
6 files changed, 15 insertions(+), 48 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -4,7 +4,6 @@ config MIPS
default y
select ARCH_32BIT_OFF_T if !64BIT
select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
- select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAS_FORTIFY_SOURCE
@@ -36,6 +35,7 @@ config MIPS
select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
+ select GENERIC_VDSO_CLOCK_MODE
select GUP_GET_PTE_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_COMPILER_H
--- a/arch/mips/include/asm/clocksource.h
+++ b/arch/mips/include/asm/clocksource.h
@@ -3,23 +3,11 @@
* Copyright (C) 2015 Imagination Technologies
* Author: Alex Smith <alex.smith@imgtec.com>
*/
-
#ifndef __ASM_CLOCKSOURCE_H
#define __ASM_CLOCKSOURCE_H
-#include <linux/types.h>
-
-/* VDSO clocksources. */
-#define VDSO_CLOCK_NONE 0 /* No suitable clocksource. */
-#define VDSO_CLOCK_R4K 1 /* Use the coprocessor 0 count. */
-#define VDSO_CLOCK_GIC 2 /* Use the GIC. */
-
-/**
- * struct arch_clocksource_data - Architecture-specific clocksource information.
- * @vdso_clock_mode: Method the VDSO should use to access the clocksource.
- */
-struct arch_clocksource_data {
- u8 vdso_clock_mode;
-};
+#define VDSO_ARCH_CLOCKMODES \
+ VDSO_CLOCKMDOE_R4K, \
+ VDSO_CLOCKMODE_GIC
#endif /* __ASM_CLOCKSOURCE_H */
--- a/arch/mips/include/asm/vdso/gettimeofday.h
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -175,28 +175,16 @@ static __always_inline u64 read_gic_coun
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
{
-#ifdef CONFIG_CLKSRC_MIPS_GIC
- const struct vdso_data *data = get_vdso_data();
-#endif
- u64 cycle_now;
-
- switch (clock_mode) {
#ifdef CONFIG_CSRC_R4K
- case VDSO_CLOCK_R4K:
- cycle_now = read_r4k_count();
- break;
+ if (clock_mode == VDSO_CLOCKMODE_R4K)
+ return read_r4k_count();
#endif
#ifdef CONFIG_CLKSRC_MIPS_GIC
- case VDSO_CLOCK_GIC:
- cycle_now = read_gic_count(data);
- break;
+ if (clock_mode == VDSO_CLOCKMODE_GIC)
+ return read_gic_count(get_vdso_data());
#endif
- default:
- cycle_now = __VDSO_USE_SYSCALL;
- break;
- }
-
- return cycle_now;
+ /* Keep GCC happy */
+ return U64_MAX;
}
static inline bool mips_vdso_hres_capable(void)
--- a/arch/mips/include/asm/vdso/vsyscall.h
+++ b/arch/mips/include/asm/vdso/vsyscall.h
@@ -19,15 +19,6 @@ struct vdso_data *__mips_get_k_vdso_data
}
#define __arch_get_k_vdso_data __mips_get_k_vdso_data
-static __always_inline
-int __mips_get_clock_mode(struct timekeeper *tk)
-{
- u32 clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
-
- return clock_mode;
-}
-#define __arch_get_clock_mode __mips_get_clock_mode
-
/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
--- a/arch/mips/kernel/csrc-r4k.c
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -78,7 +78,7 @@ int __init init_r4k_clocksource(void)
* by the VDSO (HWREna is configured by configure_hwrena()).
*/
if (cpu_has_mips_r2_r6 && rdhwr_count_usable())
- clocksource_mips.archdata.vdso_clock_mode = VDSO_CLOCK_R4K;
+ clocksource_mips.vdso_clock_mode = VDSO_CLOCKMODE_R4K;
clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
--- a/drivers/clocksource/mips-gic-timer.c
+++ b/drivers/clocksource/mips-gic-timer.c
@@ -155,10 +155,10 @@ static u64 gic_hpt_read(struct clocksour
}
static struct clocksource gic_clocksource = {
- .name = "GIC",
- .read = gic_hpt_read,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
- .archdata = { .vdso_clock_mode = VDSO_CLOCK_GIC },
+ .name = "GIC",
+ .read = gic_hpt_read,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .vdso_clock_mode = VDSO_CLOCKMODE_GIC,
};
static int __init __gic_clocksource_init(void)
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 12/15] ARM/arm64: vdso: Use common vdso clock mode storage
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (10 preceding siblings ...)
2020-01-14 18:52 ` [patch 11/15] mips: vdso: " Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 13/15] lib/vdso: Cleanup clock mode storage leftovers Thomas Gleixner
` (2 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier, Paolo Bonzini, Boris Ostrovsky,
Juergen Gross, Haiyang Zhang, Sasha Levin, Ralf Baechle,
Paul Burton, James Hogan
Convert ARM/ARM64 to the generic VDSO clock mode storage. This needs to
happen in one go as they share the clocksource driver.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
---
arch/arm/Kconfig | 1 -
arch/arm/include/asm/clocksource.h | 5 ++---
arch/arm/include/asm/vdso/vsyscall.h | 21 ---------------------
arch/arm/mm/Kconfig | 1 +
arch/arm64/Kconfig | 2 +-
arch/arm64/include/asm/clocksource.h | 5 ++---
arch/arm64/include/asm/vdso/vsyscall.h | 9 ---------
drivers/clocksource/arm_arch_timer.c | 8 ++++----
8 files changed, 10 insertions(+), 42 deletions(-)
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -3,7 +3,6 @@ config ARM
bool
default y
select ARCH_32BIT_OFF_T
- select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEVMEM_IS_ALLOWED
--- a/arch/arm/include/asm/clocksource.h
+++ b/arch/arm/include/asm/clocksource.h
@@ -1,8 +1,7 @@
#ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H
-struct arch_clocksource_data {
- bool vdso_direct; /* Usable for direct VDSO access? */
-};
+#define VDSO_ARCH_CLOCKMODES \
+ VDSO_CLOCKMODE_ARCHTIMER
#endif
--- a/arch/arm/include/asm/vdso/vsyscall.h
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -11,18 +11,6 @@
extern struct vdso_data *vdso_data;
extern bool cntvct_ok;
-static __always_inline
-bool tk_is_cntvct(const struct timekeeper *tk)
-{
- if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
- return false;
-
- if (!tk->tkr_mono.clock->archdata.vdso_direct)
- return false;
-
- return true;
-}
-
/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
@@ -41,15 +29,6 @@ bool __arm_update_vdso_data(void)
#define __arch_update_vdso_data __arm_update_vdso_data
static __always_inline
-int __arm_get_clock_mode(struct timekeeper *tk)
-{
- u32 __tk_is_cntvct = tk_is_cntvct(tk);
-
- return __tk_is_cntvct;
-}
-#define __arch_get_clock_mode __arm_get_clock_mode
-
-static __always_inline
void __arm_sync_vdso_data(struct vdso_data *vdata)
{
flush_dcache_page(virt_to_page(vdata));
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -900,6 +900,7 @@ config VDSO
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_32
select GENERIC_GETTIMEOFDAY
+ select GENERIC_VDSO_CLOCK_MODE
help
Place in the process address space an ELF shared object
providing fast implementations of gettimeofday and
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -9,7 +9,6 @@ config ARM64
select ACPI_MCFG if (ACPI && PCI)
select ACPI_SPCR_TABLE if ACPI
select ACPI_PPTT if ACPI
- select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_PREP_COHERENT
@@ -109,6 +108,7 @@ config ARM64
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
+ select GENERIC_VDSO_CLOCK_MODE
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_PCI
--- a/arch/arm64/include/asm/clocksource.h
+++ b/arch/arm64/include/asm/clocksource.h
@@ -2,8 +2,7 @@
#ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H
-struct arch_clocksource_data {
- bool vdso_direct; /* Usable for direct VDSO access? */
-};
+#define VDSO_ARCH_CLOCKMODES \
+ VDSO_CLOCKMODE_ARCHTIMER
#endif
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -22,15 +22,6 @@ struct vdso_data *__arm64_get_k_vdso_dat
#define __arch_get_k_vdso_data __arm64_get_k_vdso_data
static __always_inline
-int __arm64_get_clock_mode(struct timekeeper *tk)
-{
- u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
-
- return use_syscall;
-}
-#define __arch_get_clock_mode __arm64_get_clock_mode
-
-static __always_inline
void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
{
vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -69,7 +69,7 @@ static enum arch_timer_ppi_nr arch_timer
static bool arch_timer_c3stop;
static bool arch_timer_mem_use_virtual;
static bool arch_counter_suspend_stop;
-static bool vdso_default = true;
+static enum vdso_clock_mode vdso_default = VDSO_CLOCKMODE_ARCHTIMER;
static cpumask_t evtstrm_available = CPU_MASK_NONE;
static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
@@ -560,8 +560,8 @@ void arch_timer_enable_workaround(const
* change both the default value and the vdso itself.
*/
if (wa->read_cntvct_el0) {
- clocksource_counter.archdata.vdso_direct = false;
- vdso_default = false;
+ clocksource_counter.vdso_clock_mode = VDSO_CLOCKMODE_NONE;
+ vdso_default = VDSO_CLOCKMODE_NONE;
}
}
@@ -979,7 +979,7 @@ static void __init arch_counter_register
}
arch_timer_read_counter = rd;
- clocksource_counter.archdata.vdso_direct = vdso_default;
+ clocksource_counter.vdso_clock_mode = vdso_default;
} else {
arch_timer_read_counter = arch_counter_get_cntvct_mem;
}
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 13/15] lib/vdso: Cleanup clock mode storage leftovers
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (11 preceding siblings ...)
2020-01-14 18:52 ` [patch 12/15] ARM/arm64: vdso: Use common vdso " Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-14 18:52 ` [patch 14/15] lib/vdso: Avoid highres update if clocksource is not VDSO capable Thomas Gleixner
2020-01-14 18:52 ` [patch 15/15] lib/vdso: Move VCLOCK_TIMENS to vdso_clock_modes Thomas Gleixner
14 siblings, 0 replies; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Russell King, Catalin Marinas, Will Deacon,
Ralf Baechle, Paul Burton, James Hogan, Paolo Bonzini,
Boris Ostrovsky, Juergen Gross, Haiyang Zhang, Sasha Levin,
Mark Rutland, Marc Zyngier
Now that all architectures are converted to use the generic storage the
helpers and conditionals can be removed.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paul Burton <paulburton@kernel.org>
Cc: James Hogan <jhogan@kernel.org>
---
arch/arm/mm/Kconfig | 1 -
arch/arm64/Kconfig | 1 -
arch/mips/Kconfig | 1 -
arch/x86/Kconfig | 1 -
include/asm-generic/vdso/vsyscall.h | 7 -------
include/linux/clocksource.h | 4 ++--
kernel/time/vsyscall.c | 5 -----
lib/vdso/Kconfig | 3 ---
lib/vdso/gettimeofday.c | 17 +++++------------
9 files changed, 7 insertions(+), 33 deletions(-)
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -900,7 +900,6 @@ config VDSO
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_32
select GENERIC_GETTIMEOFDAY
- select GENERIC_VDSO_CLOCK_MODE
help
Place in the process address space an ELF shared object
providing fast implementations of gettimeofday and
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -108,7 +108,6 @@ config ARM64
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
- select GENERIC_VDSO_CLOCK_MODE
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_PCI
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -35,7 +35,6 @@ config MIPS
select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
- select GENERIC_VDSO_CLOCK_MODE
select GUP_GET_PTE_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_COMPILER_H
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -123,7 +123,6 @@ config X86
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
- select GENERIC_VDSO_CLOCK_MODE
select GENERIC_VDSO_TIME_NS
select GUP_GET_PTE_LOW_HIGH if X86_PAE
select HARDLOCKUP_CHECK_TIMESTAMP if X86_64
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -18,13 +18,6 @@ static __always_inline bool __arch_updat
}
#endif /* __arch_update_vdso_data */
-#ifndef __arch_get_clock_mode
-static __always_inline int __arch_get_clock_mode(struct timekeeper *tk)
-{
- return 0;
-}
-#endif /* __arch_get_clock_mode */
-
#ifndef __arch_update_vsyscall
static __always_inline void __arch_update_vsyscall(struct vdso_data *vdata,
struct timekeeper *tk)
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -24,13 +24,13 @@ struct clocksource;
struct module;
#if defined(CONFIG_ARCH_CLOCKSOURCE_DATA) || \
- defined(CONFIG_GENERIC_VDSO_CLOCK_MODE)
+ defined(CONFIG_GENERIC_GETTIMEOFDAY)
#include <asm/clocksource.h>
#endif
enum vdso_clock_mode {
VDSO_CLOCKMODE_NONE,
-#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
+#ifdef CONFIG_GENERIC_GETTIMEOFDAY
VDSO_ARCH_CLOCKMODES,
#endif
VDSO_CLOCKMODE_MAX,
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -77,14 +77,9 @@ void update_vsyscall(struct timekeeper *
/* copy vsyscall data */
vdso_write_begin(vdata);
-#ifdef CONFIG_GENERIC_VDSO_CLOCK_MODE
mode = tk->tkr_mono.clock->vdso_clock_mode;
vdata[CS_HRES_COARSE].clock_mode = mode;
vdata[CS_RAW].clock_mode = mode;
-#else
- vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk);
- vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk);
-#endif
/* CLOCK_REALTIME also required for time() */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
--- a/lib/vdso/Kconfig
+++ b/lib/vdso/Kconfig
@@ -30,7 +30,4 @@ config GENERIC_VDSO_TIME_NS
Selected by architectures which support time namespaces in the
VDSO
-config GENERIC_VDSO_CLOCK_MODE
- bool
-
endif
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -65,16 +65,13 @@ static int do_hres_timens(const struct v
do {
seq = vdso_read_begin(vd);
- if (IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
- vd->clock_mode == VDSO_CLOCKMODE_NONE)
+
+ if (unlikely(vd->clock_mode == VDSO_CLOCKMODE_NONE))
return -1;
+
cycles = __arch_get_hw_counter(vd->clock_mode);
ns = vdso_ts->nsec;
last = vd->cycle_last;
- if (!IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
- unlikely((s64)cycles < 0))
- return -1;
-
ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
ns >>= vd->shift;
sec = vdso_ts->sec;
@@ -137,16 +134,12 @@ static __always_inline int do_hres(const
}
smp_rmb();
- if (IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
- vd->clock_mode == VDSO_CLOCKMODE_NONE)
+ if (unlikely(vd->clock_mode == VDSO_CLOCKMODE_NONE))
return -1;
+
cycles = __arch_get_hw_counter(vd->clock_mode);
ns = vdso_ts->nsec;
last = vd->cycle_last;
- if (!IS_ENABLED(CONFIG_GENERIC_VDSO_CLOCK_MODE) &&
- unlikely((s64)cycles < 0))
- return -1;
-
ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
ns >>= vd->shift;
sec = vdso_ts->sec;
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 14/15] lib/vdso: Avoid highres update if clocksource is not VDSO capable
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (12 preceding siblings ...)
2020-01-14 18:52 ` [patch 13/15] lib/vdso: Cleanup clock mode storage leftovers Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-15 5:54 ` Christophe Leroy
2020-01-14 18:52 ` [patch 15/15] lib/vdso: Move VCLOCK_TIMENS to vdso_clock_modes Thomas Gleixner
14 siblings, 1 reply; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
If the current clocksource is not VDSO capable there is no point in
updating the high resolution parts of the VDSO data.
Replace the architecture specific check with a check for a VDSO capable
clocksource and skip the update if there is none.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/arm/include/asm/vdso/vsyscall.h | 7 -------
include/asm-generic/vdso/vsyscall.h | 7 -------
kernel/time/vsyscall.c | 14 +++++++-------
3 files changed, 7 insertions(+), 21 deletions(-)
--- a/arch/arm/include/asm/vdso/vsyscall.h
+++ b/arch/arm/include/asm/vdso/vsyscall.h
@@ -22,13 +22,6 @@ struct vdso_data *__arm_get_k_vdso_data(
#define __arch_get_k_vdso_data __arm_get_k_vdso_data
static __always_inline
-bool __arm_update_vdso_data(void)
-{
- return cntvct_ok;
-}
-#define __arch_update_vdso_data __arm_update_vdso_data
-
-static __always_inline
void __arm_sync_vdso_data(struct vdso_data *vdata)
{
flush_dcache_page(virt_to_page(vdata));
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -11,13 +11,6 @@ static __always_inline struct vdso_data
}
#endif /* __arch_get_k_vdso_data */
-#ifndef __arch_update_vdso_data
-static __always_inline bool __arch_update_vdso_data(void)
-{
- return true;
-}
-#endif /* __arch_update_vdso_data */
-
#ifndef __arch_update_vsyscall
static __always_inline void __arch_update_vsyscall(struct vdso_data *vdata,
struct timekeeper *tk)
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -71,15 +71,15 @@ void update_vsyscall(struct timekeeper *
{
struct vdso_data *vdata = __arch_get_k_vdso_data();
struct vdso_timestamp *vdso_ts;
+ s32 clock_mode;
u64 nsec;
- s32 mode;
/* copy vsyscall data */
vdso_write_begin(vdata);
- mode = tk->tkr_mono.clock->vdso_clock_mode;
- vdata[CS_HRES_COARSE].clock_mode = mode;
- vdata[CS_RAW].clock_mode = mode;
+ clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
+ vdata[CS_HRES_COARSE].clock_mode = clock_mode;
+ vdata[CS_RAW].clock_mode = clock_mode;
/* CLOCK_REALTIME also required for time() */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
@@ -105,10 +105,10 @@ void update_vsyscall(struct timekeeper *
WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
/*
- * Architectures can opt out of updating the high resolution part
- * of the VDSO.
+ * If the current clocksource is not VDSO capable, then spare the
+ * update of the high reolution parts.
*/
- if (__arch_update_vdso_data())
+ if (clock_mode != VDSO_CLOCKMODE_NONE)
update_vdso_data(vdata, tk);
__arch_update_vsyscall(vdata, tk);
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch 14/15] lib/vdso: Avoid highres update if clocksource is not VDSO capable
2020-01-14 18:52 ` [patch 14/15] lib/vdso: Avoid highres update if clocksource is not VDSO capable Thomas Gleixner
@ 2020-01-15 5:54 ` Christophe Leroy
0 siblings, 0 replies; 25+ messages in thread
From: Christophe Leroy @ 2020-01-15 5:54 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Paolo Bonzini, Boris Ostrovsky, Juergen Gross, Haiyang Zhang,
Sasha Levin, Ralf Baechle, Paul Burton, James Hogan,
Russell King, Catalin Marinas, Will Deacon, Mark Rutland,
Marc Zyngier
Le 14/01/2020 à 19:52, Thomas Gleixner a écrit :
> If the current clocksource is not VDSO capable there is no point in
> updating the high resolution parts of the VDSO data.
>
> Replace the architecture specific check with a check for a VDSO capable
> clocksource and skip the update if there is none.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> arch/arm/include/asm/vdso/vsyscall.h | 7 -------
> include/asm-generic/vdso/vsyscall.h | 7 -------
> kernel/time/vsyscall.c | 14 +++++++-------
> 3 files changed, 7 insertions(+), 21 deletions(-)
>
> --- a/arch/arm/include/asm/vdso/vsyscall.h
> +++ b/arch/arm/include/asm/vdso/vsyscall.h
> @@ -22,13 +22,6 @@ struct vdso_data *__arm_get_k_vdso_data(
> #define __arch_get_k_vdso_data __arm_get_k_vdso_data
>
> static __always_inline
> -bool __arm_update_vdso_data(void)
> -{
> - return cntvct_ok;
> -}
> -#define __arch_update_vdso_data __arm_update_vdso_data
> -
> -static __always_inline
> void __arm_sync_vdso_data(struct vdso_data *vdata)
> {
> flush_dcache_page(virt_to_page(vdata));
> --- a/include/asm-generic/vdso/vsyscall.h
> +++ b/include/asm-generic/vdso/vsyscall.h
> @@ -11,13 +11,6 @@ static __always_inline struct vdso_data
> }
> #endif /* __arch_get_k_vdso_data */
>
> -#ifndef __arch_update_vdso_data
> -static __always_inline bool __arch_update_vdso_data(void)
> -{
> - return true;
> -}
> -#endif /* __arch_update_vdso_data */
> -
> #ifndef __arch_update_vsyscall
> static __always_inline void __arch_update_vsyscall(struct vdso_data *vdata,
> struct timekeeper *tk)
> --- a/kernel/time/vsyscall.c
> +++ b/kernel/time/vsyscall.c
> @@ -71,15 +71,15 @@ void update_vsyscall(struct timekeeper *
> {
> struct vdso_data *vdata = __arch_get_k_vdso_data();
> struct vdso_timestamp *vdso_ts;
> + s32 clock_mode;
> u64 nsec;
> - s32 mode;
Can we name is clock_mode in patch 9 instead of changing name here ?
Christophe
>
> /* copy vsyscall data */
> vdso_write_begin(vdata);
>
> - mode = tk->tkr_mono.clock->vdso_clock_mode;
> - vdata[CS_HRES_COARSE].clock_mode = mode;
> - vdata[CS_RAW].clock_mode = mode;
> + clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
> + vdata[CS_HRES_COARSE].clock_mode = clock_mode;
> + vdata[CS_RAW].clock_mode = clock_mode;
>
> /* CLOCK_REALTIME also required for time() */
> vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
> @@ -105,10 +105,10 @@ void update_vsyscall(struct timekeeper *
> WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution);
>
> /*
> - * Architectures can opt out of updating the high resolution part
> - * of the VDSO.
> + * If the current clocksource is not VDSO capable, then spare the
> + * update of the high reolution parts.
> */
> - if (__arch_update_vdso_data())
> + if (clock_mode != VDSO_CLOCKMODE_NONE)
> update_vdso_data(vdata, tk);
>
> __arch_update_vsyscall(vdata, tk);
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* [patch 15/15] lib/vdso: Move VCLOCK_TIMENS to vdso_clock_modes
2020-01-14 18:52 [patch 00/15] lib/vdso: Bugfix and consolidation Thomas Gleixner
` (13 preceding siblings ...)
2020-01-14 18:52 ` [patch 14/15] lib/vdso: Avoid highres update if clocksource is not VDSO capable Thomas Gleixner
@ 2020-01-14 18:52 ` Thomas Gleixner
2020-01-15 5:58 ` Christophe Leroy
14 siblings, 1 reply; 25+ messages in thread
From: Thomas Gleixner @ 2020-01-14 18:52 UTC (permalink / raw)
To: LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Christophe Leroy, Paolo Bonzini, Boris Ostrovsky, Juergen Gross,
Haiyang Zhang, Sasha Levin, Ralf Baechle, Paul Burton,
James Hogan, Russell King, Catalin Marinas, Will Deacon,
Mark Rutland, Marc Zyngier
Move the time namespace indicator clock mode to the other ones for
consistency sake.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/clocksource.h | 3 +++
include/vdso/datapage.h | 2 --
kernel/time/namespace.c | 7 ++++---
lib/vdso/gettimeofday.c | 18 ++++++++++--------
4 files changed, 17 insertions(+), 13 deletions(-)
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -34,6 +34,9 @@ enum vdso_clock_mode {
VDSO_ARCH_CLOCKMODES,
#endif
VDSO_CLOCKMODE_MAX,
+
+ /* Indicator for time namespace VDSO */
+ VDSO_CLOCKMODE_TIMENS = INT_MAX
};
/**
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -21,8 +21,6 @@
#define CS_RAW 1
#define CS_BASES (CS_RAW + 1)
-#define VCLOCK_TIMENS UINT_MAX
-
/**
* struct vdso_timestamp - basetime per clock_id
* @sec: seconds
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -8,6 +8,7 @@
#include <linux/user_namespace.h>
#include <linux/sched/signal.h>
#include <linux/sched/task.h>
+#include <linux/clocksource.h>
#include <linux/seq_file.h>
#include <linux/proc_ns.h>
#include <linux/export.h>
@@ -172,8 +173,8 @@ static struct timens_offset offset_from_
* for vdso_data->clock_mode is a non-issue. The task is spin waiting for the
* update to finish and for 'seq' to become even anyway.
*
- * Timens page has vdso_data->clock_mode set to VCLOCK_TIMENS which enforces
- * the time namespace handling path.
+ * Timens page has vdso_data->clock_mode set to VDSO_CLOCKMODE_TIMENS which
+ * enforces the time namespace handling path.
*/
static void timens_setup_vdso_data(struct vdso_data *vdata,
struct time_namespace *ns)
@@ -183,7 +184,7 @@ static void timens_setup_vdso_data(struc
struct timens_offset boottime = offset_from_ts(ns->offsets.boottime);
vdata->seq = 1;
- vdata->clock_mode = VCLOCK_TIMENS;
+ vdata->clock_mode = VDSO_CLOCKMODE_TIMENS;
offset[CLOCK_MONOTONIC] = monotonic;
offset[CLOCK_MONOTONIC_RAW] = monotonic;
offset[CLOCK_MONOTONIC_COARSE] = monotonic;
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -116,10 +116,10 @@ static __always_inline int do_hres(const
do {
/*
- * Open coded to handle VCLOCK_TIMENS. Time namespace
+ * Open coded to handle VDSO_CLOCKMODE_TIMENS. Time namespace
* enabled tasks have a special VVAR page installed which
* has vd->seq set to 1 and vd->clock_mode set to
- * VCLOCK_TIMENS. For non time namespace affected tasks
+ * VDSO_CLOCKMODE_TIMENS. For non time namespace affected tasks
* this does not affect performance because if vd->seq is
* odd, i.e. a concurrent update is in progress the extra
* check for vd->clock_mode is just a few extra
@@ -128,7 +128,7 @@ static __always_inline int do_hres(const
*/
while (unlikely((seq = READ_ONCE(vd->seq)) & 1)) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VCLOCK_TIMENS)
+ vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
return do_hres_timens(vd, clk, ts);
cpu_relax();
}
@@ -200,12 +200,12 @@ static __always_inline int do_coarse(con
do {
/*
- * Open coded to handle VCLOCK_TIMENS. See comment in
+ * Open coded to handle VDSO_CLOCK_TIMENS. See comment in
* do_hres().
*/
while ((seq = READ_ONCE(vd->seq)) & 1) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VCLOCK_TIMENS)
+ vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
return do_coarse_timens(vd, clk, ts);
cpu_relax();
}
@@ -292,7 +292,7 @@ static __maybe_unused int
if (unlikely(tz != NULL)) {
if (IS_ENABLED(CONFIG_TIME_NS) &&
- vd->clock_mode == VCLOCK_TIMENS)
+ vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
vd = __arch_get_timens_vdso_data();
tz->tz_minuteswest = vd[CS_HRES_COARSE].tz_minuteswest;
@@ -308,7 +308,8 @@ static __maybe_unused __kernel_old_time_
const struct vdso_data *vd = __arch_get_vdso_data();
__kernel_old_time_t t;
- if (IS_ENABLED(CONFIG_TIME_NS) && vd->clock_mode == VCLOCK_TIMENS)
+ if (IS_ENABLED(CONFIG_TIME_NS) &&
+ vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
vd = __arch_get_timens_vdso_data();
t = READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
@@ -333,7 +334,8 @@ int __cvdso_clock_getres_common(clockid_
if (unlikely((u32) clock >= MAX_CLOCKS))
return -1;
- if (IS_ENABLED(CONFIG_TIME_NS) && vd->clock_mode == VCLOCK_TIMENS)
+ if (IS_ENABLED(CONFIG_TIME_NS) &&
+ vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
vd = __arch_get_timens_vdso_data();
hrtimer_res = READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res);
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch 15/15] lib/vdso: Move VCLOCK_TIMENS to vdso_clock_modes
2020-01-14 18:52 ` [patch 15/15] lib/vdso: Move VCLOCK_TIMENS to vdso_clock_modes Thomas Gleixner
@ 2020-01-15 5:58 ` Christophe Leroy
0 siblings, 0 replies; 25+ messages in thread
From: Christophe Leroy @ 2020-01-15 5:58 UTC (permalink / raw)
To: Thomas Gleixner, LKML
Cc: x86, John Stultz, Vincenzo Frascino, Andy Lutomirski,
Paolo Bonzini, Boris Ostrovsky, Juergen Gross, Haiyang Zhang,
Sasha Levin, Ralf Baechle, Paul Burton, James Hogan,
Russell King, Catalin Marinas, Will Deacon, Mark Rutland,
Marc Zyngier
Le 14/01/2020 à 19:52, Thomas Gleixner a écrit :
> Move the time namespace indicator clock mode to the other ones for
> consistency sake.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> include/linux/clocksource.h | 3 +++
> include/vdso/datapage.h | 2 --
> kernel/time/namespace.c | 7 ++++---
> lib/vdso/gettimeofday.c | 18 ++++++++++--------
> 4 files changed, 17 insertions(+), 13 deletions(-)
>
> --- a/include/linux/clocksource.h
> +++ b/include/linux/clocksource.h
> @@ -34,6 +34,9 @@ enum vdso_clock_mode {
> VDSO_ARCH_CLOCKMODES,
> #endif
> VDSO_CLOCKMODE_MAX,
> +
> + /* Indicator for time namespace VDSO */ > + VDSO_CLOCKMODE_TIMENS = INT_MAX
Can we shorten the names a bit in order to avoid code line splits ?
WOuldn't something like VDSO_CMODE_XXX be explicit enough ?
Christophe
> };
>
> /**
> --- a/include/vdso/datapage.h
> +++ b/include/vdso/datapage.h
> @@ -21,8 +21,6 @@
> #define CS_RAW 1
> #define CS_BASES (CS_RAW + 1)
>
> -#define VCLOCK_TIMENS UINT_MAX
> -
> /**
> * struct vdso_timestamp - basetime per clock_id
> * @sec: seconds
> --- a/kernel/time/namespace.c
> +++ b/kernel/time/namespace.c
> @@ -8,6 +8,7 @@
> #include <linux/user_namespace.h>
> #include <linux/sched/signal.h>
> #include <linux/sched/task.h>
> +#include <linux/clocksource.h>
> #include <linux/seq_file.h>
> #include <linux/proc_ns.h>
> #include <linux/export.h>
> @@ -172,8 +173,8 @@ static struct timens_offset offset_from_
> * for vdso_data->clock_mode is a non-issue. The task is spin waiting for the
> * update to finish and for 'seq' to become even anyway.
> *
> - * Timens page has vdso_data->clock_mode set to VCLOCK_TIMENS which enforces
> - * the time namespace handling path.
> + * Timens page has vdso_data->clock_mode set to VDSO_CLOCKMODE_TIMENS which
> + * enforces the time namespace handling path.
> */
> static void timens_setup_vdso_data(struct vdso_data *vdata,
> struct time_namespace *ns)
> @@ -183,7 +184,7 @@ static void timens_setup_vdso_data(struc
> struct timens_offset boottime = offset_from_ts(ns->offsets.boottime);
>
> vdata->seq = 1;
> - vdata->clock_mode = VCLOCK_TIMENS;
> + vdata->clock_mode = VDSO_CLOCKMODE_TIMENS;
> offset[CLOCK_MONOTONIC] = monotonic;
> offset[CLOCK_MONOTONIC_RAW] = monotonic;
> offset[CLOCK_MONOTONIC_COARSE] = monotonic;
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -116,10 +116,10 @@ static __always_inline int do_hres(const
>
> do {
> /*
> - * Open coded to handle VCLOCK_TIMENS. Time namespace
> + * Open coded to handle VDSO_CLOCKMODE_TIMENS. Time namespace
> * enabled tasks have a special VVAR page installed which
> * has vd->seq set to 1 and vd->clock_mode set to
> - * VCLOCK_TIMENS. For non time namespace affected tasks
> + * VDSO_CLOCKMODE_TIMENS. For non time namespace affected tasks
> * this does not affect performance because if vd->seq is
> * odd, i.e. a concurrent update is in progress the extra
> * check for vd->clock_mode is just a few extra
> @@ -128,7 +128,7 @@ static __always_inline int do_hres(const
> */
> while (unlikely((seq = READ_ONCE(vd->seq)) & 1)) {
> if (IS_ENABLED(CONFIG_TIME_NS) &&
> - vd->clock_mode == VCLOCK_TIMENS)
> + vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
> return do_hres_timens(vd, clk, ts);
> cpu_relax();
> }
> @@ -200,12 +200,12 @@ static __always_inline int do_coarse(con
>
> do {
> /*
> - * Open coded to handle VCLOCK_TIMENS. See comment in
> + * Open coded to handle VDSO_CLOCK_TIMENS. See comment in
> * do_hres().
> */
> while ((seq = READ_ONCE(vd->seq)) & 1) {
> if (IS_ENABLED(CONFIG_TIME_NS) &&
> - vd->clock_mode == VCLOCK_TIMENS)
> + vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
> return do_coarse_timens(vd, clk, ts);
> cpu_relax();
> }
> @@ -292,7 +292,7 @@ static __maybe_unused int
>
> if (unlikely(tz != NULL)) {
> if (IS_ENABLED(CONFIG_TIME_NS) &&
> - vd->clock_mode == VCLOCK_TIMENS)
> + vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
> vd = __arch_get_timens_vdso_data();
>
> tz->tz_minuteswest = vd[CS_HRES_COARSE].tz_minuteswest;
> @@ -308,7 +308,8 @@ static __maybe_unused __kernel_old_time_
> const struct vdso_data *vd = __arch_get_vdso_data();
> __kernel_old_time_t t;
>
> - if (IS_ENABLED(CONFIG_TIME_NS) && vd->clock_mode == VCLOCK_TIMENS)
> + if (IS_ENABLED(CONFIG_TIME_NS) &&
> + vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
> vd = __arch_get_timens_vdso_data();
>
> t = READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
> @@ -333,7 +334,8 @@ int __cvdso_clock_getres_common(clockid_
> if (unlikely((u32) clock >= MAX_CLOCKS))
> return -1;
>
> - if (IS_ENABLED(CONFIG_TIME_NS) && vd->clock_mode == VCLOCK_TIMENS)
> + if (IS_ENABLED(CONFIG_TIME_NS) &&
> + vd->clock_mode == VDSO_CLOCKMODE_TIMENS)
> vd = __arch_get_timens_vdso_data();
>
> hrtimer_res = READ_ONCE(vd[CS_HRES_COARSE].hrtimer_res);
>
^ permalink raw reply [flat|nested] 25+ messages in thread