From d7b4202e0581683f1a14fe598633da0067f5241e Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 4 Sep 2012 15:12:07 -0400 Subject: time: Move timekeeper structure to timekeeper_internal.h for vsyscall changes We're going to need to access the timekeeper in update_vsyscall, so make the structure available for those who need it. Cc: Tony Luck Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Andy Lutomirski Cc: Martin Schwidefsky Cc: Paul Turner Cc: Steven Rostedt Cc: Richard Cochran Cc: Prarit Bhargava Cc: Thomas Gleixner Signed-off-by: John Stultz --- include/linux/timekeeper_internal.h | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 include/linux/timekeeper_internal.h (limited to 'include/linux/timekeeper_internal.h') diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h new file mode 100644 index 000000000000..8ba43fa8c7e6 --- /dev/null +++ b/include/linux/timekeeper_internal.h @@ -0,0 +1,68 @@ +/* + * You SHOULD NOT be including this unless you're vsyscall + * handling code or timekeeping internal code! + */ + +#ifndef _LINUX_TIMEKEEPER_INTERNAL_H +#define _LINUX_TIMEKEEPER_INTERNAL_H + +#include +#include +#include + +/* Structure holding internal timekeeping values. */ +struct timekeeper { + /* Current clocksource used for timekeeping. */ + struct clocksource *clock; + /* NTP adjusted clock multiplier */ + u32 mult; + /* The shift value of the current clocksource. */ + u32 shift; + /* Number of clock cycles in one NTP interval. */ + cycle_t cycle_interval; + /* Number of clock shifted nano seconds in one NTP interval. */ + u64 xtime_interval; + /* shifted nano seconds left over when rounding cycle_interval */ + s64 xtime_remainder; + /* Raw nano seconds accumulated per NTP interval. */ + u32 raw_interval; + + /* Current CLOCK_REALTIME time in seconds */ + u64 xtime_sec; + /* Clock shifted nano seconds */ + u64 xtime_nsec; + + /* Difference between accumulated time and NTP time in ntp + * shifted nano seconds. */ + s64 ntp_error; + /* Shift conversion between clock shifted nano seconds and + * ntp shifted nano seconds. */ + u32 ntp_error_shift; + + /* + * wall_to_monotonic is what we need to add to xtime (or xtime corrected + * for sub jiffie times) to get to monotonic time. Monotonic is pegged + * at zero at system boot time, so wall_to_monotonic will be negative, + * however, we will ALWAYS keep the tv_nsec part positive so we can use + * the usual normalization. + * + * wall_to_monotonic is moved after resume from suspend for the + * monotonic time not to jump. We need to add total_sleep_time to + * wall_to_monotonic to get the real boot based time offset. + * + * - wall_to_monotonic is no longer the boot time, getboottime must be + * used instead. + */ + struct timespec wall_to_monotonic; + /* Offset clock monotonic -> clock realtime */ + ktime_t offs_real; + /* time spent in suspend */ + struct timespec total_sleep_time; + /* Offset clock monotonic -> clock boottime */ + ktime_t offs_boot; + /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */ + struct timespec raw_time; + /* Seqlock for all timekeeper values */ + seqlock_t lock; +}; +#endif /* _LINUX_TIMEKEEPER_INTERNAL_H */ -- cgit v1.2.3 From 189374aed657e2228ad6b39ece438c9cdafc8dae Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 4 Sep 2012 15:27:48 -0400 Subject: time: Move update_vsyscall definitions to timekeeper_internal.h Since users will need to include timekeeper_internal.h, move update_vsyscall definitions to timekeeper_internal.h. Cc: Tony Luck Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Andy Lutomirski Cc: Martin Schwidefsky Cc: Paul Turner Cc: Steven Rostedt Cc: Richard Cochran Cc: Prarit Bhargava Cc: Thomas Gleixner Signed-off-by: John Stultz --- arch/ia64/kernel/time.c | 2 +- arch/powerpc/kernel/time.c | 2 +- arch/s390/kernel/time.c | 2 +- arch/x86/kernel/vsyscall_64.c | 2 +- include/linux/clocksource.h | 16 ---------------- include/linux/timekeeper_internal.h | 17 +++++++++++++++++ kernel/time.c | 2 +- 7 files changed, 22 insertions(+), 21 deletions(-) (limited to 'include/linux/timekeeper_internal.h') diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index ecc904b33c5f..acb688fe2354 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index e49e93191b69..613a830d9d50 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -73,7 +73,7 @@ /* powerpc clocksource/clockevent code */ #include -#include +#include static cycle_t rtc_read(struct clocksource *); static struct clocksource clocksource_rtc = { diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index dcec960fc724..bfb62ad312a6 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 8d141b309046..6ec8411a4710 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index fbe89e17124e..4dceaf8ae152 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -319,22 +319,6 @@ static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz) __clocksource_updatefreq_scale(cs, 1000, khz); } -#ifdef CONFIG_GENERIC_TIME_VSYSCALL -extern void -update_vsyscall(struct timespec *ts, struct timespec *wtm, - struct clocksource *c, u32 mult); -extern void update_vsyscall_tz(void); -#else -static inline void -update_vsyscall(struct timespec *ts, struct timespec *wtm, - struct clocksource *c, u32 mult) -{ -} - -static inline void update_vsyscall_tz(void) -{ -} -#endif extern void timekeeping_notify(struct clocksource *clock); diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index 8ba43fa8c7e6..9c1c2cf413a6 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -65,4 +65,21 @@ struct timekeeper { /* Seqlock for all timekeeper values */ seqlock_t lock; }; + + +#ifdef CONFIG_GENERIC_TIME_VSYSCALL +extern void +update_vsyscall(struct timespec *ts, struct timespec *wtm, + struct clocksource *c, u32 mult); +extern void update_vsyscall_tz(void); +#else +static inline void update_vsyscall(struct timespec *ts, struct timespec *wtm, + struct clocksource *c, u32 mult) +{ +} +static inline void update_vsyscall_tz(void) +{ +} +#endif + #endif /* _LINUX_TIMEKEEPER_INTERNAL_H */ diff --git a/kernel/time.c b/kernel/time.c index ba744cf80696..d226c6a3fd28 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3 From 706394211648117762edfaeffd6fc04bf3b1a75d Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 4 Sep 2012 15:34:21 -0400 Subject: time: Convert CONFIG_GENERIC_TIME_VSYSCALL to CONFIG_GENERIC_TIME_VSYSCALL_OLD To help migrate archtectures over to the new update_vsyscall method, redfine CONFIG_GENERIC_TIME_VSYSCALL as CONFIG_GENERIC_TIME_VSYSCALL_OLD Cc: Tony Luck Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Andy Lutomirski Cc: Martin Schwidefsky Cc: Paul Turner Cc: Steven Rostedt Cc: Richard Cochran Cc: Prarit Bhargava Cc: Thomas Gleixner Signed-off-by: John Stultz --- arch/ia64/Kconfig | 2 +- arch/ia64/kernel/time.c | 2 +- arch/powerpc/Kconfig | 2 +- arch/powerpc/kernel/time.c | 2 +- arch/s390/Kconfig | 2 +- arch/s390/kernel/time.c | 2 +- arch/x86/Kconfig | 2 +- arch/x86/kernel/vsyscall_64.c | 2 +- include/linux/timekeeper_internal.h | 7 ++++--- kernel/time/Kconfig | 2 +- kernel/time/timekeeping.c | 2 +- 11 files changed, 14 insertions(+), 13 deletions(-) (limited to 'include/linux/timekeeper_internal.h') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 310cf5781fad..f9e673c252a7 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -38,7 +38,7 @@ config IA64 select ARCH_TASK_STRUCT_ALLOCATOR select ARCH_THREAD_INFO_ALLOCATOR select ARCH_CLOCKSOURCE_DATA - select GENERIC_TIME_VSYSCALL + select GENERIC_TIME_VSYSCALL_OLD default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index acb688fe2354..d2f4e260db40 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -454,7 +454,7 @@ void update_vsyscall_tz(void) { } -void update_vsyscall(struct timespec *wall, struct timespec *wtm, +void update_vsyscall_old(struct timespec *wall, struct timespec *wtm, struct clocksource *c, u32 mult) { write_seqcount_begin(&fsyscall_gtod_data.seq); diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 352f416269ce..0881660c9efa 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -135,7 +135,7 @@ config PPC select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_SMP_IDLE_THREAD select GENERIC_CMOS_UPDATE - select GENERIC_TIME_VSYSCALL + select GENERIC_TIME_VSYSCALL_OLD select GENERIC_CLOCKEVENTS select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 613a830d9d50..c825809b92e7 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -712,7 +712,7 @@ static cycle_t timebase_read(struct clocksource *cs) return (cycle_t)get_tb(); } -void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, +void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm, struct clocksource *clock, u32 mult) { u64 new_tb_to_xs, new_stamp_xsec; diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 107610e01a29..ba488aa500de 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -121,7 +121,7 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_SMP_IDLE_THREAD - select GENERIC_TIME_VSYSCALL + select GENERIC_TIME_VSYSCALL_OLD select GENERIC_CLOCKEVENTS select KTIME_SCALAR if 32BIT select HAVE_ARCH_SECCOMP_FILTER diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index bfb62ad312a6..c5430bf5b5e6 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -219,7 +219,7 @@ struct clocksource * __init clocksource_default_clock(void) return &clocksource_tod; } -void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, +void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm, struct clocksource *clock, u32 mult) { if (clock != &clocksource_tod) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8ec3a1aa4abd..e3f3c1a5a744 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -93,7 +93,7 @@ config X86 select GENERIC_CLOCKEVENTS select ARCH_CLOCKSOURCE_DATA if X86_64 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC) - select GENERIC_TIME_VSYSCALL if X86_64 + select GENERIC_TIME_VSYSCALL_OLD if X86_64 select KTIME_SCALAR if X86_32 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 6ec8411a4710..77dde2953c64 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -82,7 +82,7 @@ void update_vsyscall_tz(void) vsyscall_gtod_data.sys_tz = sys_tz; } -void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, +void update_vsyscall_old(struct timespec *wall_time, struct timespec *wtm, struct clocksource *clock, u32 mult) { struct timespec monotonic; diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index 9c1c2cf413a6..a904d76a5faa 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -67,13 +67,14 @@ struct timekeeper { }; -#ifdef CONFIG_GENERIC_TIME_VSYSCALL +#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD extern void -update_vsyscall(struct timespec *ts, struct timespec *wtm, +update_vsyscall_old(struct timespec *ts, struct timespec *wtm, struct clocksource *c, u32 mult); extern void update_vsyscall_tz(void); #else -static inline void update_vsyscall(struct timespec *ts, struct timespec *wtm, +static inline void +update_vsyscall_old(struct timespec *ts, struct timespec *wtm, struct clocksource *c, u32 mult) { } diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index fd42bd452b75..489c86154d1f 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig @@ -13,7 +13,7 @@ config ARCH_CLOCKSOURCE_DATA bool # Timekeeping vsyscall support -config GENERIC_TIME_VSYSCALL +config GENERIC_TIME_VSYSCALL_OLD bool # ktime_t scalar 64bit nsec representation diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 02c19d3d8e0d..7c2851384c46 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -199,7 +199,7 @@ static void timekeeping_update(struct timekeeper *tk, bool clearntp) ntp_clear(); } xt = tk_xtime(tk); - update_vsyscall(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult); + update_vsyscall_old(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult); } /** -- cgit v1.2.3 From 576094b7f0aaf41aadab9b7d4e5bd85faa432711 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 11 Sep 2012 19:58:13 -0400 Subject: time: Introduce new GENERIC_TIME_VSYSCALL Now that we moved everyone over to GENERIC_TIME_VSYSCALL_OLD, introduce the new declaration and config option for the new update_vsyscall method. Cc: Tony Luck Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Andy Lutomirski Cc: Martin Schwidefsky Cc: Paul Turner Cc: Steven Rostedt Cc: Richard Cochran Cc: Prarit Bhargava Cc: Thomas Gleixner Signed-off-by: John Stultz --- include/linux/timekeeper_internal.h | 36 +++++++++++++++++++++++++++++------- kernel/time/Kconfig | 4 ++++ kernel/time/timekeeping.c | 14 +------------- 3 files changed, 34 insertions(+), 20 deletions(-) (limited to 'include/linux/timekeeper_internal.h') diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index a904d76a5faa..e1d558e237ec 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -66,16 +66,38 @@ struct timekeeper { seqlock_t lock; }; +static inline struct timespec tk_xtime(struct timekeeper *tk) +{ + struct timespec ts; + + ts.tv_sec = tk->xtime_sec; + ts.tv_nsec = (long)(tk->xtime_nsec >> tk->shift); + return ts; +} + + +#ifdef CONFIG_GENERIC_TIME_VSYSCALL + +extern void update_vsyscall(struct timekeeper *tk); +extern void update_vsyscall_tz(void); -#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD -extern void -update_vsyscall_old(struct timespec *ts, struct timespec *wtm, - struct clocksource *c, u32 mult); +#elif defined(CONFIG_GENERIC_TIME_VSYSCALL_OLD) + +extern void update_vsyscall_old(struct timespec *ts, struct timespec *wtm, + struct clocksource *c, u32 mult); extern void update_vsyscall_tz(void); + +static inline void update_vsyscall(struct timekeeper *tk) +{ + struct timespec xt; + + xt = tk_xtime(tk); + update_vsyscall_old(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult); +} + #else -static inline void -update_vsyscall_old(struct timespec *ts, struct timespec *wtm, - struct clocksource *c, u32 mult) + +static inline void update_vsyscall(struct timekeeper *tk) { } static inline void update_vsyscall_tz(void) diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig index 489c86154d1f..8601f0db1261 100644 --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig @@ -12,6 +12,10 @@ config CLOCKSOURCE_WATCHDOG config ARCH_CLOCKSOURCE_DATA bool +# Timekeeping vsyscall support +config GENERIC_TIME_VSYSCALL + bool + # Timekeeping vsyscall support config GENERIC_TIME_VSYSCALL_OLD bool diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 7c2851384c46..ce618010c373 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -42,15 +42,6 @@ static inline void tk_normalize_xtime(struct timekeeper *tk) } } -static struct timespec tk_xtime(struct timekeeper *tk) -{ - struct timespec ts; - - ts.tv_sec = tk->xtime_sec; - ts.tv_nsec = (long)(tk->xtime_nsec >> tk->shift); - return ts; -} - static void tk_set_xtime(struct timekeeper *tk, const struct timespec *ts) { tk->xtime_sec = ts->tv_sec; @@ -192,14 +183,11 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) /* must hold write on timekeeper.lock */ static void timekeeping_update(struct timekeeper *tk, bool clearntp) { - struct timespec xt; - if (clearntp) { tk->ntp_error = 0; ntp_clear(); } - xt = tk_xtime(tk); - update_vsyscall_old(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult); + update_vsyscall(tk); } /** -- cgit v1.2.3