diff options
| author | Vasily Gorbik <gor@linux.ibm.com> | 2024-11-29 12:56:48 +0100 |
|---|---|---|
| committer | Alexander Gordeev <agordeev@linux.ibm.com> | 2025-01-26 17:24:02 +0100 |
| commit | 70309dc77699dd598ade67ca7fca5a17ac3275c1 (patch) | |
| tree | d48aac0ddeee8d19cad9ea38815ec870e224398f /arch/s390/boot | |
| parent | b2a992a55fb60395d1ab9a4d4b2ea3783e3b7ad9 (diff) | |
s390/boot: Add timestamps to early boot messages
When CONFIG_PRINTK_TIME is enabled, add timestamps to boot messages in
the same format as regular printk. Timestamps appear only with earlyprintk
and are stored in the boot messages ring buffer, but are not propagated
to main kernel messages (if earlyprintk is not enabled). This prevents
double timestamps in the output.
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Diffstat (limited to 'arch/s390/boot')
| -rw-r--r-- | arch/s390/boot/printk.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/s390/boot/printk.c b/arch/s390/boot/printk.c index abfa05cf9562..b4c66fa667d5 100644 --- a/arch/s390/boot/printk.c +++ b/arch/s390/boot/printk.c @@ -190,12 +190,29 @@ static void boot_console_earlyprintk(const char *buf) return; buf = printk_skip_level(buf); /* print debug messages only when bootdebug is enabled */ - if (level == LOGLEVEL_DEBUG && (!bootdebug || !bootdebug_filter_match(buf))) + if (level == LOGLEVEL_DEBUG && (!bootdebug || !bootdebug_filter_match(skip_timestamp(buf)))) return; if (boot_ignore_loglevel || level < boot_console_loglevel) sclp_early_printk(buf); } +static char *add_timestamp(char *buf) +{ +#ifdef CONFIG_PRINTK_TIME + union tod_clock *boot_clock = (union tod_clock *)&get_lowcore()->boot_clock; + unsigned long ns = tod_to_ns(get_tod_clock() - boot_clock->tod); + char ts[MAX_NUMLEN]; + + *buf++ = '['; + buf += strpad(buf, MAX_NUMLEN, as_dec(ts, ns / NSEC_PER_SEC, 0), 5, 0, 0); + *buf++ = '.'; + buf += strpad(buf, MAX_NUMLEN, as_dec(ts, (ns % NSEC_PER_SEC) / NSEC_PER_USEC, 0), 6, 1, 0); + *buf++ = ']'; + *buf++ = ' '; +#endif + return buf; +} + #define va_arg_len_type(args, lenmod, typemod) \ ((lenmod == 'l') ? va_arg(args, typemod long) : \ (lenmod == 'h') ? (typemod short)va_arg(args, typemod int) : \ @@ -215,10 +232,10 @@ int boot_printk(const char *fmt, ...) ssize_t len; int pad; - if (!printk_get_level(fmt)) { - *p++ = KERN_SOH_ASCII; - *p++ = '0' + MESSAGE_LOGLEVEL_DEFAULT; - } + *p++ = KERN_SOH_ASCII; + *p++ = printk_get_level(fmt) ?: '0' + MESSAGE_LOGLEVEL_DEFAULT; + p = add_timestamp(p); + fmt = printk_skip_level(fmt); va_start(args, fmt); for (; p < end && *fmt; fmt++) { |
