diff options
author | Kay Sievers <kay@vrfy.org> | 2012-05-09 22:30:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-09 23:35:06 -0400 |
commit | 649e6ee33f73ba1c4f2492c6de9aff2254b540cb (patch) | |
tree | f7fe1b11f4eb7c306a07a8893980a5d34a0886d9 | |
parent | 5c5d5ca51abd728c8de3be43ffd6bb00f977bfcd (diff) |
printk() - restore timestamp printing at console output
The output of the timestamps got lost with the conversion of the
kmsg buffer to records; restore the old behavior.
Document, that CONFIG_PRINTK_TIME now only controls the output of
the timestamps in the syslog() system call and on the console, and
not the recording of the timestamps.
Cc: Joe Perches <joe@perches.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Sasha Levin <levinsasha928@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Reported-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Kay Sievers <kay@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | kernel/printk.c | 43 | ||||
-rw-r--r-- | lib/Kconfig.debug | 16 |
2 files changed, 36 insertions, 23 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 301fb0f09fbf..572941d7e5f7 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -786,6 +786,22 @@ static bool printk_time; | |||
786 | #endif | 786 | #endif |
787 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); | 787 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); |
788 | 788 | ||
789 | static size_t prepend_timestamp(unsigned long long t, char *buf) | ||
790 | { | ||
791 | unsigned long rem_ns; | ||
792 | |||
793 | if (!printk_time) | ||
794 | return 0; | ||
795 | |||
796 | if (!buf) | ||
797 | return 15; | ||
798 | |||
799 | rem_ns = do_div(t, 1000000000); | ||
800 | |||
801 | return sprintf(buf, "[%5lu.%06lu] ", | ||
802 | (unsigned long) t, rem_ns / 1000); | ||
803 | } | ||
804 | |||
789 | static int syslog_print_line(u32 idx, char *text, size_t size) | 805 | static int syslog_print_line(u32 idx, char *text, size_t size) |
790 | { | 806 | { |
791 | struct log *msg; | 807 | struct log *msg; |
@@ -800,9 +816,7 @@ static int syslog_print_line(u32 idx, char *text, size_t size) | |||
800 | len++; | 816 | len++; |
801 | if (msg->level > 99) | 817 | if (msg->level > 99) |
802 | len++; | 818 | len++; |
803 | 819 | len += prepend_timestamp(0, NULL); | |
804 | if (printk_time) | ||
805 | len += 15; | ||
806 | 820 | ||
807 | len += msg->text_len; | 821 | len += msg->text_len; |
808 | len++; | 822 | len++; |
@@ -810,15 +824,7 @@ static int syslog_print_line(u32 idx, char *text, size_t size) | |||
810 | } | 824 | } |
811 | 825 | ||
812 | len = sprintf(text, "<%u>", msg->level); | 826 | len = sprintf(text, "<%u>", msg->level); |
813 | 827 | len += prepend_timestamp(msg->ts_nsec, text + len); | |
814 | if (printk_time) { | ||
815 | unsigned long long t = msg->ts_nsec; | ||
816 | unsigned long rem_ns = do_div(t, 1000000000); | ||
817 | |||
818 | len += sprintf(text + len, "[%5lu.%06lu] ", | ||
819 | (unsigned long) t, rem_ns / 1000); | ||
820 | } | ||
821 | |||
822 | if (len + msg->text_len > size) | 828 | if (len + msg->text_len > size) |
823 | return -EINVAL; | 829 | return -EINVAL; |
824 | memcpy(text + len, log_text(msg), msg->text_len); | 830 | memcpy(text + len, log_text(msg), msg->text_len); |
@@ -1741,7 +1747,7 @@ again: | |||
1741 | for (;;) { | 1747 | for (;;) { |
1742 | struct log *msg; | 1748 | struct log *msg; |
1743 | static char text[LOG_LINE_MAX]; | 1749 | static char text[LOG_LINE_MAX]; |
1744 | size_t len; | 1750 | size_t len, l; |
1745 | int level; | 1751 | int level; |
1746 | 1752 | ||
1747 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 1753 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
@@ -1761,10 +1767,13 @@ again: | |||
1761 | 1767 | ||
1762 | msg = log_from_idx(console_idx); | 1768 | msg = log_from_idx(console_idx); |
1763 | level = msg->level & 7; | 1769 | level = msg->level & 7; |
1764 | len = msg->text_len; | 1770 | |
1765 | if (len+1 >= sizeof(text)) | 1771 | len = prepend_timestamp(msg->ts_nsec, text); |
1766 | len = sizeof(text)-1; | 1772 | l = msg->text_len; |
1767 | memcpy(text, log_text(msg), len); | 1773 | if (len + l + 1 >= sizeof(text)) |
1774 | l = sizeof(text) - len - 1; | ||
1775 | memcpy(text + len, log_text(msg), l); | ||
1776 | len += l; | ||
1768 | text[len++] = '\n'; | 1777 | text[len++] = '\n'; |
1769 | 1778 | ||
1770 | console_idx = log_next(console_idx); | 1779 | console_idx = log_next(console_idx); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ef8192bc0c33..e11934177030 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -3,12 +3,16 @@ config PRINTK_TIME | |||
3 | bool "Show timing information on printks" | 3 | bool "Show timing information on printks" |
4 | depends on PRINTK | 4 | depends on PRINTK |
5 | help | 5 | help |
6 | Selecting this option causes timing information to be | 6 | Selecting this option causes time stamps of the printk() |
7 | included in printk output. This allows you to measure | 7 | messages to be added to the output of the syslog() system |
8 | the interval between kernel operations, including bootup | 8 | call and at the console. |
9 | operations. This is useful for identifying long delays | 9 | |
10 | in kernel startup. Or add printk.time=1 at boot-time. | 10 | The timestamp is always recorded internally, and exported |
11 | See Documentation/kernel-parameters.txt | 11 | to /dev/kmsg. This flag just specifies if the timestamp should |
12 | be included, not that the timestamp is recorded. | ||
13 | |||
14 | The behavior is also controlled by the kernel command line | ||
15 | parameter printk.time=1. See Documentation/kernel-parameters.txt | ||
12 | 16 | ||
13 | config DEFAULT_MESSAGE_LOGLEVEL | 17 | config DEFAULT_MESSAGE_LOGLEVEL |
14 | int "Default message log level (1-7)" | 18 | int "Default message log level (1-7)" |