printk: Add new timestamps
v12 cover printk: Add new timestamps
printk.time=1/CONFIG_PRINTK_TIME=1 adds a unmodified local hardware clock timestamp to printk messages. The local hardware clock loses time each day making it difficult to determine exactly when an issue has occurred in the kernel log, and making it difficult to determine how kernel and hardware issues relate to each other in real time.
Add monotonic, boottime, and real clock timestamps in addition to the existing local hardware clock timestamp.
Changes from v12: In 1/3 remove typecast. In 3/3, Reword Kconfig names, simplify timestamp logic and remove recursive code.
Prarit Bhargava (2):
time: Make fast functions return 0 before timekeeping is initialized
printk: Add monotonic, boottime, and realtime timestamps
Thomas Gleixner (1):
timekeeping: Provide NMI safe access to clock realtime
Documentation/admin-guide/kernel-parameters.txt | 6 +- include/linux/timekeeper_internal.h | 6 +- include/linux/timekeeping.h | 1 + kernel/printk/printk.c | 130 +++++++++++++++++++++++- kernel/time/timekeeping.c | 60 +++++++++-- lib/Kconfig.debug | 48 ++++++++- 6 files changed, 233 insertions(+), 18 deletions(-)
Signature · 1 line
1.8.5.5
PATCH v12 1/3 time: Make fast functions return 0 before timekeeping is initialized
printk timestamps will be extended to include mono and boot time by using the fast timekeeping functions ktime_get_mono|boot_fast_ns() functions. The functions can return garbage before timekeeping is initialized resulting in garbage timestamps.
The fast time functions must return 0 before timekeeping is initialized.
[v12]: Remove typecast.
--- kernel/time/timekeeping.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)
kernel/time/timekeeping.c +21 -14
@@ -60,8 +60,27 @@ struct tk_fast {struct tk_read_base base[2 ]; }; -static struct tk_fast tk_fast_mono____cacheline_aligned ; -static struct tk_fast tk_fast_raw____cacheline_aligned ; +/* Suspend-time cycles value for halted fast timekeeper. */ +static u64 cycles_at_suspend; + +static u64 dummy_clock_read (struct clocksource *cs) +{ +return cycles_at_suspend; +} + +static struct clocksource dummy_clock = { + .read = dummy_clock_read, +}; + +static struct tk_fast tk_fast_mono____cacheline_aligned = { + .base[0 ] = { .clock = &dummy_clock, }, + .base[1 ] = { .clock = &dummy_clock, }, +}; + +static struct tk_fast tk_fast_raw____cacheline_aligned = { + .base[0 ] = { .clock = &dummy_clock, }, + .base[1 ] = { .clock = &dummy_clock, }, +};/* flag for if timekeeping is suspended */ int __read_mostly timekeeping_suspended;
@@ -477,18 +496,6 @@ u64 notrace ktime_get_boot_fast_ns(void) }EXPORT_SYMBOL_GPL (ktime_get_boot_fast_ns); -/* Suspend-time cycles value for halted fast timekeeper. */ -static u64 cycles_at_suspend; - -static u64 dummy_clock_read (struct clocksource *cs) -{ -return cycles_at_suspend; -} - -static struct clocksource dummy_clock = { - .read = dummy_clock_read, -}; -/** * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource. * @tk: Timekeeper to snapshot.
Signature · 1 line
1.8.5.5
PATCH v12 2/3 timekeeping: Provide NMI safe access to clock realtime
In reply to Prarit BhargavaFrom: Thomas Gleixner <[email protected]>
The configurable printk timestamping wants access to clock realtime. Right now there is no ktime_get_real_fast_ns() accessor because reading the monotonic base and the realtime offset cannot be done atomically. Contrary to boot time this offset can change during runtime and cause half updated readouts.
struct tk_read_base was fully packed when the fast timekeeper access was implemented. commit ceea5e3771ed ("time: Fix clock->read(clock) race around clocksource changes") removed the 'read' function pointer from the structure, but of course left the comment stale.
So now the structure can fit a new 64bit member w/o violating the cache line constraints.
Add real_base to tk_read_base and update it in the fast timekeeper update sequence.
Implement an accessor which follows the same scheme as the accessor to clock monotonic, but uses the new real_base to access clock real time.
The runtime overhead for updating real_base is minimal as it just adds two cache hot values and stores into the same an already dirtied cache line.
--- include/linux/timekeeper_internal.h | 6 +++++- include/linux/timekeeping.h | 1 + kernel/time/timekeeping.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-)
include/linux/timekeeper_internal.h +5 -1
@@ -13,19 +13,22 @@/** * struct tk_read_base - base structure for timekeeping readout * @clock: Current clocksource used for timekeeping. -* @read: Read function of @clock * @mask: Bitmask for two's complement subtraction of non 64bit clocks * @cycle_last: @clock cycle value at last update * @mult: (NTP adjusted) multiplier for scaled math conversion * @shift: Shift value for scaled math conversion * @xtime_nsec: Shifted (fractional) nano seconds offset for readout * @base: ktime_t (nanoseconds) base time for readout +* @base_real: Nanoseconds base value for clock REALTIME readout * * This struct has size 56 byte on 64 bit. Together with a seqcount it * occupies a single 64byte cache line. * * The struct is separate from struct timekeeper as it is also used * for a fast NMI safe accessors. +* +* @base_real is for the fast NMI safe accessor to allow reading clock +* realtime from any context. */ struct tk_read_base {struct clocksource *clock;
@@ -35,6 +38,7 @@ struct tk_read_base {u32 shift;u64 xtime_nsec;ktime_t base; +u64 base_real; };/**
include/linux/timekeeping.h +1 -0
@@ -239,6 +239,7 @@ static inline u64 ktime_get_raw_ns(void)extern u64 ktime_get_mono_fast_ns (void );extern u64 ktime_get_raw_fast_ns (void );extern u64 ktime_get_boot_fast_ns (void ); +extern u64 ktime_get_real_fast_ns (void );/* * Timespec interfaces utilizing the ktime based ones
kernel/time/timekeeping.c +35 -0
@@ -496,6 +496,39 @@ u64 notrace ktime_get_boot_fast_ns(void) }EXPORT_SYMBOL_GPL (ktime_get_boot_fast_ns); + +/* +* See comment for __ktime_get_fast_ns() vs. timestamp ordering +*/ +static __always_inline u64 __ktime_get_real_fast_ns(struct tk_fast *tkf) +{ +struct tk_read_base *tkr; +unsigned int seq; +u64 now; + +do { + seq =raw_read_seqcount_latch (&tkf->seq); + tkr = tkf->base + (seq &0x01 ); + now =ktime_to_ns (tkr->base_real); + + now +=timekeeping_delta_to_ns (tkr, +clocksource_delta ( +tk_clock_read (tkr), + tkr->cycle_last, + tkr->mask)); + }while (read_seqcount_retry (&tkf->seq, seq)); + +return now; +} + +/** +* ktime_get_real_fast_ns: - NMI safe and fast access to clock realtime. +*/ +u64 ktime_get_real_fast_ns (void ) +{ +return __ktime_get_real_fast_ns (&tk_fast_mono); +} +/** * halt_fast_timekeeper - Prevent fast timekeeper from accessing clocksource. * @tk: Timekeeper to snapshot.
@@ -514,6 +547,7 @@ static void halt_fast_timekeeper(struct timekeeper *tk)memcpy (&tkr_dummy, tkr,sizeof (tkr_dummy)); cycles_at_suspend =tk_clock_read (tkr); tkr_dummy.clock = &dummy_clock; + tkr_dummy.base_real = tkr->base + tk->offs_real;update_fast_timekeeper (&tkr_dummy, &tk_fast_mono); tkr = &tk->tkr_raw;
@@ -661,6 +695,7 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)update_vsyscall (tk);update_pvclock_gtod (tk, action &TK_CLOCK_WAS_SET ); + tk->tkr_mono.base_real = tk->tkr_mono.base + tk->offs_real;update_fast_timekeeper (&tk->tkr_mono, &tk_fast_mono);update_fast_timekeeper (&tk->tkr_raw, &tk_fast_raw);
Signature · 1 line
1.8.5.5
PATCH v12 3/3 printk: Add monotonic, boottime, and realtime timestamps
In reply to Prarit Bhargavaprintk.time=1/CONFIG_PRINTK_TIME=1 adds a unmodified local hardware clock timestamp to printk messages. The local hardware clock loses time each day making it difficult to determine exactly when an issue has occurred in the kernel log, and making it difficult to determine how kernel and hardware issues relate to each other in real time.
Make printk output different timestamps by adding options for no timestamp, the local hardware clock, the monotonic clock, the boottime clock, and the real clock. Allow a user to pick one of the clocks by using the printk.time kernel parameter. Output the type of clock in /sys/module/printk/parameters/time so userspace programs can interpret the timestamp.
v2: Use peterz's suggested Kconfig options. Merge patchset together. Fix i386 !CONFIG_PRINTK builds.
v3: Fixed x86_64_defconfig. Added printk_time_type enum and printk_time_str for better output. Added BOOTTIME clock functionality.
v4: Fix messages, add additional printk.time options, and fix configs.
v5: Renaming of structures, and allow printk_time_set() to evaluate substrings of entries (eg: allow 'r', 'real', 'realtime'). From peterz, make fast functions return 0 until timekeeping is initialized (removes timekeeping_active & ktime_get_boot|real_log_ts() suggested by
tglx and adds ktime_get_real_offset()). Switch to a function pointer
for printk_get_ts() and reference fast functions. Make timestamp_sources enum match choice options for CONFIG_PRINTK_TIME (adds PRINTK_TIME_UNDEFINED).
v6: Define PRINTK_TIME_UNDEFINED for !CONFIG_PRINTK builds. Separate timekeeping changes into separate patch. Minor include file cleanup.
v7: Add default case to printk_set_timestamp() and add PRINTK_TIME_DEBUG for users that want to set timestamp to different values during runtime. Add jstultz' Kconfig to avoid defconfig churn.
v8: Add CONFIG_PRINTK_TIME_DEBUG to allow timestamp runtime switching. Rename PRINTK_TIME_DISABLE to PRINTK_TIME_DISABLED. Rename printk_set_timestamp() to printk_set_ts_func(). Separate printk_set_ts_func() and printk_get_first_ts() portions. Rename param functions. Adjust configs, enum, and timestamp_sources_str to be 0-4. Add mention realtime clock is UTC in Documentation.
v9: Fix typo. Add __ktime_get_real_fast_ns_unsafe().
v10: Remove time parameter restrictions.
v11: Rework using tglx's real time patch
v12: Reword Kconfig names. Simplify timestamp logic and remove recursive code.
--- Documentation/admin-guide/kernel-parameters.txt | 6 +- kernel/printk/printk.c | 130 +++++++++++++++++++++++- lib/Kconfig.debug | 48 ++++++++- 3 files changed, 176 insertions(+), 8 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +4 -2
@@ -3211,8 +3211,10 @@ ratelimit - ratelimit the logging Default: ratelimit - printk.time= Show timing data prefixed to each printk message line - Format: <bool> (1/Y/y=enable, 0/N/n=disable) + printk.time= Show timestamp prefixed to each printk message line + Format: <string> + (0/N/n/disable, 1/Y/y/local, + b/boot, m/monotonic, r/realtime (in UTC)) processor.max_cstate= [HW,ACPI] Limit processor to maximum C-state
kernel/printk/printk.c +125 -5
165 lines not on this page · raw message
lib/Kconfig.debug +47 -1
59 lines not on this page · raw message
Signature · 1 line
1.8.5.5
Re: [PATCH 3/3 v12] printk: Add monotonic, boottime, and realtime timestamps
Quoted 26 lines · Prarit Bhargava
printk.time=1/CONFIG_PRINTK_TIME=1 adds a unmodified local hardware clock timestamp to printk messages. The local hardware clock loses time each day making it difficult to determine exactly when an issue has occurred in the kernel log, and making it difficult to determine how kernel and hardware issues relate to each other in real time.
Make printk output different timestamps by adding options for no timestamp, the local hardware clock, the monotonic clock, the boottime clock, and the real clock. Allow a user to pick one of the clocks by using the printk.time kernel parameter. Output the type of clock in
/sys/module/printk/parameters/timeso userspace programs can interpret the timestamp.kernel/printk/printk.c +5
-0@@ -1201,14 +1204,130 @@ static inline void boot_delay_msec(int level) +static int printk_time =CONFIG_PRINTK_TIME_TYPE ; + +static int printk_set_ts_source (enum timestamp_sources ts_source) +{ +int err =0 ;
kernel/printk/printk.c static size_t msg_print_text(const struct printk_log *msg, · line 1983
Quoted 4 lines
kernel/printk/printk.c +1
-0@@ -1861,6 +1980,7 @@ static size_t msg_print_text(const struct printk_log *msg, bool syslog, char *buf, size_t size) { return 0; }static bool suppress_message_printing (int level) {return false; } +static int printk_time;
I worried if the variable should have got initialized. But it seems to be a relic from an older version. The variable is not longer used and needed when CONFIG_PRINTK is not defined. It is proved by gcc:
CC kernel/printk/printk.okernel/printk/printk.c:1983:12: warning: ‘printk_time’ defined but not used [-Wunused-variable]
static int printk_time;
kernel/printk/printk.c static size_t msg_print_text(const struct printk_log *msg, · line 1986
Quoted 3 lines
kernel/printk/printk.c +0
-0#endif /* CONFIG_PRINTK */ #ifdef CONFIG_EARLY_PRINTK
Otherwise that patch looks fine. With the unused variable removed, feel free to use:
Best Regards,
Petr
Re: [PATCH 3/3 v12] printk: Add monotonic, boottime, and realtime timestamps
Quoted 36 lines · Petr Mladek
Quoted 26 lines · Prarit Bhargava
printk.time=1/CONFIG_PRINTK_TIME=1 adds a unmodified local hardware clock timestamp to printk messages. The local hardware clock loses time each day making it difficult to determine exactly when an issue has occurred in the kernel log, and making it difficult to determine how kernel and hardware issues relate to each other in real time.
Make printk output different timestamps by adding options for no timestamp, the local hardware clock, the monotonic clock, the boottime clock, and the real clock. Allow a user to pick one of the clocks by using the printk.time kernel parameter. Output the type of clock in
/sys/module/printk/parameters/timeso userspace programs can interpret the timestamp.kernel/printk/printk.c +5
-0@@ -1201,14 +1204,130 @@ static inline void boot_delay_msec(int level) +static int printk_time =CONFIG_PRINTK_TIME_TYPE ; + +static int printk_set_ts_source (enum timestamp_sources ts_source) +{ +int err =0 ;kernel/printk/printk.c static size_t msg_print_text(const struct printk_log *msg, · line 1983
Quoted 4 lines
kernel/printk/printk.c +1
-0@@ -1861,6 +1980,7 @@ static size_t msg_print_text(const struct printk_log *msg, bool syslog, char *buf, size_t size) { return 0; }static bool suppress_message_printing (int level) {return false; } +static int printk_time;I worried if the variable should have got initialized. But it seems to be a relic from an older version. The variable is not longer used and needed when
CONFIG_PRINTKis not defined. It is proved by gcc:
Quoted 4 lines
CC
kernel/printk/printk.okernel/printk/printk.c:1983:12: warning: ‘printk_time’ defined but not used [-Wunused-variable]
static intprintk_time;
I didn't catch that :(. tglx, want a v14?
P.
Quoted 13 lines
kernel/printk/printk.c static size_t msg_print_text(const struct printk_log *msg, · line 1986
Quoted 4 lines
kernel/printk/printk.c +0
-0#endif /* CONFIG_PRINTK */ #ifdef CONFIG_EARLY_PRINTK Otherwise that patch looks fine. With the unused variable removed, feel free to use:
Reviewed-by Petr Mladek <[email protected]>Best Regards,
Petr
Re: [PATCH 3/3 v12] printk: Add monotonic, boottime, and realtime timestamps
In reply to Prarit BhargavaHi!
Quoted 54 lines
lib/Kconfig.debug +40
-1@@ -8,12 +8,58 @@ config PRINTK_TIME messages to be added to the output of the syslog() system call and at the console. +choice + prompt "printk default clock timestamp" if PRINTK_TIME + default PRINTK_TIME_LOCAL if PRINTK_TIME + help + This option is selected by setting one of + PRINTK_TIME_[DISABLE|LOCAL|BOOT|MONO|REAL] and causes time stamps of + the printk() messages to be added to the output of the syslog() + system call and at the console. + The timestamp is always recorded internally, and exported to /dev/kmsg. This flag just specifies if the timestamp should be included, not that the timestamp is recorded. The behavior is also controlled by the kernel command line - parameter printk.time=1. See Documentation/admin-guide/kernel-parameters.rst + parameter printk.time. See + Documentation/admin-guide/kernel-parameters.rst + +config PRINTK_TIME_LOCAL + bool "Local Clock" + help + Selecting this option causes the time stamps of printk() to be + stamped with the unadjusted hardware clock. + +config PRINTK_TIME_BOOT + bool "Boot Time Clock" + help + Selecting this option causes the time stamps of printk() to be + stamped with the adjusted boottime clock. + +config PRINTK_TIME_MONO + bool "Monotonic Clock" + help + Selecting this option causes the time stamps of printk() to be + stamped with the adjusted monotonic clock. + +config PRINTK_TIME_REAL + bool "Real Time Clock" + help + Selecting this option causes the time stamps of printk() to be + stamped with the adjusted realtime clock (UTC). +endchoice + +config PRINTK_TIME_TYPE + int + depends on PRINTK
lib/Kconfig.debug config PRINTK_TIME · line 65
Quoted 10 lines
lib/Kconfig.debug +7
-0+ range 0 4 + default 0 if !PRINTK_TIME + default 1 if PRINTK_TIME_LOCAL + default 2 if PRINTK_TIME_BOOT + default 3 if PRINTK_TIME_MONO + default 4 if PRINTK_TIME_REAL + config CONSOLE_LOGLEVEL_DEFAULT int "Default console loglevel (1-15)"
Come on, you don't need to ask user just to set default value to be overriden by command line. This is not nearly important enough.
Drop it. You can still use CONFIG_CMDLINE="...".
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html