aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/core-api/printk-formats.rst8
-rw-r--r--include/linux/kern_levels.h2
-rw-r--r--include/linux/printk.h1
-rw-r--r--kernel/printk/printk.c90
-rw-r--r--lib/Kconfig.debug17
-rw-r--r--lib/vsprintf.c1
6 files changed, 96 insertions, 23 deletions
diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index a7fae4538946..c37ec7cd9c06 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -13,6 +13,10 @@ Integer types
13 13
14 If variable is of Type, use printk format specifier: 14 If variable is of Type, use printk format specifier:
15 ------------------------------------------------------------ 15 ------------------------------------------------------------
16 char %hhd or %hhx
17 unsigned char %hhu or %hhx
18 short int %hd or %hx
19 unsigned short int %hu or %hx
16 int %d or %x 20 int %d or %x
17 unsigned int %u or %x 21 unsigned int %u or %x
18 long %ld or %lx 22 long %ld or %lx
@@ -21,6 +25,10 @@ Integer types
21 unsigned long long %llu or %llx 25 unsigned long long %llu or %llx
22 size_t %zu or %zx 26 size_t %zu or %zx
23 ssize_t %zd or %zx 27 ssize_t %zd or %zx
28 s8 %hhd or %hhx
29 u8 %hhu or %hhx
30 s16 %hd or %hx
31 u16 %hu or %hx
24 s32 %d or %x 32 s32 %d or %x
25 u32 %u or %x 33 u32 %u or %x
26 s64 %lld or %llx 34 s64 %lld or %llx
diff --git a/include/linux/kern_levels.h b/include/linux/kern_levels.h
index d237fe854ad9..bf2389c26ae3 100644
--- a/include/linux/kern_levels.h
+++ b/include/linux/kern_levels.h
@@ -14,7 +14,7 @@
14#define KERN_INFO KERN_SOH "6" /* informational */ 14#define KERN_INFO KERN_SOH "6" /* informational */
15#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */ 15#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
16 16
17#define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel */ 17#define KERN_DEFAULT "" /* the default kernel loglevel */
18 18
19/* 19/*
20 * Annotation for a "continued" line of log printout (only done after a 20 * Annotation for a "continued" line of log printout (only done after a
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 02b5c115d89b..d7c77ed1a4cb 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -18,7 +18,6 @@ static inline int printk_get_level(const char *buffer)
18 if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { 18 if (buffer[0] == KERN_SOH_ASCII && buffer[1]) {
19 switch (buffer[1]) { 19 switch (buffer[1]) {
20 case '0' ... '7': 20 case '0' ... '7':
21 case 'd': /* KERN_DEFAULT */
22 case 'c': /* KERN_CONT */ 21 case 'c': /* KERN_CONT */
23 return buffer[1]; 22 return buffer[1];
24 } 23 }
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index d3d170374ceb..8eee85bb2687 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -344,7 +344,6 @@ static int console_msg_format = MSG_FORMAT_DEFAULT;
344 344
345enum log_flags { 345enum log_flags {
346 LOG_NEWLINE = 2, /* text ended with a newline */ 346 LOG_NEWLINE = 2, /* text ended with a newline */
347 LOG_PREFIX = 4, /* text started with a prefix */
348 LOG_CONT = 8, /* text is a fragment of a continuation line */ 347 LOG_CONT = 8, /* text is a fragment of a continuation line */
349}; 348};
350 349
@@ -356,6 +355,9 @@ struct printk_log {
356 u8 facility; /* syslog facility */ 355 u8 facility; /* syslog facility */
357 u8 flags:5; /* internal record flags */ 356 u8 flags:5; /* internal record flags */
358 u8 level:3; /* syslog level */ 357 u8 level:3; /* syslog level */
358#ifdef CONFIG_PRINTK_CALLER
359 u32 caller_id; /* thread id or processor id */
360#endif
359} 361}
360#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 362#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
361__packed __aligned(4) 363__packed __aligned(4)
@@ -422,7 +424,11 @@ static u64 exclusive_console_stop_seq;
422static u64 clear_seq; 424static u64 clear_seq;
423static u32 clear_idx; 425static u32 clear_idx;
424 426
427#ifdef CONFIG_PRINTK_CALLER
428#define PREFIX_MAX 48
429#else
425#define PREFIX_MAX 32 430#define PREFIX_MAX 32
431#endif
426#define LOG_LINE_MAX (1024 - PREFIX_MAX) 432#define LOG_LINE_MAX (1024 - PREFIX_MAX)
427 433
428#define LOG_LEVEL(v) ((v) & 0x07) 434#define LOG_LEVEL(v) ((v) & 0x07)
@@ -577,7 +583,7 @@ static u32 truncate_msg(u16 *text_len, u16 *trunc_msg_len,
577} 583}
578 584
579/* insert record into the buffer, discard old ones, update heads */ 585/* insert record into the buffer, discard old ones, update heads */
580static int log_store(int facility, int level, 586static int log_store(u32 caller_id, int facility, int level,
581 enum log_flags flags, u64 ts_nsec, 587 enum log_flags flags, u64 ts_nsec,
582 const char *dict, u16 dict_len, 588 const char *dict, u16 dict_len,
583 const char *text, u16 text_len) 589 const char *text, u16 text_len)
@@ -625,6 +631,9 @@ static int log_store(int facility, int level,
625 msg->ts_nsec = ts_nsec; 631 msg->ts_nsec = ts_nsec;
626 else 632 else
627 msg->ts_nsec = local_clock(); 633 msg->ts_nsec = local_clock();
634#ifdef CONFIG_PRINTK_CALLER
635 msg->caller_id = caller_id;
636#endif
628 memset(log_dict(msg) + dict_len, 0, pad_len); 637 memset(log_dict(msg) + dict_len, 0, pad_len);
629 msg->len = size; 638 msg->len = size;
630 639
@@ -688,12 +697,21 @@ static ssize_t msg_print_ext_header(char *buf, size_t size,
688 struct printk_log *msg, u64 seq) 697 struct printk_log *msg, u64 seq)
689{ 698{
690 u64 ts_usec = msg->ts_nsec; 699 u64 ts_usec = msg->ts_nsec;
700 char caller[20];
701#ifdef CONFIG_PRINTK_CALLER
702 u32 id = msg->caller_id;
703
704 snprintf(caller, sizeof(caller), ",caller=%c%u",
705 id & 0x80000000 ? 'C' : 'T', id & ~0x80000000);
706#else
707 caller[0] = '\0';
708#endif
691 709
692 do_div(ts_usec, 1000); 710 do_div(ts_usec, 1000);
693 711
694 return scnprintf(buf, size, "%u,%llu,%llu,%c;", 712 return scnprintf(buf, size, "%u,%llu,%llu,%c%s;",
695 (msg->facility << 3) | msg->level, seq, ts_usec, 713 (msg->facility << 3) | msg->level, seq, ts_usec,
696 msg->flags & LOG_CONT ? 'c' : '-'); 714 msg->flags & LOG_CONT ? 'c' : '-', caller);
697} 715}
698 716
699static ssize_t msg_print_ext_body(char *buf, size_t size, 717static ssize_t msg_print_ext_body(char *buf, size_t size,
@@ -1038,6 +1056,9 @@ void log_buf_vmcoreinfo_setup(void)
1038 VMCOREINFO_OFFSET(printk_log, len); 1056 VMCOREINFO_OFFSET(printk_log, len);
1039 VMCOREINFO_OFFSET(printk_log, text_len); 1057 VMCOREINFO_OFFSET(printk_log, text_len);
1040 VMCOREINFO_OFFSET(printk_log, dict_len); 1058 VMCOREINFO_OFFSET(printk_log, dict_len);
1059#ifdef CONFIG_PRINTK_CALLER
1060 VMCOREINFO_OFFSET(printk_log, caller_id);
1061#endif
1041} 1062}
1042#endif 1063#endif
1043 1064
@@ -1236,10 +1257,23 @@ static size_t print_time(u64 ts, char *buf)
1236{ 1257{
1237 unsigned long rem_nsec = do_div(ts, 1000000000); 1258 unsigned long rem_nsec = do_div(ts, 1000000000);
1238 1259
1239 return sprintf(buf, "[%5lu.%06lu] ", 1260 return sprintf(buf, "[%5lu.%06lu]",
1240 (unsigned long)ts, rem_nsec / 1000); 1261 (unsigned long)ts, rem_nsec / 1000);
1241} 1262}
1242 1263
1264#ifdef CONFIG_PRINTK_CALLER
1265static size_t print_caller(u32 id, char *buf)
1266{
1267 char caller[12];
1268
1269 snprintf(caller, sizeof(caller), "%c%u",
1270 id & 0x80000000 ? 'C' : 'T', id & ~0x80000000);
1271 return sprintf(buf, "[%6s]", caller);
1272}
1273#else
1274#define print_caller(id, buf) 0
1275#endif
1276
1243static size_t print_prefix(const struct printk_log *msg, bool syslog, 1277static size_t print_prefix(const struct printk_log *msg, bool syslog,
1244 bool time, char *buf) 1278 bool time, char *buf)
1245{ 1279{
@@ -1247,8 +1281,17 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog,
1247 1281
1248 if (syslog) 1282 if (syslog)
1249 len = print_syslog((msg->facility << 3) | msg->level, buf); 1283 len = print_syslog((msg->facility << 3) | msg->level, buf);
1284
1250 if (time) 1285 if (time)
1251 len += print_time(msg->ts_nsec, buf + len); 1286 len += print_time(msg->ts_nsec, buf + len);
1287
1288 len += print_caller(msg->caller_id, buf + len);
1289
1290 if (IS_ENABLED(CONFIG_PRINTK_CALLER) || time) {
1291 buf[len++] = ' ';
1292 buf[len] = '\0';
1293 }
1294
1252 return len; 1295 return len;
1253} 1296}
1254 1297
@@ -1752,6 +1795,12 @@ static inline void printk_delay(void)
1752 } 1795 }
1753} 1796}
1754 1797
1798static inline u32 printk_caller_id(void)
1799{
1800 return in_task() ? task_pid_nr(current) :
1801 0x80000000 + raw_smp_processor_id();
1802}
1803
1755/* 1804/*
1756 * Continuation lines are buffered, and not committed to the record buffer 1805 * Continuation lines are buffered, and not committed to the record buffer
1757 * until the line is complete, or a race forces it. The line fragments 1806 * until the line is complete, or a race forces it. The line fragments
@@ -1761,7 +1810,7 @@ static inline void printk_delay(void)
1761static struct cont { 1810static struct cont {
1762 char buf[LOG_LINE_MAX]; 1811 char buf[LOG_LINE_MAX];
1763 size_t len; /* length == 0 means unused buffer */ 1812 size_t len; /* length == 0 means unused buffer */
1764 struct task_struct *owner; /* task of first print*/ 1813 u32 caller_id; /* printk_caller_id() of first print */
1765 u64 ts_nsec; /* time of first print */ 1814 u64 ts_nsec; /* time of first print */
1766 u8 level; /* log level of first message */ 1815 u8 level; /* log level of first message */
1767 u8 facility; /* log facility of first message */ 1816 u8 facility; /* log facility of first message */
@@ -1773,12 +1822,13 @@ static void cont_flush(void)
1773 if (cont.len == 0) 1822 if (cont.len == 0)
1774 return; 1823 return;
1775 1824
1776 log_store(cont.facility, cont.level, cont.flags, cont.ts_nsec, 1825 log_store(cont.caller_id, cont.facility, cont.level, cont.flags,
1777 NULL, 0, cont.buf, cont.len); 1826 cont.ts_nsec, NULL, 0, cont.buf, cont.len);
1778 cont.len = 0; 1827 cont.len = 0;
1779} 1828}
1780 1829
1781static bool cont_add(int facility, int level, enum log_flags flags, const char *text, size_t len) 1830static bool cont_add(u32 caller_id, int facility, int level,
1831 enum log_flags flags, const char *text, size_t len)
1782{ 1832{
1783 /* If the line gets too long, split it up in separate records. */ 1833 /* If the line gets too long, split it up in separate records. */
1784 if (cont.len + len > sizeof(cont.buf)) { 1834 if (cont.len + len > sizeof(cont.buf)) {
@@ -1789,7 +1839,7 @@ static bool cont_add(int facility, int level, enum log_flags flags, const char *
1789 if (!cont.len) { 1839 if (!cont.len) {
1790 cont.facility = facility; 1840 cont.facility = facility;
1791 cont.level = level; 1841 cont.level = level;
1792 cont.owner = current; 1842 cont.caller_id = caller_id;
1793 cont.ts_nsec = local_clock(); 1843 cont.ts_nsec = local_clock();
1794 cont.flags = flags; 1844 cont.flags = flags;
1795 } 1845 }
@@ -1809,13 +1859,15 @@ static bool cont_add(int facility, int level, enum log_flags flags, const char *
1809 1859
1810static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len) 1860static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len)
1811{ 1861{
1862 const u32 caller_id = printk_caller_id();
1863
1812 /* 1864 /*
1813 * If an earlier line was buffered, and we're a continuation 1865 * If an earlier line was buffered, and we're a continuation
1814 * write from the same process, try to add it to the buffer. 1866 * write from the same context, try to add it to the buffer.
1815 */ 1867 */
1816 if (cont.len) { 1868 if (cont.len) {
1817 if (cont.owner == current && (lflags & LOG_CONT)) { 1869 if (cont.caller_id == caller_id && (lflags & LOG_CONT)) {
1818 if (cont_add(facility, level, lflags, text, text_len)) 1870 if (cont_add(caller_id, facility, level, lflags, text, text_len))
1819 return text_len; 1871 return text_len;
1820 } 1872 }
1821 /* Otherwise, make sure it's flushed */ 1873 /* Otherwise, make sure it's flushed */
@@ -1828,12 +1880,13 @@ static size_t log_output(int facility, int level, enum log_flags lflags, const c
1828 1880
1829 /* If it doesn't end in a newline, try to buffer the current line */ 1881 /* If it doesn't end in a newline, try to buffer the current line */
1830 if (!(lflags & LOG_NEWLINE)) { 1882 if (!(lflags & LOG_NEWLINE)) {
1831 if (cont_add(facility, level, lflags, text, text_len)) 1883 if (cont_add(caller_id, facility, level, lflags, text, text_len))
1832 return text_len; 1884 return text_len;
1833 } 1885 }
1834 1886
1835 /* Store it in the record log */ 1887 /* Store it in the record log */
1836 return log_store(facility, level, lflags, 0, dict, dictlen, text, text_len); 1888 return log_store(caller_id, facility, level, lflags, 0,
1889 dict, dictlen, text, text_len);
1837} 1890}
1838 1891
1839/* Must be called under logbuf_lock. */ 1892/* Must be called under logbuf_lock. */
@@ -1867,9 +1920,6 @@ int vprintk_store(int facility, int level,
1867 case '0' ... '7': 1920 case '0' ... '7':
1868 if (level == LOGLEVEL_DEFAULT) 1921 if (level == LOGLEVEL_DEFAULT)
1869 level = kern_level - '0'; 1922 level = kern_level - '0';
1870 /* fallthrough */
1871 case 'd': /* KERN_DEFAULT */
1872 lflags |= LOG_PREFIX;
1873 break; 1923 break;
1874 case 'c': /* KERN_CONT */ 1924 case 'c': /* KERN_CONT */
1875 lflags |= LOG_CONT; 1925 lflags |= LOG_CONT;
@@ -1884,7 +1934,7 @@ int vprintk_store(int facility, int level,
1884 level = default_message_loglevel; 1934 level = default_message_loglevel;
1885 1935
1886 if (dict) 1936 if (dict)
1887 lflags |= LOG_PREFIX|LOG_NEWLINE; 1937 lflags |= LOG_NEWLINE;
1888 1938
1889 return log_output(facility, level, lflags, 1939 return log_output(facility, level, lflags,
1890 dict, dictlen, text, text_len); 1940 dict, dictlen, text, text_len);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index e718487c97c3..91ed81250fb3 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -17,6 +17,23 @@ config PRINTK_TIME
17 The behavior is also controlled by the kernel command line 17 The behavior is also controlled by the kernel command line
18 parameter printk.time=1. See Documentation/admin-guide/kernel-parameters.rst 18 parameter printk.time=1. See Documentation/admin-guide/kernel-parameters.rst
19 19
20config PRINTK_CALLER
21 bool "Show caller information on printks"
22 depends on PRINTK
23 help
24 Selecting this option causes printk() to add a caller "thread id" (if
25 in task context) or a caller "processor id" (if not in task context)
26 to every message.
27
28 This option is intended for environments where multiple threads
29 concurrently call printk() for many times, for it is difficult to
30 interpret without knowing where these lines (or sometimes individual
31 line which was divided into multiple lines due to race) came from.
32
33 Since toggling after boot makes the code racy, currently there is
34 no option to enable/disable at the kernel command line parameter or
35 sysfs interface.
36
20config CONSOLE_LOGLEVEL_DEFAULT 37config CONSOLE_LOGLEVEL_DEFAULT
21 int "Default console loglevel (1-15)" 38 int "Default console loglevel (1-15)"
22 range 1 15 39 range 1 15
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 30b00de4f321..791b6fa36905 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1931,7 +1931,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
1931 * (legacy clock framework) of the clock 1931 * (legacy clock framework) of the clock
1932 * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address 1932 * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address
1933 * (legacy clock framework) of the clock 1933 * (legacy clock framework) of the clock
1934 * - 'Cr' For a clock, it prints the current rate of the clock
1935 * - 'G' For flags to be printed as a collection of symbolic strings that would 1934 * - 'G' For flags to be printed as a collection of symbolic strings that would
1936 * construct the specific value. Supported flags given by option: 1935 * construct the specific value. Supported flags given by option:
1937 * p page flags (see struct page) given as pointer to unsigned long 1936 * p page flags (see struct page) given as pointer to unsigned long