Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'printk-for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk

Pull printk updates from Petr Mladek:

- Different vendors have a different expectation about a console
quietness. Make it configurable to reduce bike-shedding about the
upstream default

- Decide about the message visibility when the message is stored. It
avoids races caused by a delayed console handling

- Always store printk() messages into the per-CPU buffers again in NMI.
The only exception is when flushing trace log in panic(). There the
risk of loosing messages is worth an eventual reordering

- Handle invalid %pO printf modifiers correctly

- Better handle %p printf modifier tests before crng is initialized

- Some clean up

* tag 'printk-for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk:
lib/vsprintf: Do not handle %pO[^F] as %px
printk: Fix warning about unused suppress_message_printing
printk/nmi: Prevent deadlock when accessing the main log buffer in NMI
printk: Create helper function to queue deferred console handling
printk: Split the code for storing a message into the log buffer
printk: Clean up syslog_print_all()
printk: Remove unnecessary kmalloc() from syslog during clear
printk: Make CONSOLE_LOGLEVEL_QUIET configurable
printk: make sure to print log on console.
lib/test_printf.c: accept "ptrval" as valid result for plain 'p' tests

+191 -114
+7 -3
include/linux/printk.h
··· 50 50 /* We show everything that is MORE important than this.. */ 51 51 #define CONSOLE_LOGLEVEL_SILENT 0 /* Mum's the word */ 52 52 #define CONSOLE_LOGLEVEL_MIN 1 /* Minimum loglevel we let people use */ 53 - #define CONSOLE_LOGLEVEL_QUIET 4 /* Shhh ..., when booted with "quiet" */ 54 53 #define CONSOLE_LOGLEVEL_DEBUG 10 /* issue debug messages */ 55 54 #define CONSOLE_LOGLEVEL_MOTORMOUTH 15 /* You can't shut this one up */ 56 55 57 56 /* 58 - * Default used to be hard-coded at 7, we're now allowing it to be set from 59 - * kernel config. 57 + * Default used to be hard-coded at 7, quiet used to be hardcoded at 4, 58 + * we're now allowing both to be set from kernel config. 60 59 */ 61 60 #define CONSOLE_LOGLEVEL_DEFAULT CONFIG_CONSOLE_LOGLEVEL_DEFAULT 61 + #define CONSOLE_LOGLEVEL_QUIET CONFIG_CONSOLE_LOGLEVEL_QUIET 62 62 63 63 extern int console_printk[]; 64 64 ··· 148 148 #ifdef CONFIG_PRINTK_NMI 149 149 extern void printk_nmi_enter(void); 150 150 extern void printk_nmi_exit(void); 151 + extern void printk_nmi_direct_enter(void); 152 + extern void printk_nmi_direct_exit(void); 151 153 #else 152 154 static inline void printk_nmi_enter(void) { } 153 155 static inline void printk_nmi_exit(void) { } 156 + static inline void printk_nmi_direct_enter(void) { } 157 + static inline void printk_nmi_direct_exit(void) { } 154 158 #endif /* PRINTK_NMI */ 155 159 156 160 #ifdef CONFIG_PRINTK
+8 -1
kernel/printk/internal.h
··· 19 19 #ifdef CONFIG_PRINTK 20 20 21 21 #define PRINTK_SAFE_CONTEXT_MASK 0x3fffffff 22 - #define PRINTK_NMI_DEFERRED_CONTEXT_MASK 0x40000000 22 + #define PRINTK_NMI_DIRECT_CONTEXT_MASK 0x40000000 23 23 #define PRINTK_NMI_CONTEXT_MASK 0x80000000 24 24 25 25 extern raw_spinlock_t logbuf_lock; 26 + 27 + __printf(5, 0) 28 + int vprintk_store(int facility, int level, 29 + const char *dict, size_t dictlen, 30 + const char *fmt, va_list args); 26 31 27 32 __printf(1, 0) int vprintk_default(const char *fmt, va_list args); 28 33 __printf(1, 0) int vprintk_deferred(const char *fmt, va_list args); ··· 58 53 __printk_safe_exit(); \ 59 54 local_irq_enable(); \ 60 55 } while (0) 56 + 57 + void defer_console_output(void); 61 58 62 59 #else 63 60
+102 -83
kernel/printk/printk.c
··· 349 349 */ 350 350 351 351 enum log_flags { 352 - LOG_NOCONS = 1, /* already flushed, do not print to console */ 352 + LOG_NOCONS = 1, /* suppress print, do not print to console */ 353 353 LOG_NEWLINE = 2, /* text ended with a newline */ 354 354 LOG_PREFIX = 4, /* text started with a prefix */ 355 355 LOG_CONT = 8, /* text is a fragment of a continuation line */ ··· 1352 1352 { 1353 1353 char *text; 1354 1354 int len = 0; 1355 + u64 next_seq; 1356 + u64 seq; 1357 + u32 idx; 1355 1358 1356 1359 text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); 1357 1360 if (!text) 1358 1361 return -ENOMEM; 1359 1362 1360 1363 logbuf_lock_irq(); 1361 - if (buf) { 1362 - u64 next_seq; 1363 - u64 seq; 1364 - u32 idx; 1364 + /* 1365 + * Find first record that fits, including all following records, 1366 + * into the user-provided buffer for this dump. 1367 + */ 1368 + seq = clear_seq; 1369 + idx = clear_idx; 1370 + while (seq < log_next_seq) { 1371 + struct printk_log *msg = log_from_idx(idx); 1365 1372 1366 - /* 1367 - * Find first record that fits, including all following records, 1368 - * into the user-provided buffer for this dump. 1369 - */ 1370 - seq = clear_seq; 1371 - idx = clear_idx; 1372 - while (seq < log_next_seq) { 1373 - struct printk_log *msg = log_from_idx(idx); 1373 + len += msg_print_text(msg, true, NULL, 0); 1374 + idx = log_next(idx); 1375 + seq++; 1376 + } 1374 1377 1375 - len += msg_print_text(msg, true, NULL, 0); 1376 - idx = log_next(idx); 1377 - seq++; 1378 + /* move first record forward until length fits into the buffer */ 1379 + seq = clear_seq; 1380 + idx = clear_idx; 1381 + while (len > size && seq < log_next_seq) { 1382 + struct printk_log *msg = log_from_idx(idx); 1383 + 1384 + len -= msg_print_text(msg, true, NULL, 0); 1385 + idx = log_next(idx); 1386 + seq++; 1387 + } 1388 + 1389 + /* last message fitting into this dump */ 1390 + next_seq = log_next_seq; 1391 + 1392 + len = 0; 1393 + while (len >= 0 && seq < next_seq) { 1394 + struct printk_log *msg = log_from_idx(idx); 1395 + int textlen; 1396 + 1397 + textlen = msg_print_text(msg, true, text, 1398 + LOG_LINE_MAX + PREFIX_MAX); 1399 + if (textlen < 0) { 1400 + len = textlen; 1401 + break; 1378 1402 } 1403 + idx = log_next(idx); 1404 + seq++; 1379 1405 1380 - /* move first record forward until length fits into the buffer */ 1381 - seq = clear_seq; 1382 - idx = clear_idx; 1383 - while (len > size && seq < log_next_seq) { 1384 - struct printk_log *msg = log_from_idx(idx); 1406 + logbuf_unlock_irq(); 1407 + if (copy_to_user(buf + len, text, textlen)) 1408 + len = -EFAULT; 1409 + else 1410 + len += textlen; 1411 + logbuf_lock_irq(); 1385 1412 1386 - len -= msg_print_text(msg, true, NULL, 0); 1387 - idx = log_next(idx); 1388 - seq++; 1389 - } 1390 - 1391 - /* last message fitting into this dump */ 1392 - next_seq = log_next_seq; 1393 - 1394 - len = 0; 1395 - while (len >= 0 && seq < next_seq) { 1396 - struct printk_log *msg = log_from_idx(idx); 1397 - int textlen; 1398 - 1399 - textlen = msg_print_text(msg, true, text, 1400 - LOG_LINE_MAX + PREFIX_MAX); 1401 - if (textlen < 0) { 1402 - len = textlen; 1403 - break; 1404 - } 1405 - idx = log_next(idx); 1406 - seq++; 1407 - 1408 - logbuf_unlock_irq(); 1409 - if (copy_to_user(buf + len, text, textlen)) 1410 - len = -EFAULT; 1411 - else 1412 - len += textlen; 1413 - logbuf_lock_irq(); 1414 - 1415 - if (seq < log_first_seq) { 1416 - /* messages are gone, move to next one */ 1417 - seq = log_first_seq; 1418 - idx = log_first_idx; 1419 - } 1413 + if (seq < log_first_seq) { 1414 + /* messages are gone, move to next one */ 1415 + seq = log_first_seq; 1416 + idx = log_first_idx; 1420 1417 } 1421 1418 } 1422 1419 ··· 1425 1428 1426 1429 kfree(text); 1427 1430 return len; 1431 + } 1432 + 1433 + static void syslog_clear(void) 1434 + { 1435 + logbuf_lock_irq(); 1436 + clear_seq = log_next_seq; 1437 + clear_idx = log_next_idx; 1438 + logbuf_unlock_irq(); 1428 1439 } 1429 1440 1430 1441 int do_syslog(int type, char __user *buf, int len, int source) ··· 1479 1474 break; 1480 1475 /* Clear ring buffer */ 1481 1476 case SYSLOG_ACTION_CLEAR: 1482 - syslog_print_all(NULL, 0, true); 1477 + syslog_clear(); 1483 1478 break; 1484 1479 /* Disable logging to console */ 1485 1480 case SYSLOG_ACTION_CONSOLE_OFF: ··· 1829 1824 return log_store(facility, level, lflags, 0, dict, dictlen, text, text_len); 1830 1825 } 1831 1826 1832 - asmlinkage int vprintk_emit(int facility, int level, 1833 - const char *dict, size_t dictlen, 1834 - const char *fmt, va_list args) 1827 + /* Must be called under logbuf_lock. */ 1828 + int vprintk_store(int facility, int level, 1829 + const char *dict, size_t dictlen, 1830 + const char *fmt, va_list args) 1835 1831 { 1836 1832 static char textbuf[LOG_LINE_MAX]; 1837 1833 char *text = textbuf; 1838 1834 size_t text_len; 1839 1835 enum log_flags lflags = 0; 1840 - unsigned long flags; 1841 - int printed_len; 1842 - bool in_sched = false; 1843 1836 1844 - if (level == LOGLEVEL_SCHED) { 1845 - level = LOGLEVEL_DEFAULT; 1846 - in_sched = true; 1847 - } 1848 - 1849 - boot_delay_msec(level); 1850 - printk_delay(); 1851 - 1852 - /* This stops the holder of console_sem just where we want him */ 1853 - logbuf_lock_irqsave(flags); 1854 1837 /* 1855 1838 * The printf needs to come first; we need the syslog 1856 1839 * prefix which might be passed-in as a parameter. ··· 1879 1886 if (dict) 1880 1887 lflags |= LOG_PREFIX|LOG_NEWLINE; 1881 1888 1882 - printed_len = log_output(facility, level, lflags, dict, dictlen, text, text_len); 1889 + if (suppress_message_printing(level)) 1890 + lflags |= LOG_NOCONS; 1883 1891 1892 + return log_output(facility, level, lflags, 1893 + dict, dictlen, text, text_len); 1894 + } 1895 + 1896 + asmlinkage int vprintk_emit(int facility, int level, 1897 + const char *dict, size_t dictlen, 1898 + const char *fmt, va_list args) 1899 + { 1900 + int printed_len; 1901 + bool in_sched = false; 1902 + unsigned long flags; 1903 + 1904 + if (level == LOGLEVEL_SCHED) { 1905 + level = LOGLEVEL_DEFAULT; 1906 + in_sched = true; 1907 + } 1908 + 1909 + boot_delay_msec(level); 1910 + printk_delay(); 1911 + 1912 + /* This stops the holder of console_sem just where we want him */ 1913 + logbuf_lock_irqsave(flags); 1914 + printed_len = vprintk_store(facility, level, dict, dictlen, fmt, args); 1884 1915 logbuf_unlock_irqrestore(flags); 1885 1916 1886 1917 /* If called from the scheduler, we can not call up(). */ ··· 2030 2013 const char *text, size_t len) {} 2031 2014 static size_t msg_print_text(const struct printk_log *msg, 2032 2015 bool syslog, char *buf, size_t size) { return 0; } 2033 - static bool suppress_message_printing(int level) { return false; } 2034 2016 2035 2017 #endif /* CONFIG_PRINTK */ 2036 2018 ··· 2365 2349 break; 2366 2350 2367 2351 msg = log_from_idx(console_idx); 2368 - if (suppress_message_printing(msg->level)) { 2352 + if (msg->flags & LOG_NOCONS) { 2369 2353 /* 2370 - * Skip record we have buffered and already printed 2371 - * directly to the console when we received it, and 2372 - * record that has level above the console loglevel. 2354 + * Skip record if !ignore_loglevel, and 2355 + * record has level above the console loglevel. 2373 2356 */ 2374 2357 console_idx = log_next(console_idx); 2375 2358 console_seq++; ··· 2893 2878 preempt_enable(); 2894 2879 } 2895 2880 2881 + void defer_console_output(void) 2882 + { 2883 + preempt_disable(); 2884 + __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT); 2885 + irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); 2886 + preempt_enable(); 2887 + } 2888 + 2896 2889 int vprintk_deferred(const char *fmt, va_list args) 2897 2890 { 2898 2891 int r; 2899 2892 2900 2893 r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, 0, fmt, args); 2901 - 2902 - preempt_disable(); 2903 - __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT); 2904 - irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); 2905 - preempt_enable(); 2894 + defer_console_output(); 2906 2895 2907 2896 return r; 2908 2897 }
+37 -21
kernel/printk/printk_safe.c
··· 308 308 309 309 void printk_nmi_enter(void) 310 310 { 311 - /* 312 - * The size of the extra per-CPU buffer is limited. Use it only when 313 - * the main one is locked. If this CPU is not in the safe context, 314 - * the lock must be taken on another CPU and we could wait for it. 315 - */ 316 - if ((this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK) && 317 - raw_spin_is_locked(&logbuf_lock)) { 318 - this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK); 319 - } else { 320 - this_cpu_or(printk_context, PRINTK_NMI_DEFERRED_CONTEXT_MASK); 321 - } 311 + this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK); 322 312 } 323 313 324 314 void printk_nmi_exit(void) 325 315 { 326 - this_cpu_and(printk_context, 327 - ~(PRINTK_NMI_CONTEXT_MASK | 328 - PRINTK_NMI_DEFERRED_CONTEXT_MASK)); 316 + this_cpu_and(printk_context, ~PRINTK_NMI_CONTEXT_MASK); 317 + } 318 + 319 + /* 320 + * Marks a code that might produce many messages in NMI context 321 + * and the risk of losing them is more critical than eventual 322 + * reordering. 323 + * 324 + * It has effect only when called in NMI context. Then printk() 325 + * will try to store the messages into the main logbuf directly 326 + * and use the per-CPU buffers only as a fallback when the lock 327 + * is not available. 328 + */ 329 + void printk_nmi_direct_enter(void) 330 + { 331 + if (this_cpu_read(printk_context) & PRINTK_NMI_CONTEXT_MASK) 332 + this_cpu_or(printk_context, PRINTK_NMI_DIRECT_CONTEXT_MASK); 333 + } 334 + 335 + void printk_nmi_direct_exit(void) 336 + { 337 + this_cpu_and(printk_context, ~PRINTK_NMI_DIRECT_CONTEXT_MASK); 329 338 } 330 339 331 340 #else ··· 372 363 373 364 __printf(1, 0) int vprintk_func(const char *fmt, va_list args) 374 365 { 366 + /* 367 + * Try to use the main logbuf even in NMI. But avoid calling console 368 + * drivers that might have their own locks. 369 + */ 370 + if ((this_cpu_read(printk_context) & PRINTK_NMI_DIRECT_CONTEXT_MASK) && 371 + raw_spin_trylock(&logbuf_lock)) { 372 + int len; 373 + 374 + len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, 0, fmt, args); 375 + raw_spin_unlock(&logbuf_lock); 376 + defer_console_output(); 377 + return len; 378 + } 379 + 375 380 /* Use extra buffer in NMI when logbuf_lock is taken or in safe mode. */ 376 381 if (this_cpu_read(printk_context) & PRINTK_NMI_CONTEXT_MASK) 377 382 return vprintk_nmi(fmt, args); ··· 393 370 /* Use extra buffer to prevent a recursion deadlock in safe mode. */ 394 371 if (this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK) 395 372 return vprintk_safe(fmt, args); 396 - 397 - /* 398 - * Use the main logbuf when logbuf_lock is available in NMI. 399 - * But avoid calling console drivers that might have their own locks. 400 - */ 401 - if (this_cpu_read(printk_context) & PRINTK_NMI_DEFERRED_CONTEXT_MASK) 402 - return vprintk_deferred(fmt, args); 403 373 404 374 /* No obstacles. */ 405 375 return vprintk_default(fmt, args);
+3 -1
kernel/trace/trace.c
··· 8288 8288 tracing_off(); 8289 8289 8290 8290 local_irq_save(flags); 8291 + printk_nmi_direct_enter(); 8291 8292 8292 8293 /* Simulate the iterator */ 8293 8294 trace_init_global_iter(&iter); ··· 8368 8367 for_each_tracing_cpu(cpu) { 8369 8368 atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled); 8370 8369 } 8371 - atomic_dec(&dump_running); 8370 + atomic_dec(&dump_running); 8371 + printk_nmi_direct_exit(); 8372 8372 local_irq_restore(flags); 8373 8373 } 8374 8374 EXPORT_SYMBOL_GPL(ftrace_dump);
+11
lib/Kconfig.debug
··· 30 30 usage in the kernel. That is controlled by the MESSAGE_LOGLEVEL_DEFAULT 31 31 option. 32 32 33 + config CONSOLE_LOGLEVEL_QUIET 34 + int "quiet console loglevel (1-15)" 35 + range 1 15 36 + default "4" 37 + help 38 + loglevel to use when "quiet" is passed on the kernel commandline. 39 + 40 + When "quiet" is passed on the kernel commandline this loglevel 41 + will be used as the loglevel. IOW passing "quiet" will be the 42 + equivalent of passing "loglevel=<CONSOLE_LOGLEVEL_QUIET>" 43 + 33 44 config MESSAGE_LOGLEVEL_DEFAULT 34 45 int "Default message log level (1-7)" 35 46 range 1 7
-3
lib/nmi_backtrace.c
··· 87 87 88 88 bool nmi_cpu_backtrace(struct pt_regs *regs) 89 89 { 90 - static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED; 91 90 int cpu = smp_processor_id(); 92 91 93 92 if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { 94 - arch_spin_lock(&lock); 95 93 if (regs && cpu_in_idle(instruction_pointer(regs))) { 96 94 pr_warn("NMI backtrace for cpu %d skipped: idling at %pS\n", 97 95 cpu, (void *)instruction_pointer(regs)); ··· 100 102 else 101 103 dump_stack(); 102 104 } 103 - arch_spin_unlock(&lock); 104 105 cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); 105 106 return true; 106 107 }
+22 -2
lib/test_printf.c
··· 206 206 #define PTR_WIDTH 16 207 207 #define PTR ((void *)0xffff0123456789abUL) 208 208 #define PTR_STR "ffff0123456789ab" 209 + #define PTR_VAL_NO_CRNG "(____ptrval____)" 209 210 #define ZEROS "00000000" /* hex 32 zero bits */ 210 211 211 212 static int __init ··· 217 216 218 217 nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); 219 218 220 - if (nchars != PTR_WIDTH || strncmp(buf, ZEROS, strlen(ZEROS)) != 0) 219 + if (nchars != PTR_WIDTH) 220 + return -1; 221 + 222 + if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { 223 + pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", 224 + PTR_VAL_NO_CRNG); 225 + return 0; 226 + } 227 + 228 + if (strncmp(buf, ZEROS, strlen(ZEROS)) != 0) 221 229 return -1; 222 230 223 231 return 0; ··· 237 227 #define PTR_WIDTH 8 238 228 #define PTR ((void *)0x456789ab) 239 229 #define PTR_STR "456789ab" 230 + #define PTR_VAL_NO_CRNG "(ptrval)" 240 231 241 232 static int __init 242 233 plain_format(void) ··· 256 245 257 246 nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); 258 247 259 - if (nchars != PTR_WIDTH || strncmp(buf, PTR_STR, PTR_WIDTH) == 0) 248 + if (nchars != PTR_WIDTH) 249 + return -1; 250 + 251 + if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { 252 + pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", 253 + PTR_VAL_NO_CRNG); 254 + return 0; 255 + } 256 + 257 + if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0) 260 258 return -1; 261 259 262 260 return 0;
+1
lib/vsprintf.c
··· 1942 1942 case 'F': 1943 1943 return device_node_string(buf, end, ptr, spec, fmt + 1); 1944 1944 } 1945 + break; 1945 1946 case 'x': 1946 1947 return pointer_string(buf, end, ptr, spec); 1947 1948 }