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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull printk updates from Petr Mladek:

- Initialize pointer hashing using the system workqueue. It avoids
taking locks in printk()/vsprintf() code path

- Misc code clean up

* tag 'printk-for-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
printk: Mark __printk percpu data ready __ro_after_init
printk: Remove bogus comment vs. boot consoles
printk: Remove write only variable nr_ext_console_drivers
printk: Declare log_wait properly
printk: Make pr_flush() static
lib/vsprintf: Initialize vsprintf's pointer hash once the random core is ready.
lib/vsprintf: Remove static_branch_likely() from __ptr_to_hashval().
lib/vnsprintf: add const modifier for param 'bitmap'

+35 -47
-2
fs/proc/kmsg.c
··· 17 17 18 18 #include <asm/io.h> 19 19 20 - extern wait_queue_head_t log_wait; 21 - 22 20 static int kmsg_open(struct inode * inode, struct file * file) 23 21 { 24 22 return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_PROC);
-7
include/linux/printk.h
··· 169 169 #define printk_deferred_enter __printk_safe_enter 170 170 #define printk_deferred_exit __printk_safe_exit 171 171 172 - extern bool pr_flush(int timeout_ms, bool reset_on_progress); 173 - 174 172 /* 175 173 * Please don't use printk_ratelimit(), because it shares ratelimiting state 176 174 * with all other unrelated printk_ratelimit() callsites. Instead use ··· 217 219 218 220 static inline void printk_deferred_exit(void) 219 221 { 220 - } 221 - 222 - static inline bool pr_flush(int timeout_ms, bool reset_on_progress) 223 - { 224 - return true; 225 222 } 226 223 227 224 static inline int printk_ratelimit(void)
+3
include/linux/syslog.h
··· 8 8 #ifndef _LINUX_SYSLOG_H 9 9 #define _LINUX_SYSLOG_H 10 10 11 + #include <linux/wait.h> 12 + 11 13 /* Close the log. Currently a NOP. */ 12 14 #define SYSLOG_ACTION_CLOSE 0 13 15 /* Open the log. Currently a NOP. */ ··· 37 35 #define SYSLOG_FROM_PROC 1 38 36 39 37 int do_syslog(int type, char __user *buf, int count, int source); 38 + extern wait_queue_head_t log_wait; 40 39 41 40 #endif /* _LINUX_SYSLOG_H */
+4 -15
kernel/printk/printk.c
··· 220 220 } 221 221 #endif /* CONFIG_PRINTK && CONFIG_SYSCTL */ 222 222 223 - /* Number of registered extended console drivers. */ 224 - static int nr_ext_console_drivers; 225 - 226 223 /* 227 224 * Helper macros to handle lockdep when locking/unlocking console_sem. We use 228 225 * macros instead of functions so that _RET_IP_ contains useful information. ··· 430 433 * per_cpu_areas are initialised. This variable is set to true when 431 434 * it's safe to access per-CPU data. 432 435 */ 433 - static bool __printk_percpu_data_ready __read_mostly; 436 + static bool __printk_percpu_data_ready __ro_after_init; 434 437 435 438 bool printk_percpu_data_ready(void) 436 439 { ··· 2293 2296 } 2294 2297 EXPORT_SYMBOL(_printk); 2295 2298 2299 + static bool pr_flush(int timeout_ms, bool reset_on_progress); 2296 2300 static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress); 2297 2301 2298 2302 #else /* CONFIG_PRINTK */ ··· 2328 2330 { 2329 2331 } 2330 2332 static bool suppress_message_printing(int level) { return false; } 2333 + static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } 2331 2334 static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; } 2332 2335 2333 2336 #endif /* CONFIG_PRINTK */ ··· 3185 3186 console_drivers->next = newcon; 3186 3187 } 3187 3188 3188 - if (newcon->flags & CON_EXTENDED) 3189 - nr_ext_console_drivers++; 3190 - 3191 3189 newcon->dropped = 0; 3192 3190 if (newcon->flags & CON_PRINTBUFFER) { 3193 3191 /* Get a consistent copy of @syslog_seq. */ ··· 3209 3213 if (bootcon_enabled && 3210 3214 ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) && 3211 3215 !keep_bootcon) { 3212 - /* We need to iterate through all boot consoles, to make 3213 - * sure we print everything out, before we unregister them. 3214 - */ 3215 3216 for_each_console(con) 3216 3217 if (con->flags & CON_BOOT) 3217 3218 unregister_console(con); ··· 3246 3253 3247 3254 if (res) 3248 3255 goto out_disable_unlock; 3249 - 3250 - if (console->flags & CON_EXTENDED) 3251 - nr_ext_console_drivers--; 3252 3256 3253 3257 /* 3254 3258 * If this isn't the last console and it has CON_CONSDEV set, we ··· 3428 3438 * Context: Process context. May sleep while acquiring console lock. 3429 3439 * Return: true if all enabled printers are caught up. 3430 3440 */ 3431 - bool pr_flush(int timeout_ms, bool reset_on_progress) 3441 + static bool pr_flush(int timeout_ms, bool reset_on_progress) 3432 3442 { 3433 3443 return __pr_flush(NULL, timeout_ms, reset_on_progress); 3434 3444 } 3435 - EXPORT_SYMBOL(pr_flush); 3436 3445 3437 3446 /* 3438 3447 * Delayed printk version, for scheduler-internal messages:
+28 -23
lib/vsprintf.c
··· 750 750 } 751 751 early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); 752 752 753 - static DEFINE_STATIC_KEY_FALSE(filled_random_ptr_key); 753 + static bool filled_random_ptr_key __read_mostly; 754 + static siphash_key_t ptr_key __read_mostly; 755 + static void fill_ptr_key_workfn(struct work_struct *work); 756 + static DECLARE_DELAYED_WORK(fill_ptr_key_work, fill_ptr_key_workfn); 754 757 755 - static void enable_ptr_key_workfn(struct work_struct *work) 758 + static void fill_ptr_key_workfn(struct work_struct *work) 756 759 { 757 - static_branch_enable(&filled_random_ptr_key); 760 + if (!rng_is_initialized()) { 761 + queue_delayed_work(system_unbound_wq, &fill_ptr_key_work, HZ * 2); 762 + return; 763 + } 764 + 765 + get_random_bytes(&ptr_key, sizeof(ptr_key)); 766 + 767 + /* Pairs with smp_rmb() before reading ptr_key. */ 768 + smp_wmb(); 769 + WRITE_ONCE(filled_random_ptr_key, true); 758 770 } 771 + 772 + static int __init vsprintf_init_hashval(void) 773 + { 774 + fill_ptr_key_workfn(NULL); 775 + return 0; 776 + } 777 + subsys_initcall(vsprintf_init_hashval) 759 778 760 779 /* Maps a pointer to a 32 bit unique identifier. */ 761 780 static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out) 762 781 { 763 - static siphash_key_t ptr_key __read_mostly; 764 782 unsigned long hashval; 765 783 766 - if (!static_branch_likely(&filled_random_ptr_key)) { 767 - static bool filled = false; 768 - static DEFINE_SPINLOCK(filling); 769 - static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); 770 - unsigned long flags; 784 + if (!READ_ONCE(filled_random_ptr_key)) 785 + return -EBUSY; 771 786 772 - if (!system_unbound_wq || !rng_is_initialized() || 773 - !spin_trylock_irqsave(&filling, flags)) 774 - return -EAGAIN; 775 - 776 - if (!filled) { 777 - get_random_bytes(&ptr_key, sizeof(ptr_key)); 778 - queue_work(system_unbound_wq, &enable_ptr_key_work); 779 - filled = true; 780 - } 781 - spin_unlock_irqrestore(&filling, flags); 782 - } 783 - 787 + /* Pairs with smp_wmb() after writing ptr_key. */ 788 + smp_rmb(); 784 789 785 790 #ifdef CONFIG_64BIT 786 791 hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); ··· 1194 1189 } 1195 1190 1196 1191 static noinline_for_stack 1197 - char *bitmap_string(char *buf, char *end, unsigned long *bitmap, 1192 + char *bitmap_string(char *buf, char *end, const unsigned long *bitmap, 1198 1193 struct printf_spec spec, const char *fmt) 1199 1194 { 1200 1195 const int CHUNKSZ = 32; ··· 1238 1233 } 1239 1234 1240 1235 static noinline_for_stack 1241 - char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, 1236 + char *bitmap_list_string(char *buf, char *end, const unsigned long *bitmap, 1242 1237 struct printf_spec spec, const char *fmt) 1243 1238 { 1244 1239 int nr_bits = max_t(int, spec.field_width, 0);