Loading kernel/printk/printk.c +118 −66 Original line number Diff line number Diff line Loading @@ -3134,42 +3134,40 @@ static inline void printk_kthreads_check_locked(void) { } #endif /* CONFIG_PRINTK */ /* * Print out all remaining records to all consoles. * Print out one record for each console. * * @do_cond_resched is set by the caller. It can be true only in schedulable * context. * * @next_seq is set to the sequence number after the last available record. * The value is valid only when this function returns true. It means that all * usable consoles are completely flushed. * The value is valid only when all usable consoles were flushed. It is * when the function returns true (can do the job) and @try_again parameter * is set to false, see below. * * @handover will be set to true if a printk waiter has taken over the * console_lock, in which case the caller is no longer holding the * console_lock. Otherwise it is set to false. * * Returns true when there was at least one usable console and all messages * were flushed to all usable consoles. A returned false informs the caller * that everything was not flushed (either there were no usable consoles or * another context has taken over printing or it is a panic situation and this * is not the panic CPU). Regardless the reason, the caller should assume it * is not useful to immediately try again. * @try_again will be set to true when it still makes sense to call this * function again. The function could do the job, see the return value. * And some consoles still make progress. * * Returns true when the function could do the job. Some consoles are usable, * and there was no takeover and no panic_on_other_cpu(). * * Requires the console_lock. */ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover) static bool console_flush_one_record(bool do_cond_resched, u64 *next_seq, bool *handover, bool *try_again) { struct console_flush_type ft; bool any_usable = false; struct console *con; bool any_progress; int cookie; *next_seq = 0; *handover = false; do { any_progress = false; *try_again = false; printk_get_console_flush_type(&ft); Loading @@ -3180,8 +3178,8 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove bool progress; /* * console_flush_all() is only responsible for nbcon * consoles when the nbcon consoles cannot print via * console_flush_one_record() is only responsible for * nbcon consoles when the nbcon consoles cannot print via * their atomic or threaded flushing. */ if ((flags & CON_NBCON) && (ft.nbcon_atomic || ft.nbcon_offload)) Loading @@ -3205,7 +3203,7 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove * is already released. */ if (*handover) return false; goto fail; /* Track the next of the highest seq flushed. */ if (printk_seq > *next_seq) Loading @@ -3213,25 +3211,70 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove if (!progress) continue; any_progress = true; /* * An usable console made a progress. There might still be * pending messages. */ *try_again = true; /* Allow panic_cpu to take over the consoles safely. */ if (panic_on_other_cpu()) goto abandon; goto fail_srcu; if (do_cond_resched) cond_resched(); } console_srcu_read_unlock(cookie); } while (any_progress); return any_usable; abandon: fail_srcu: console_srcu_read_unlock(cookie); fail: *try_again = false; return false; } /* * Print out all remaining records to all consoles. * * @do_cond_resched is set by the caller. It can be true only in schedulable * context. * * @next_seq is set to the sequence number after the last available record. * The value is valid only when this function returns true. It means that all * usable consoles are completely flushed. * * @handover will be set to true if a printk waiter has taken over the * console_lock, in which case the caller is no longer holding the * console_lock. Otherwise it is set to false. * * Returns true when there was at least one usable console and all messages * were flushed to all usable consoles. A returned false informs the caller * that everything was not flushed (either there were no usable consoles or * another context has taken over printing or it is a panic situation and this * is not the panic CPU). Regardless the reason, the caller should assume it * is not useful to immediately try again. * * Requires the console_lock. */ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover) { bool try_again; bool ret; *next_seq = 0; *handover = false; do { ret = console_flush_one_record(do_cond_resched, next_seq, handover, &try_again); } while (try_again); return ret; } static void __console_flush_and_unlock(void) { bool do_cond_resched; Loading Loading @@ -3597,17 +3640,26 @@ static bool legacy_kthread_should_wakeup(void) static int legacy_kthread_func(void *unused) { for (;;) { bool try_again; wait_for_event: wait_event_interruptible(legacy_wait, legacy_kthread_should_wakeup()); do { bool handover = false; u64 next_seq = 0; if (kthread_should_stop()) break; return 0; console_lock(); __console_flush_and_unlock(); } console_flush_one_record(true, &next_seq, &handover, &try_again); if (!handover) __console_unlock(); return 0; } while (try_again); goto wait_for_event; } static bool legacy_kthread_create(void) Loading Loading
kernel/printk/printk.c +118 −66 Original line number Diff line number Diff line Loading @@ -3134,42 +3134,40 @@ static inline void printk_kthreads_check_locked(void) { } #endif /* CONFIG_PRINTK */ /* * Print out all remaining records to all consoles. * Print out one record for each console. * * @do_cond_resched is set by the caller. It can be true only in schedulable * context. * * @next_seq is set to the sequence number after the last available record. * The value is valid only when this function returns true. It means that all * usable consoles are completely flushed. * The value is valid only when all usable consoles were flushed. It is * when the function returns true (can do the job) and @try_again parameter * is set to false, see below. * * @handover will be set to true if a printk waiter has taken over the * console_lock, in which case the caller is no longer holding the * console_lock. Otherwise it is set to false. * * Returns true when there was at least one usable console and all messages * were flushed to all usable consoles. A returned false informs the caller * that everything was not flushed (either there were no usable consoles or * another context has taken over printing or it is a panic situation and this * is not the panic CPU). Regardless the reason, the caller should assume it * is not useful to immediately try again. * @try_again will be set to true when it still makes sense to call this * function again. The function could do the job, see the return value. * And some consoles still make progress. * * Returns true when the function could do the job. Some consoles are usable, * and there was no takeover and no panic_on_other_cpu(). * * Requires the console_lock. */ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover) static bool console_flush_one_record(bool do_cond_resched, u64 *next_seq, bool *handover, bool *try_again) { struct console_flush_type ft; bool any_usable = false; struct console *con; bool any_progress; int cookie; *next_seq = 0; *handover = false; do { any_progress = false; *try_again = false; printk_get_console_flush_type(&ft); Loading @@ -3180,8 +3178,8 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove bool progress; /* * console_flush_all() is only responsible for nbcon * consoles when the nbcon consoles cannot print via * console_flush_one_record() is only responsible for * nbcon consoles when the nbcon consoles cannot print via * their atomic or threaded flushing. */ if ((flags & CON_NBCON) && (ft.nbcon_atomic || ft.nbcon_offload)) Loading @@ -3205,7 +3203,7 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove * is already released. */ if (*handover) return false; goto fail; /* Track the next of the highest seq flushed. */ if (printk_seq > *next_seq) Loading @@ -3213,25 +3211,70 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove if (!progress) continue; any_progress = true; /* * An usable console made a progress. There might still be * pending messages. */ *try_again = true; /* Allow panic_cpu to take over the consoles safely. */ if (panic_on_other_cpu()) goto abandon; goto fail_srcu; if (do_cond_resched) cond_resched(); } console_srcu_read_unlock(cookie); } while (any_progress); return any_usable; abandon: fail_srcu: console_srcu_read_unlock(cookie); fail: *try_again = false; return false; } /* * Print out all remaining records to all consoles. * * @do_cond_resched is set by the caller. It can be true only in schedulable * context. * * @next_seq is set to the sequence number after the last available record. * The value is valid only when this function returns true. It means that all * usable consoles are completely flushed. * * @handover will be set to true if a printk waiter has taken over the * console_lock, in which case the caller is no longer holding the * console_lock. Otherwise it is set to false. * * Returns true when there was at least one usable console and all messages * were flushed to all usable consoles. A returned false informs the caller * that everything was not flushed (either there were no usable consoles or * another context has taken over printing or it is a panic situation and this * is not the panic CPU). Regardless the reason, the caller should assume it * is not useful to immediately try again. * * Requires the console_lock. */ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handover) { bool try_again; bool ret; *next_seq = 0; *handover = false; do { ret = console_flush_one_record(do_cond_resched, next_seq, handover, &try_again); } while (try_again); return ret; } static void __console_flush_and_unlock(void) { bool do_cond_resched; Loading Loading @@ -3597,17 +3640,26 @@ static bool legacy_kthread_should_wakeup(void) static int legacy_kthread_func(void *unused) { for (;;) { bool try_again; wait_for_event: wait_event_interruptible(legacy_wait, legacy_kthread_should_wakeup()); do { bool handover = false; u64 next_seq = 0; if (kthread_should_stop()) break; return 0; console_lock(); __console_flush_and_unlock(); } console_flush_one_record(true, &next_seq, &handover, &try_again); if (!handover) __console_unlock(); return 0; } while (try_again); goto wait_for_event; } static bool legacy_kthread_create(void) Loading