Loading drivers/tty/sysrq.c +2 −0 Original line number Diff line number Diff line Loading @@ -578,6 +578,7 @@ void __handle_sysrq(int key, bool check_mask) rcu_sysrq_start(); rcu_read_lock(); printk_prefer_direct_enter(); /* * Raise the apparent loglevel to maximum so that the sysrq header * is shown to provide the user with positive feedback. We do not Loading Loading @@ -619,6 +620,7 @@ void __handle_sysrq(int key, bool check_mask) pr_cont("\n"); console_loglevel = orig_log_level; } printk_prefer_direct_exit(); rcu_read_unlock(); rcu_sysrq_end(); Loading include/linux/console.h +19 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/atomic.h> #include <linux/types.h> #include <linux/mutex.h> struct vc_data; struct console_font_op; Loading Loading @@ -151,6 +152,24 @@ struct console { int cflag; uint ispeed; uint ospeed; u64 seq; unsigned long dropped; struct task_struct *thread; bool blocked; /* * The per-console lock is used by printing kthreads to synchronize * this console with callers of console_lock(). This is necessary in * order to allow printing kthreads to run in parallel to each other, * while each safely accessing the @blocked field and synchronizing * against direct printing via console_lock/console_unlock. * * Note: For synchronizing against direct printing via * console_trylock/console_unlock, see the static global * variable @console_kthreads_active. */ struct mutex lock; void *data; struct console *next; }; Loading include/linux/printk.h +56 −26 Original line number Diff line number Diff line Loading @@ -170,6 +170,11 @@ extern void __printk_safe_exit(void); #define printk_deferred_enter __printk_safe_enter #define printk_deferred_exit __printk_safe_exit extern void printk_prefer_direct_enter(void); extern void printk_prefer_direct_exit(void); extern bool pr_flush(int timeout_ms, bool reset_on_progress); /* * Please don't use printk_ratelimit(), because it shares ratelimiting state * with all other unrelated printk_ratelimit() callsites. Instead use Loading Loading @@ -220,6 +225,19 @@ static inline void printk_deferred_exit(void) { } static inline void printk_prefer_direct_enter(void) { } static inline void printk_prefer_direct_exit(void) { } static inline bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } static inline int printk_ratelimit(void) { return 0; Loading Loading @@ -277,45 +295,57 @@ static inline void printk_trigger_flush(void) #endif #ifdef CONFIG_SMP extern int __printk_cpu_trylock(void); extern void __printk_wait_on_cpu_lock(void); extern void __printk_cpu_unlock(void); extern int __printk_cpu_sync_try_get(void); extern void __printk_cpu_sync_wait(void); extern void __printk_cpu_sync_put(void); #else #define __printk_cpu_sync_try_get() true #define __printk_cpu_sync_wait() #define __printk_cpu_sync_put() #endif /* CONFIG_SMP */ /** * printk_cpu_lock_irqsave() - Acquire the printk cpu-reentrant spinning * lock and disable interrupts. * printk_cpu_sync_get_irqsave() - Disable interrupts and acquire the printk * cpu-reentrant spinning lock. * @flags: Stack-allocated storage for saving local interrupt state, * to be passed to printk_cpu_unlock_irqrestore(). * to be passed to printk_cpu_sync_put_irqrestore(). * * If the lock is owned by another CPU, spin until it becomes available. * Interrupts are restored while spinning. * * CAUTION: This function must be used carefully. It does not behave like a * typical lock. Here are important things to watch out for... * * * This function is reentrant on the same CPU. Therefore the calling * code must not assume exclusive access to data if code accessing the * data can run reentrant or within NMI context on the same CPU. * * * If there exists usage of this function from NMI context, it becomes * unsafe to perform any type of locking or spinning to wait for other * CPUs after calling this function from any context. This includes * using spinlocks or any other busy-waiting synchronization methods. */ #define printk_cpu_lock_irqsave(flags) \ #define printk_cpu_sync_get_irqsave(flags) \ for (;;) { \ local_irq_save(flags); \ if (__printk_cpu_trylock()) \ if (__printk_cpu_sync_try_get()) \ break; \ local_irq_restore(flags); \ __printk_wait_on_cpu_lock(); \ __printk_cpu_sync_wait(); \ } /** * printk_cpu_unlock_irqrestore() - Release the printk cpu-reentrant spinning * printk_cpu_sync_put_irqrestore() - Release the printk cpu-reentrant spinning * lock and restore interrupts. * @flags: Caller's saved interrupt state, from printk_cpu_lock_irqsave(). * @flags: Caller's saved interrupt state, from printk_cpu_sync_get_irqsave(). */ #define printk_cpu_unlock_irqrestore(flags) \ #define printk_cpu_sync_put_irqrestore(flags) \ do { \ __printk_cpu_unlock(); \ __printk_cpu_sync_put(); \ local_irq_restore(flags); \ } while (0) \ #else #define printk_cpu_lock_irqsave(flags) ((void)flags) #define printk_cpu_unlock_irqrestore(flags) ((void)flags) #endif /* CONFIG_SMP */ } while (0) extern int kptr_restrict; Loading kernel/hung_task.c +10 −1 Original line number Diff line number Diff line Loading @@ -127,6 +127,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) * complain: */ if (sysctl_hung_task_warnings) { printk_prefer_direct_enter(); if (sysctl_hung_task_warnings > 0) sysctl_hung_task_warnings--; pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n", Loading @@ -142,6 +144,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) if (sysctl_hung_task_all_cpu_backtrace) hung_task_show_all_bt = true; printk_prefer_direct_exit(); } touch_nmi_watchdog(); Loading Loading @@ -204,12 +208,17 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) } unlock: rcu_read_unlock(); if (hung_task_show_lock) if (hung_task_show_lock) { printk_prefer_direct_enter(); debug_show_all_locks(); printk_prefer_direct_exit(); } if (hung_task_show_all_bt) { hung_task_show_all_bt = false; printk_prefer_direct_enter(); trigger_all_cpu_backtrace(); printk_prefer_direct_exit(); } if (hung_task_call_panic) Loading kernel/panic.c +4 −0 Original line number Diff line number Diff line Loading @@ -560,6 +560,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, { disable_trace_on_warning(); printk_prefer_direct_enter(); if (file) pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", raw_smp_processor_id(), current->pid, file, line, Loading Loading @@ -597,6 +599,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, /* Just a warning, don't kill lockdep. */ add_taint(taint, LOCKDEP_STILL_OK); printk_prefer_direct_exit(); } #ifndef __WARN_FLAGS Loading Loading
drivers/tty/sysrq.c +2 −0 Original line number Diff line number Diff line Loading @@ -578,6 +578,7 @@ void __handle_sysrq(int key, bool check_mask) rcu_sysrq_start(); rcu_read_lock(); printk_prefer_direct_enter(); /* * Raise the apparent loglevel to maximum so that the sysrq header * is shown to provide the user with positive feedback. We do not Loading Loading @@ -619,6 +620,7 @@ void __handle_sysrq(int key, bool check_mask) pr_cont("\n"); console_loglevel = orig_log_level; } printk_prefer_direct_exit(); rcu_read_unlock(); rcu_sysrq_end(); Loading
include/linux/console.h +19 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/atomic.h> #include <linux/types.h> #include <linux/mutex.h> struct vc_data; struct console_font_op; Loading Loading @@ -151,6 +152,24 @@ struct console { int cflag; uint ispeed; uint ospeed; u64 seq; unsigned long dropped; struct task_struct *thread; bool blocked; /* * The per-console lock is used by printing kthreads to synchronize * this console with callers of console_lock(). This is necessary in * order to allow printing kthreads to run in parallel to each other, * while each safely accessing the @blocked field and synchronizing * against direct printing via console_lock/console_unlock. * * Note: For synchronizing against direct printing via * console_trylock/console_unlock, see the static global * variable @console_kthreads_active. */ struct mutex lock; void *data; struct console *next; }; Loading
include/linux/printk.h +56 −26 Original line number Diff line number Diff line Loading @@ -170,6 +170,11 @@ extern void __printk_safe_exit(void); #define printk_deferred_enter __printk_safe_enter #define printk_deferred_exit __printk_safe_exit extern void printk_prefer_direct_enter(void); extern void printk_prefer_direct_exit(void); extern bool pr_flush(int timeout_ms, bool reset_on_progress); /* * Please don't use printk_ratelimit(), because it shares ratelimiting state * with all other unrelated printk_ratelimit() callsites. Instead use Loading Loading @@ -220,6 +225,19 @@ static inline void printk_deferred_exit(void) { } static inline void printk_prefer_direct_enter(void) { } static inline void printk_prefer_direct_exit(void) { } static inline bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } static inline int printk_ratelimit(void) { return 0; Loading Loading @@ -277,45 +295,57 @@ static inline void printk_trigger_flush(void) #endif #ifdef CONFIG_SMP extern int __printk_cpu_trylock(void); extern void __printk_wait_on_cpu_lock(void); extern void __printk_cpu_unlock(void); extern int __printk_cpu_sync_try_get(void); extern void __printk_cpu_sync_wait(void); extern void __printk_cpu_sync_put(void); #else #define __printk_cpu_sync_try_get() true #define __printk_cpu_sync_wait() #define __printk_cpu_sync_put() #endif /* CONFIG_SMP */ /** * printk_cpu_lock_irqsave() - Acquire the printk cpu-reentrant spinning * lock and disable interrupts. * printk_cpu_sync_get_irqsave() - Disable interrupts and acquire the printk * cpu-reentrant spinning lock. * @flags: Stack-allocated storage for saving local interrupt state, * to be passed to printk_cpu_unlock_irqrestore(). * to be passed to printk_cpu_sync_put_irqrestore(). * * If the lock is owned by another CPU, spin until it becomes available. * Interrupts are restored while spinning. * * CAUTION: This function must be used carefully. It does not behave like a * typical lock. Here are important things to watch out for... * * * This function is reentrant on the same CPU. Therefore the calling * code must not assume exclusive access to data if code accessing the * data can run reentrant or within NMI context on the same CPU. * * * If there exists usage of this function from NMI context, it becomes * unsafe to perform any type of locking or spinning to wait for other * CPUs after calling this function from any context. This includes * using spinlocks or any other busy-waiting synchronization methods. */ #define printk_cpu_lock_irqsave(flags) \ #define printk_cpu_sync_get_irqsave(flags) \ for (;;) { \ local_irq_save(flags); \ if (__printk_cpu_trylock()) \ if (__printk_cpu_sync_try_get()) \ break; \ local_irq_restore(flags); \ __printk_wait_on_cpu_lock(); \ __printk_cpu_sync_wait(); \ } /** * printk_cpu_unlock_irqrestore() - Release the printk cpu-reentrant spinning * printk_cpu_sync_put_irqrestore() - Release the printk cpu-reentrant spinning * lock and restore interrupts. * @flags: Caller's saved interrupt state, from printk_cpu_lock_irqsave(). * @flags: Caller's saved interrupt state, from printk_cpu_sync_get_irqsave(). */ #define printk_cpu_unlock_irqrestore(flags) \ #define printk_cpu_sync_put_irqrestore(flags) \ do { \ __printk_cpu_unlock(); \ __printk_cpu_sync_put(); \ local_irq_restore(flags); \ } while (0) \ #else #define printk_cpu_lock_irqsave(flags) ((void)flags) #define printk_cpu_unlock_irqrestore(flags) ((void)flags) #endif /* CONFIG_SMP */ } while (0) extern int kptr_restrict; Loading
kernel/hung_task.c +10 −1 Original line number Diff line number Diff line Loading @@ -127,6 +127,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) * complain: */ if (sysctl_hung_task_warnings) { printk_prefer_direct_enter(); if (sysctl_hung_task_warnings > 0) sysctl_hung_task_warnings--; pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n", Loading @@ -142,6 +144,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) if (sysctl_hung_task_all_cpu_backtrace) hung_task_show_all_bt = true; printk_prefer_direct_exit(); } touch_nmi_watchdog(); Loading Loading @@ -204,12 +208,17 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) } unlock: rcu_read_unlock(); if (hung_task_show_lock) if (hung_task_show_lock) { printk_prefer_direct_enter(); debug_show_all_locks(); printk_prefer_direct_exit(); } if (hung_task_show_all_bt) { hung_task_show_all_bt = false; printk_prefer_direct_enter(); trigger_all_cpu_backtrace(); printk_prefer_direct_exit(); } if (hung_task_call_panic) Loading
kernel/panic.c +4 −0 Original line number Diff line number Diff line Loading @@ -560,6 +560,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, { disable_trace_on_warning(); printk_prefer_direct_enter(); if (file) pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", raw_smp_processor_id(), current->pid, file, line, Loading Loading @@ -597,6 +599,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, /* Just a warning, don't kill lockdep. */ add_taint(taint, LOCKDEP_STILL_OK); printk_prefer_direct_exit(); } #ifndef __WARN_FLAGS Loading