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

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

Pull printk updates from Petr Mladek:

- Do not try to get the console lock when it is not need or useful in
panic()

- Replace the global console_suspended state by a per-console flag

- Export symbols needed for dumping the raw printk buffer in panic()

- Fix documentation of printf formats for integer types

- Moved Sergey Senozhatsky to the reviewer role

- Misc cleanups

* tag 'printk-for-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
printk: export symbols for debug modules
lib: test_scanf: Add explicit type cast to result initialization in test_number_prefix()
printk: ringbuffer: Fix truncating buffer size min_t cast
printk: Rename abandon_console_lock_in_panic() to other_cpu_in_panic()
printk: Add per-console suspended state
printk: Consolidate console deferred printing
printk: Do not take console lock for console_flush_on_panic()
printk: Keep non-panic-CPUs out of console lock
printk: Reduce console_unblank() usage in unsafe scenarios
kdb: Do not assume write() callback available
docs: printk-formats: Treat char as always unsigned
docs: printk-formats: Fix hex printing of signed values
MAINTAINERS: adjust printk/vsprintf entries

+167 -81
+5 -4
Documentation/core-api/printk-formats.rst
··· 15 15 16 16 If variable is of Type, use printk format specifier: 17 17 ------------------------------------------------------------ 18 - char %d or %x 18 + signed char %d or %hhx 19 19 unsigned char %u or %x 20 - short int %d or %x 20 + char %u or %x 21 + short int %d or %hx 21 22 unsigned short int %u or %x 22 23 int %d or %x 23 24 unsigned int %u or %x ··· 28 27 unsigned long long %llu or %llx 29 28 size_t %zu or %zx 30 29 ssize_t %zd or %zx 31 - s8 %d or %x 30 + s8 %d or %hhx 32 31 u8 %u or %x 33 - s16 %d or %x 32 + s16 %d or %hx 34 33 u16 %u or %x 35 34 s32 %d or %x 36 35 u32 %u or %x
+2 -2
MAINTAINERS
··· 17176 17176 17177 17177 PRINTK 17178 17178 M: Petr Mladek <pmladek@suse.com> 17179 - M: Sergey Senozhatsky <senozhatsky@chromium.org> 17180 17179 R: Steven Rostedt <rostedt@goodmis.org> 17181 17180 R: John Ogness <john.ogness@linutronix.de> 17181 + R: Sergey Senozhatsky <senozhatsky@chromium.org> 17182 17182 S: Maintained 17183 17183 T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git 17184 17184 F: include/linux/printk.h ··· 23072 23072 VSPRINTF 23073 23073 M: Petr Mladek <pmladek@suse.com> 23074 23074 M: Steven Rostedt <rostedt@goodmis.org> 23075 - M: Sergey Senozhatsky <senozhatsky@chromium.org> 23076 23075 R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 23077 23076 R: Rasmus Villemoes <linux@rasmusvillemoes.dk> 23077 + R: Sergey Senozhatsky <senozhatsky@chromium.org> 23078 23078 S: Maintained 23079 23079 T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git 23080 23080 F: Documentation/core-api/printk-formats.rst
+3
include/linux/console.h
··· 154 154 * receiving the printk spam for obvious reasons. 155 155 * @CON_EXTENDED: The console supports the extended output format of 156 156 * /dev/kmesg which requires a larger output buffer. 157 + * @CON_SUSPENDED: Indicates if a console is suspended. If true, the 158 + * printing callbacks must not be called. 157 159 */ 158 160 enum cons_flags { 159 161 CON_PRINTBUFFER = BIT(0), ··· 165 163 CON_ANYTIME = BIT(4), 166 164 CON_BRL = BIT(5), 167 165 CON_EXTENDED = BIT(6), 166 + CON_SUSPENDED = BIT(7), 168 167 }; 169 168 170 169 /**
+2
kernel/debug/kdb/kdb_io.c
··· 590 590 continue; 591 591 if (c == dbg_io_ops->cons) 592 592 continue; 593 + if (!c->write) 594 + continue; 593 595 /* 594 596 * Set oops_in_progress to encourage the console drivers to 595 597 * disregard their internal spin locks: in the current calling
+2
kernel/printk/internal.h
··· 103 103 u64 seq; 104 104 unsigned long dropped; 105 105 }; 106 + 107 + bool other_cpu_in_panic(void);
+149 -66
kernel/printk/printk.c
··· 88 88 static DEFINE_MUTEX(console_mutex); 89 89 90 90 /* 91 - * console_sem protects updates to console->seq and console_suspended, 91 + * console_sem protects updates to console->seq 92 92 * and also provides serialization for console printing. 93 93 */ 94 94 static DEFINE_SEMAPHORE(console_sem, 1); ··· 361 361 * paths in the console code where we end up in places I want 362 362 * locked without the console semaphore held). 363 363 */ 364 - static int console_locked, console_suspended; 364 + static int console_locked; 365 365 366 366 /* 367 367 * Array of consoles built from command line options (console=) ··· 538 538 { 539 539 return log_buf; 540 540 } 541 + EXPORT_SYMBOL_GPL(log_buf_addr_get); 541 542 542 543 /* Return log buffer size */ 543 544 u32 log_buf_len_get(void) 544 545 { 545 546 return log_buf_len; 546 547 } 548 + EXPORT_SYMBOL_GPL(log_buf_len_get); 547 549 548 550 /* 549 551 * Define how much of the log buffer we could take at maximum. The value ··· 2310 2308 preempt_enable(); 2311 2309 } 2312 2310 2313 - wake_up_klogd(); 2311 + if (in_sched) 2312 + defer_console_output(); 2313 + else 2314 + wake_up_klogd(); 2315 + 2314 2316 return printed_len; 2315 2317 } 2316 2318 EXPORT_SYMBOL(vprintk_emit); ··· 2553 2547 */ 2554 2548 void suspend_console(void) 2555 2549 { 2550 + struct console *con; 2551 + 2556 2552 if (!console_suspend_enabled) 2557 2553 return; 2558 2554 pr_info("Suspending console(s) (use no_console_suspend to debug)\n"); 2559 2555 pr_flush(1000, true); 2560 - console_lock(); 2561 - console_suspended = 1; 2562 - up_console_sem(); 2556 + 2557 + console_list_lock(); 2558 + for_each_console(con) 2559 + console_srcu_write_flags(con, con->flags | CON_SUSPENDED); 2560 + console_list_unlock(); 2561 + 2562 + /* 2563 + * Ensure that all SRCU list walks have completed. All printing 2564 + * contexts must be able to see that they are suspended so that it 2565 + * is guaranteed that all printing has stopped when this function 2566 + * completes. 2567 + */ 2568 + synchronize_srcu(&console_srcu); 2563 2569 } 2564 2570 2565 2571 void resume_console(void) 2566 2572 { 2573 + struct console *con; 2574 + 2567 2575 if (!console_suspend_enabled) 2568 2576 return; 2569 - down_console_sem(); 2570 - console_suspended = 0; 2571 - console_unlock(); 2577 + 2578 + console_list_lock(); 2579 + for_each_console(con) 2580 + console_srcu_write_flags(con, con->flags & ~CON_SUSPENDED); 2581 + console_list_unlock(); 2582 + 2583 + /* 2584 + * Ensure that all SRCU list walks have completed. All printing 2585 + * contexts must be able to see they are no longer suspended so 2586 + * that they are guaranteed to wake up and resume printing. 2587 + */ 2588 + synchronize_srcu(&console_srcu); 2589 + 2572 2590 pr_flush(1000, true); 2573 2591 } 2574 2592 ··· 2615 2585 return 0; 2616 2586 } 2617 2587 2588 + /* 2589 + * Return true if a panic is in progress on a remote CPU. 2590 + * 2591 + * On true, the local CPU should immediately release any printing resources 2592 + * that may be needed by the panic CPU. 2593 + */ 2594 + bool other_cpu_in_panic(void) 2595 + { 2596 + if (!panic_in_progress()) 2597 + return false; 2598 + 2599 + /* 2600 + * We can use raw_smp_processor_id() here because it is impossible for 2601 + * the task to be migrated to the panic_cpu, or away from it. If 2602 + * panic_cpu has already been set, and we're not currently executing on 2603 + * that CPU, then we never will be. 2604 + */ 2605 + return atomic_read(&panic_cpu) != raw_smp_processor_id(); 2606 + } 2607 + 2618 2608 /** 2619 2609 * console_lock - block the console subsystem from printing 2620 2610 * ··· 2647 2597 { 2648 2598 might_sleep(); 2649 2599 2600 + /* On panic, the console_lock must be left to the panic cpu. */ 2601 + while (other_cpu_in_panic()) 2602 + msleep(1000); 2603 + 2650 2604 down_console_sem(); 2651 - if (console_suspended) 2652 - return; 2653 2605 console_locked = 1; 2654 2606 console_may_schedule = 1; 2655 2607 } ··· 2667 2615 */ 2668 2616 int console_trylock(void) 2669 2617 { 2618 + /* On panic, the console_lock must be left to the panic cpu. */ 2619 + if (other_cpu_in_panic()) 2620 + return 0; 2670 2621 if (down_trylock_console_sem()) 2671 2622 return 0; 2672 - if (console_suspended) { 2673 - up_console_sem(); 2674 - return 0; 2675 - } 2676 2623 console_locked = 1; 2677 2624 console_may_schedule = 0; 2678 2625 return 1; ··· 2685 2634 EXPORT_SYMBOL(is_console_locked); 2686 2635 2687 2636 /* 2688 - * Return true when this CPU should unlock console_sem without pushing all 2689 - * messages to the console. This reduces the chance that the console is 2690 - * locked when the panic CPU tries to use it. 2691 - */ 2692 - static bool abandon_console_lock_in_panic(void) 2693 - { 2694 - if (!panic_in_progress()) 2695 - return false; 2696 - 2697 - /* 2698 - * We can use raw_smp_processor_id() here because it is impossible for 2699 - * the task to be migrated to the panic_cpu, or away from it. If 2700 - * panic_cpu has already been set, and we're not currently executing on 2701 - * that CPU, then we never will be. 2702 - */ 2703 - return atomic_read(&panic_cpu) != raw_smp_processor_id(); 2704 - } 2705 - 2706 - /* 2707 2637 * Check if the given console is currently capable and allowed to print 2708 2638 * records. 2709 2639 * ··· 2695 2663 short flags = console_srcu_read_flags(con); 2696 2664 2697 2665 if (!(flags & CON_ENABLED)) 2666 + return false; 2667 + 2668 + if ((flags & CON_SUSPENDED)) 2698 2669 return false; 2699 2670 2700 2671 if (!con->write) ··· 2983 2948 any_progress = true; 2984 2949 2985 2950 /* Allow panic_cpu to take over the consoles safely. */ 2986 - if (abandon_console_lock_in_panic()) 2951 + if (other_cpu_in_panic()) 2987 2952 goto abandon; 2988 2953 2989 2954 if (do_cond_resched) ··· 3017 2982 bool handover; 3018 2983 bool flushed; 3019 2984 u64 next_seq; 3020 - 3021 - if (console_suspended) { 3022 - up_console_sem(); 3023 - return; 3024 - } 3025 2985 3026 2986 /* 3027 2987 * Console drivers are called with interrupts disabled, so ··· 3075 3045 3076 3046 void console_unblank(void) 3077 3047 { 3048 + bool found_unblank = false; 3078 3049 struct console *c; 3079 3050 int cookie; 3051 + 3052 + /* 3053 + * First check if there are any consoles implementing the unblank() 3054 + * callback. If not, there is no reason to continue and take the 3055 + * console lock, which in particular can be dangerous if 3056 + * @oops_in_progress is set. 3057 + */ 3058 + cookie = console_srcu_read_lock(); 3059 + for_each_console_srcu(c) { 3060 + if ((console_srcu_read_flags(c) & CON_ENABLED) && c->unblank) { 3061 + found_unblank = true; 3062 + break; 3063 + } 3064 + } 3065 + console_srcu_read_unlock(cookie); 3066 + if (!found_unblank) 3067 + return; 3080 3068 3081 3069 /* 3082 3070 * Stop console printing because the unblank() callback may ··· 3104 3056 * In that case, attempt a trylock as best-effort. 3105 3057 */ 3106 3058 if (oops_in_progress) { 3059 + /* Semaphores are not NMI-safe. */ 3060 + if (in_nmi()) 3061 + return; 3062 + 3063 + /* 3064 + * Attempting to trylock the console lock can deadlock 3065 + * if another CPU was stopped while modifying the 3066 + * semaphore. "Hope and pray" that this is not the 3067 + * current situation. 3068 + */ 3107 3069 if (down_trylock_console_sem() != 0) 3108 3070 return; 3109 3071 } else ··· 3143 3085 */ 3144 3086 void console_flush_on_panic(enum con_flush_mode mode) 3145 3087 { 3088 + bool handover; 3089 + u64 next_seq; 3090 + 3146 3091 /* 3147 - * If someone else is holding the console lock, trylock will fail 3148 - * and may_schedule may be set. Ignore and proceed to unlock so 3149 - * that messages are flushed out. As this can be called from any 3150 - * context and we don't want to get preempted while flushing, 3151 - * ensure may_schedule is cleared. 3092 + * Ignore the console lock and flush out the messages. Attempting a 3093 + * trylock would not be useful because: 3094 + * 3095 + * - if it is contended, it must be ignored anyway 3096 + * - console_lock() and console_trylock() block and fail 3097 + * respectively in panic for non-panic CPUs 3098 + * - semaphores are not NMI-safe 3152 3099 */ 3153 - console_trylock(); 3100 + 3101 + /* 3102 + * If another context is holding the console lock, 3103 + * @console_may_schedule might be set. Clear it so that 3104 + * this context does not call cond_resched() while flushing. 3105 + */ 3154 3106 console_may_schedule = 0; 3155 3107 3156 3108 if (mode == CONSOLE_REPLAY_ALL) { ··· 3173 3105 cookie = console_srcu_read_lock(); 3174 3106 for_each_console_srcu(c) { 3175 3107 /* 3176 - * If the above console_trylock() failed, this is an 3177 - * unsynchronized assignment. But in that case, the 3108 + * This is an unsynchronized assignment, but the 3178 3109 * kernel is in "hope and pray" mode anyway. 3179 3110 */ 3180 3111 c->seq = seq; 3181 3112 } 3182 3113 console_srcu_read_unlock(cookie); 3183 3114 } 3184 - console_unlock(); 3115 + 3116 + console_flush_all(false, &next_seq, &handover); 3185 3117 } 3186 3118 3187 3119 /* ··· 3747 3679 3748 3680 /* 3749 3681 * Hold the console_lock to guarantee safe access to 3750 - * console->seq and to prevent changes to @console_suspended 3751 - * until all consoles have been processed. 3682 + * console->seq. 3752 3683 */ 3753 3684 console_lock(); 3754 3685 ··· 3755 3688 for_each_console_srcu(c) { 3756 3689 if (con && con != c) 3757 3690 continue; 3691 + /* 3692 + * If consoles are not usable, it cannot be expected 3693 + * that they make forward progress, so only increment 3694 + * @diff for usable consoles. 3695 + */ 3758 3696 if (!console_is_usable(c)) 3759 3697 continue; 3760 3698 printk_seq = c->seq; ··· 3768 3696 } 3769 3697 console_srcu_read_unlock(cookie); 3770 3698 3771 - /* 3772 - * If consoles are suspended, it cannot be expected that they 3773 - * make forward progress, so timeout immediately. @diff is 3774 - * still used to return a valid flush status. 3775 - */ 3776 - if (console_suspended) 3777 - remaining = 0; 3778 - else if (diff != last_diff && reset_on_progress) 3699 + if (diff != last_diff && reset_on_progress) 3779 3700 remaining = timeout_ms; 3780 3701 3781 3702 console_unlock(); 3782 3703 3704 + /* Note: @diff is 0 if there are no usable consoles. */ 3783 3705 if (diff == 0 || remaining == 0) 3784 3706 break; 3785 3707 ··· 3807 3741 * printer has been seen to make some forward progress. 3808 3742 * 3809 3743 * Context: Process context. May sleep while acquiring console lock. 3810 - * Return: true if all enabled printers are caught up. 3744 + * Return: true if all usable printers are caught up. 3811 3745 */ 3812 3746 static bool pr_flush(int timeout_ms, bool reset_on_progress) 3813 3747 { ··· 3864 3798 preempt_enable(); 3865 3799 } 3866 3800 3801 + /** 3802 + * wake_up_klogd - Wake kernel logging daemon 3803 + * 3804 + * Use this function when new records have been added to the ringbuffer 3805 + * and the console printing of those records has already occurred or is 3806 + * known to be handled by some other context. This function will only 3807 + * wake the logging daemon. 3808 + * 3809 + * Context: Any context. 3810 + */ 3867 3811 void wake_up_klogd(void) 3868 3812 { 3869 3813 __wake_up_klogd(PRINTK_PENDING_WAKEUP); 3870 3814 } 3871 3815 3816 + /** 3817 + * defer_console_output - Wake kernel logging daemon and trigger 3818 + * console printing in a deferred context 3819 + * 3820 + * Use this function when new records have been added to the ringbuffer, 3821 + * this context is responsible for console printing those records, but 3822 + * the current context is not allowed to perform the console printing. 3823 + * Trigger an irq_work context to perform the console printing. This 3824 + * function also wakes the logging daemon. 3825 + * 3826 + * Context: Any context. 3827 + */ 3872 3828 void defer_console_output(void) 3873 3829 { 3874 3830 /* ··· 3907 3819 3908 3820 int vprintk_deferred(const char *fmt, va_list args) 3909 3821 { 3910 - int r; 3911 - 3912 - r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); 3913 - defer_console_output(); 3914 - 3915 - return r; 3822 + return vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); 3916 3823 } 3917 3824 3918 3825 int _printk_deferred(const char *fmt, ...)
+1 -1
kernel/printk/printk_ringbuffer.c
··· 1735 1735 if (!buf || !buf_size) 1736 1736 return true; 1737 1737 1738 - data_size = min_t(u16, buf_size, len); 1738 + data_size = min_t(unsigned int, buf_size, len); 1739 1739 1740 1740 memcpy(&buf[0], data, data_size); /* LMM(copy_data:A) */ 1741 1741 return true;
+2 -7
kernel/printk/printk_safe.c
··· 38 38 * Use the main logbuf even in NMI. But avoid calling console 39 39 * drivers that might have their own locks. 40 40 */ 41 - if (this_cpu_read(printk_context) || in_nmi()) { 42 - int len; 43 - 44 - len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args); 45 - defer_console_output(); 46 - return len; 47 - } 41 + if (this_cpu_read(printk_context) || in_nmi()) 42 + return vprintk_deferred(fmt, args); 48 43 49 44 /* No obstacles. */ 50 45 return vprintk_default(fmt, args);
+1 -1
lib/test_scanf.c
··· 606 606 #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \ 607 607 do { \ 608 608 const T expect[2] = { expect0, expect1 }; \ 609 - T result[2] = {~expect[0], ~expect[1]}; \ 609 + T result[2] = { (T)~expect[0], (T)~expect[1] }; \ 610 610 \ 611 611 _test(fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]); \ 612 612 } while (0)