[PATCH] printk: Test using all three timestamps: mono, boot, real

From: Petr Mladek
Date: Thu Aug 20 2020 - 04:18:57 EST


Test timekeeper enhancements proposed at
https://lore.kernel.org/r/20200814101933.574326079@xxxxxxxxxxxxx

Allow to store and show all three timestamp (mono, boot, real).

It is not final solution. The prefix takes 83 characters that might
make the real text invisible or hard to read. Fragments of seconds
are lost in when printing real time timestamp. Offset is not provided
for crashdump tools.

Only syslog interface is supported. The log can be seen on consoles
or via:

dmesg -S

Signed-off-by: Petr Mladek <pmladek@xxxxxxxx>
---
kernel/printk/printk.c | 40 ++++++++++++++++++++++++++--------------
1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 9b75f6bfc333..329f3595b024 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -366,7 +366,7 @@ enum log_flags {
};

struct printk_log {
- u64 ts_nsec; /* timestamp in nanoseconds */
+ struct ktime_timestamps ts; /* timestamps */
u16 len; /* length of entire record */
u16 text_len; /* length of text buffer */
u16 dict_len; /* length of dictionary buffer */
@@ -443,7 +443,7 @@ static u64 clear_seq;
static u32 clear_idx;

#ifdef CONFIG_PRINTK_CALLER
-#define PREFIX_MAX 48
+#define PREFIX_MAX 48+14+21
#else
#define PREFIX_MAX 32
#endif
@@ -614,7 +614,7 @@ static u32 truncate_msg(u16 *text_len, u16 *trunc_msg_len,

/* insert record into the buffer, discard old ones, update heads */
static int log_store(u32 caller_id, int facility, int level,
- enum log_flags flags, u64 ts_nsec,
+ enum log_flags flags, struct ktime_timestamps *ts,
const char *dict, u16 dict_len,
const char *text, u16 text_len)
{
@@ -657,10 +657,10 @@ static int log_store(u32 caller_id, int facility, int level,
msg->facility = facility;
msg->level = level & 7;
msg->flags = flags & 0x1f;
- if (ts_nsec > 0)
- msg->ts_nsec = ts_nsec;
+ if (ts)
+ msg->ts = *ts;
else
- msg->ts_nsec = local_clock();
+ ktime_get_fast_timestamps(&msg->ts);
#ifdef CONFIG_PRINTK_CALLER
msg->caller_id = caller_id;
#endif
@@ -726,7 +726,7 @@ static void append_char(char **pp, char *e, char c)
static ssize_t msg_print_ext_header(char *buf, size_t size,
struct printk_log *msg, u64 seq)
{
- u64 ts_usec = msg->ts_nsec;
+ u64 ts_usec = msg->ts.mono;
char caller[20];
#ifdef CONFIG_PRINTK_CALLER
u32 id = msg->caller_id;
@@ -1090,8 +1090,8 @@ void log_buf_vmcoreinfo_setup(void)
* parse it and detect any changes to structure down the line.
*/
VMCOREINFO_STRUCT_SIZE(printk_log);
- VMCOREINFO_OFFSET(printk_log, ts_nsec);
- VMCOREINFO_OFFSET(printk_log, len);
+/* VMCOREINFO_OFFSET(printk_log, ts);
+ */ VMCOREINFO_OFFSET(printk_log, len);
VMCOREINFO_OFFSET(printk_log, text_len);
VMCOREINFO_OFFSET(printk_log, dict_len);
#ifdef CONFIG_PRINTK_CALLER
@@ -1308,6 +1308,14 @@ static size_t print_time(u64 ts, char *buf)
(unsigned long)ts, rem_nsec / 1000);
}

+static size_t print_real_time(u64 ts, char *buf)
+{
+ u64 ts_nsec = ts / 1000000000;
+
+ return sprintf(buf, "[%ptT]", &ts_nsec);
+}
+
+
#ifdef CONFIG_PRINTK_CALLER
static size_t print_caller(u32 id, char *buf)
{
@@ -1329,8 +1337,12 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog,
if (syslog)
len = print_syslog((msg->facility << 3) | msg->level, buf);

- if (time)
- len += print_time(msg->ts_nsec, buf + len);
+
+ if (time) {
+ len += print_time(msg->ts.mono, buf + len);
+ len += print_time(msg->ts.boot, buf + len);
+ len += print_real_time(msg->ts.real, buf + len);
+ }

len += print_caller(msg->caller_id, buf + len);

@@ -1855,7 +1867,7 @@ static struct cont {
char buf[LOG_LINE_MAX];
size_t len; /* length == 0 means unused buffer */
u32 caller_id; /* printk_caller_id() of first print */
- u64 ts_nsec; /* time of first print */
+ struct ktime_timestamps ts; /* time of first print */
u8 level; /* log level of first message */
u8 facility; /* log facility of first message */
enum log_flags flags; /* prefix, newline flags */
@@ -1867,7 +1879,7 @@ static void cont_flush(void)
return;

log_store(cont.caller_id, cont.facility, cont.level, cont.flags,
- cont.ts_nsec, NULL, 0, cont.buf, cont.len);
+ &cont.ts, NULL, 0, cont.buf, cont.len);
cont.len = 0;
}

@@ -1884,7 +1896,7 @@ static bool cont_add(u32 caller_id, int facility, int level,
cont.facility = facility;
cont.level = level;
cont.caller_id = caller_id;
- cont.ts_nsec = local_clock();
+ ktime_get_fast_timestamps(&cont.ts);
cont.flags = flags;
}

--
2.26.2