Lines 282-287
EXPORT_SYMBOL(console_list_unlock);
Link Here
|
282 |
* Return: A cookie to pass to console_srcu_read_unlock(). |
282 |
* Return: A cookie to pass to console_srcu_read_unlock(). |
283 |
*/ |
283 |
*/ |
284 |
int console_srcu_read_lock(void) |
284 |
int console_srcu_read_lock(void) |
|
|
285 |
__acquires(&console_srcu) |
285 |
{ |
286 |
{ |
286 |
return srcu_read_lock_nmisafe(&console_srcu); |
287 |
return srcu_read_lock_nmisafe(&console_srcu); |
287 |
} |
288 |
} |
Lines 295-300
EXPORT_SYMBOL(console_srcu_read_lock);
Link Here
|
295 |
* Counterpart to console_srcu_read_lock() |
296 |
* Counterpart to console_srcu_read_lock() |
296 |
*/ |
297 |
*/ |
297 |
void console_srcu_read_unlock(int cookie) |
298 |
void console_srcu_read_unlock(int cookie) |
|
|
299 |
__releases(&console_srcu) |
298 |
{ |
300 |
{ |
299 |
srcu_read_unlock_nmisafe(&console_srcu, cookie); |
301 |
srcu_read_unlock_nmisafe(&console_srcu, cookie); |
300 |
} |
302 |
} |
Lines 347-352
static bool panic_in_progress(void)
Link Here
|
347 |
return unlikely(atomic_read(&panic_cpu) != PANIC_CPU_INVALID); |
349 |
return unlikely(atomic_read(&panic_cpu) != PANIC_CPU_INVALID); |
348 |
} |
350 |
} |
349 |
|
351 |
|
|
|
352 |
/* Return true if a panic is in progress on the current CPU. */ |
353 |
bool this_cpu_in_panic(void) |
354 |
{ |
355 |
/* |
356 |
* We can use raw_smp_processor_id() here because it is impossible for |
357 |
* the task to be migrated to the panic_cpu, or away from it. If |
358 |
* panic_cpu has already been set, and we're not currently executing on |
359 |
* that CPU, then we never will be. |
360 |
*/ |
361 |
return unlikely(atomic_read(&panic_cpu) == raw_smp_processor_id()); |
362 |
} |
363 |
|
364 |
/* |
365 |
* Return true if a panic is in progress on a remote CPU. |
366 |
* |
367 |
* On true, the local CPU should immediately release any printing resources |
368 |
* that may be needed by the panic CPU. |
369 |
*/ |
370 |
bool other_cpu_in_panic(void) |
371 |
{ |
372 |
return (panic_in_progress() && !this_cpu_in_panic()); |
373 |
} |
374 |
|
350 |
/* |
375 |
/* |
351 |
* This is used for debugging the mess that is the VT code by |
376 |
* This is used for debugging the mess that is the VT code by |
352 |
* keeping track if we have the console semaphore held. It's |
377 |
* keeping track if we have the console semaphore held. It's |
Lines 438-451
static int console_msg_format = MSG_FORMAT_DEFAULT;
Link Here
|
438 |
/* syslog_lock protects syslog_* variables and write access to clear_seq. */ |
463 |
/* syslog_lock protects syslog_* variables and write access to clear_seq. */ |
439 |
static DEFINE_MUTEX(syslog_lock); |
464 |
static DEFINE_MUTEX(syslog_lock); |
440 |
|
465 |
|
441 |
#ifdef CONFIG_PRINTK |
|
|
442 |
/* |
466 |
/* |
443 |
* During panic, heavy printk by other CPUs can delay the |
467 |
* Specifies if a legacy console is registered. If legacy consoles are |
444 |
* panic and risk deadlock on console resources. |
468 |
* present, it is necessary to perform the console_lock/console_unlock dance |
|
|
469 |
* whenever console flushing should occur. |
445 |
*/ |
470 |
*/ |
446 |
static int __read_mostly suppress_panic_printk; |
471 |
bool have_legacy_console; |
447 |
|
472 |
|
|
|
473 |
/* |
474 |
* Specifies if an nbcon console is registered. If nbcon consoles are present, |
475 |
* synchronous printing of legacy consoles will not occur during panic until |
476 |
* the backtrace has been stored to the ringbuffer. |
477 |
*/ |
478 |
bool have_nbcon_console; |
479 |
|
480 |
/* |
481 |
* Specifies if a boot console is registered. If boot consoles are present, |
482 |
* nbcon consoles cannot print simultaneously and must be synchronized by |
483 |
* the console lock. This is because boot consoles and nbcon consoles may |
484 |
* have mapped the same hardware. |
485 |
*/ |
486 |
bool have_boot_console; |
487 |
|
488 |
#ifdef CONFIG_PRINTK |
448 |
DECLARE_WAIT_QUEUE_HEAD(log_wait); |
489 |
DECLARE_WAIT_QUEUE_HEAD(log_wait); |
|
|
490 |
|
491 |
static DECLARE_WAIT_QUEUE_HEAD(legacy_wait); |
492 |
|
449 |
/* All 3 protected by @syslog_lock. */ |
493 |
/* All 3 protected by @syslog_lock. */ |
450 |
/* the next printk record to read by syslog(READ) or /proc/kmsg */ |
494 |
/* the next printk record to read by syslog(READ) or /proc/kmsg */ |
451 |
static u64 syslog_seq; |
495 |
static u64 syslog_seq; |
Lines 1844-1855
static bool console_waiter;
Link Here
|
1844 |
* there may be a waiter spinning (like a spinlock). Also it must be |
1888 |
* there may be a waiter spinning (like a spinlock). Also it must be |
1845 |
* ready to hand over the lock at the end of the section. |
1889 |
* ready to hand over the lock at the end of the section. |
1846 |
*/ |
1890 |
*/ |
1847 |
static void console_lock_spinning_enable(void) |
1891 |
void console_lock_spinning_enable(void) |
1848 |
{ |
1892 |
{ |
|
|
1893 |
/* |
1894 |
* Do not use spinning in panic(). The panic CPU wants to keep the lock. |
1895 |
* Non-panic CPUs abandon the flush anyway. |
1896 |
* |
1897 |
* Just keep the lockdep annotation. The panic-CPU should avoid |
1898 |
* taking console_owner_lock because it might cause a deadlock. |
1899 |
* This looks like the easiest way how to prevent false lockdep |
1900 |
* reports without handling races a lockless way. |
1901 |
*/ |
1902 |
if (panic_in_progress()) |
1903 |
goto lockdep; |
1904 |
|
1849 |
raw_spin_lock(&console_owner_lock); |
1905 |
raw_spin_lock(&console_owner_lock); |
1850 |
console_owner = current; |
1906 |
console_owner = current; |
1851 |
raw_spin_unlock(&console_owner_lock); |
1907 |
raw_spin_unlock(&console_owner_lock); |
1852 |
|
1908 |
|
|
|
1909 |
lockdep: |
1853 |
/* The waiter may spin on us after setting console_owner */ |
1910 |
/* The waiter may spin on us after setting console_owner */ |
1854 |
spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); |
1911 |
spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); |
1855 |
} |
1912 |
} |
Lines 1870-1879
static void console_lock_spinning_enable(void)
Link Here
|
1870 |
* |
1927 |
* |
1871 |
* Return: 1 if the lock rights were passed, 0 otherwise. |
1928 |
* Return: 1 if the lock rights were passed, 0 otherwise. |
1872 |
*/ |
1929 |
*/ |
1873 |
static int console_lock_spinning_disable_and_check(int cookie) |
1930 |
int console_lock_spinning_disable_and_check(int cookie) |
1874 |
{ |
1931 |
{ |
1875 |
int waiter; |
1932 |
int waiter; |
1876 |
|
1933 |
|
|
|
1934 |
/* |
1935 |
* Ignore spinning waiters during panic() because they might get stopped |
1936 |
* or blocked at any time, |
1937 |
* |
1938 |
* It is safe because nobody is allowed to start spinning during panic |
1939 |
* in the first place. If there has been a waiter then non panic CPUs |
1940 |
* might stay spinning. They would get stopped anyway. The panic context |
1941 |
* will never start spinning and an interrupted spin on panic CPU will |
1942 |
* never continue. |
1943 |
*/ |
1944 |
if (panic_in_progress()) { |
1945 |
/* Keep lockdep happy. */ |
1946 |
spin_release(&console_owner_dep_map, _THIS_IP_); |
1947 |
return 0; |
1948 |
} |
1949 |
|
1877 |
raw_spin_lock(&console_owner_lock); |
1950 |
raw_spin_lock(&console_owner_lock); |
1878 |
waiter = READ_ONCE(console_waiter); |
1951 |
waiter = READ_ONCE(console_waiter); |
1879 |
console_owner = NULL; |
1952 |
console_owner = NULL; |
Lines 2259-2313
int vprintk_store(int facility, int level,
Link Here
|
2259 |
return ret; |
2332 |
return ret; |
2260 |
} |
2333 |
} |
2261 |
|
2334 |
|
|
|
2335 |
static bool legacy_allow_panic_sync; |
2336 |
|
2337 |
/* |
2338 |
* This acts as a one-way switch to allow legacy consoles to print from |
2339 |
* the printk() caller context on a panic CPU. |
2340 |
*/ |
2341 |
void printk_legacy_allow_panic_sync(void) |
2342 |
{ |
2343 |
legacy_allow_panic_sync = true; |
2344 |
} |
2345 |
|
2262 |
asmlinkage int vprintk_emit(int facility, int level, |
2346 |
asmlinkage int vprintk_emit(int facility, int level, |
2263 |
const struct dev_printk_info *dev_info, |
2347 |
const struct dev_printk_info *dev_info, |
2264 |
const char *fmt, va_list args) |
2348 |
const char *fmt, va_list args) |
2265 |
{ |
2349 |
{ |
|
|
2350 |
bool do_trylock_unlock = printing_via_unlock && |
2351 |
!IS_ENABLED(CONFIG_PREEMPT_RT); |
2266 |
int printed_len; |
2352 |
int printed_len; |
2267 |
bool in_sched = false; |
|
|
2268 |
|
2353 |
|
2269 |
/* Suppress unimportant messages after panic happens */ |
2354 |
/* Suppress unimportant messages after panic happens */ |
2270 |
if (unlikely(suppress_printk)) |
2355 |
if (unlikely(suppress_printk)) |
2271 |
return 0; |
2356 |
return 0; |
2272 |
|
2357 |
|
2273 |
if (unlikely(suppress_panic_printk) && |
2358 |
/* |
2274 |
atomic_read(&panic_cpu) != raw_smp_processor_id()) |
2359 |
* The messages on the panic CPU are the most important. If |
|
|
2360 |
* non-panic CPUs are generating any messages, they will be |
2361 |
* silently dropped. |
2362 |
*/ |
2363 |
if (other_cpu_in_panic()) |
2275 |
return 0; |
2364 |
return 0; |
2276 |
|
2365 |
|
2277 |
if (level == LOGLEVEL_SCHED) { |
2366 |
if (level == LOGLEVEL_SCHED) { |
2278 |
level = LOGLEVEL_DEFAULT; |
2367 |
level = LOGLEVEL_DEFAULT; |
2279 |
in_sched = true; |
2368 |
/* If called from the scheduler, we can not call up(). */ |
|
|
2369 |
do_trylock_unlock = false; |
2280 |
} |
2370 |
} |
2281 |
|
2371 |
|
2282 |
printk_delay(level); |
2372 |
printk_delay(level); |
2283 |
|
2373 |
|
2284 |
printed_len = vprintk_store(facility, level, dev_info, fmt, args); |
2374 |
printed_len = vprintk_store(facility, level, dev_info, fmt, args); |
2285 |
|
2375 |
|
2286 |
/* If called from the scheduler, we can not call up(). */ |
2376 |
if (!have_boot_console && have_nbcon_console) { |
2287 |
if (!in_sched) { |
2377 |
bool is_panic_context = this_cpu_in_panic(); |
|
|
2378 |
|
2379 |
/* |
2380 |
* In panic, the legacy consoles are not allowed to print from |
2381 |
* the printk calling context unless explicitly allowed. This |
2382 |
* gives the safe nbcon consoles a chance to print out all the |
2383 |
* panic messages first. This restriction only applies if |
2384 |
* there are nbcon consoles registered. |
2385 |
*/ |
2386 |
if (is_panic_context) |
2387 |
do_trylock_unlock &= legacy_allow_panic_sync; |
2388 |
|
2389 |
/* |
2390 |
* There are situations where nbcon atomic printing should |
2391 |
* happen in the printk() caller context: |
2392 |
* |
2393 |
* - When this CPU is in panic. |
2394 |
* |
2395 |
* - When booting, before the printing threads have been |
2396 |
* started. |
2397 |
* |
2398 |
* - During shutdown, since the printing threads may not get |
2399 |
* a chance to print the final messages. |
2400 |
* |
2401 |
* Note that if boot consoles are registered, the |
2402 |
* console_lock/console_unlock dance must be relied upon |
2403 |
* instead because nbcon consoles cannot print simultaneously |
2404 |
* with boot consoles. |
2405 |
*/ |
2406 |
if (is_panic_context || |
2407 |
!printk_threads_enabled || |
2408 |
(system_state > SYSTEM_RUNNING)) { |
2409 |
nbcon_atomic_flush_all(); |
2410 |
} |
2411 |
} |
2412 |
|
2413 |
nbcon_wake_threads(); |
2414 |
|
2415 |
if (do_trylock_unlock) { |
2288 |
/* |
2416 |
/* |
2289 |
* The caller may be holding system-critical or |
2417 |
* The caller may be holding system-critical or |
2290 |
* timing-sensitive locks. Disable preemption during |
2418 |
* timing-sensitive locks. Disable preemption during |
2291 |
* printing of all remaining records to all consoles so that |
2419 |
* printing of all remaining records to all consoles so that |
2292 |
* this context can return as soon as possible. Hopefully |
2420 |
* this context can return as soon as possible. Hopefully |
2293 |
* another printk() caller will take over the printing. |
2421 |
* another printk() caller will take over the printing. |
|
|
2422 |
* |
2423 |
* Also, nbcon_get_default_prio() requires migration disabled. |
2294 |
*/ |
2424 |
*/ |
2295 |
preempt_disable(); |
2425 |
preempt_disable(); |
|
|
2426 |
|
2296 |
/* |
2427 |
/* |
2297 |
* Try to acquire and then immediately release the console |
2428 |
* Do not emit for EMERGENCY priority. The console will be |
2298 |
* semaphore. The release will print out buffers. With the |
2429 |
* explicitly flushed when exiting the emergency section. |
2299 |
* spinning variant, this context tries to take over the |
|
|
2300 |
* printing from another printing context. |
2301 |
*/ |
2430 |
*/ |
2302 |
if (console_trylock_spinning()) |
2431 |
if (nbcon_get_default_prio() == NBCON_PRIO_EMERGENCY) { |
2303 |
console_unlock(); |
2432 |
do_trylock_unlock = false; |
|
|
2433 |
} else { |
2434 |
/* |
2435 |
* Try to acquire and then immediately release the |
2436 |
* console semaphore. The release will print out |
2437 |
* buffers. With the spinning variant, this context |
2438 |
* tries to take over the printing from another |
2439 |
* printing context. |
2440 |
*/ |
2441 |
if (console_trylock_spinning()) |
2442 |
console_unlock(); |
2443 |
} |
2444 |
|
2304 |
preempt_enable(); |
2445 |
preempt_enable(); |
2305 |
} |
2446 |
} |
2306 |
|
2447 |
|
2307 |
if (in_sched) |
2448 |
if (do_trylock_unlock) |
2308 |
defer_console_output(); |
|
|
2309 |
else |
2310 |
wake_up_klogd(); |
2449 |
wake_up_klogd(); |
|
|
2450 |
else |
2451 |
defer_console_output(); |
2311 |
|
2452 |
|
2312 |
return printed_len; |
2453 |
return printed_len; |
2313 |
} |
2454 |
} |
Lines 2335-2340
EXPORT_SYMBOL(_printk);
Link Here
|
2335 |
static bool pr_flush(int timeout_ms, bool reset_on_progress); |
2476 |
static bool pr_flush(int timeout_ms, bool reset_on_progress); |
2336 |
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress); |
2477 |
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress); |
2337 |
|
2478 |
|
|
|
2479 |
static struct task_struct *nbcon_legacy_kthread; |
2480 |
|
2481 |
static inline void wake_up_legacy_kthread(void) |
2482 |
{ |
2483 |
if (nbcon_legacy_kthread) |
2484 |
wake_up_interruptible(&legacy_wait); |
2485 |
} |
2486 |
|
2338 |
#else /* CONFIG_PRINTK */ |
2487 |
#else /* CONFIG_PRINTK */ |
2339 |
|
2488 |
|
2340 |
#define printk_time false |
2489 |
#define printk_time false |
Lines 2348-2353
static u64 syslog_seq;
Link Here
|
2348 |
static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } |
2497 |
static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; } |
2349 |
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; } |
2498 |
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; } |
2350 |
|
2499 |
|
|
|
2500 |
static inline void nbcon_legacy_kthread_create(void) { } |
2501 |
static inline void wake_up_legacy_kthread(void) { } |
2351 |
#endif /* CONFIG_PRINTK */ |
2502 |
#endif /* CONFIG_PRINTK */ |
2352 |
|
2503 |
|
2353 |
#ifdef CONFIG_EARLY_PRINTK |
2504 |
#ifdef CONFIG_EARLY_PRINTK |
Lines 2563-2568
void suspend_console(void)
Link Here
|
2563 |
void resume_console(void) |
2714 |
void resume_console(void) |
2564 |
{ |
2715 |
{ |
2565 |
struct console *con; |
2716 |
struct console *con; |
|
|
2717 |
short flags; |
2718 |
int cookie; |
2566 |
|
2719 |
|
2567 |
if (!console_suspend_enabled) |
2720 |
if (!console_suspend_enabled) |
2568 |
return; |
2721 |
return; |
Lines 2579-2584
void resume_console(void)
Link Here
|
2579 |
*/ |
2732 |
*/ |
2580 |
synchronize_srcu(&console_srcu); |
2733 |
synchronize_srcu(&console_srcu); |
2581 |
|
2734 |
|
|
|
2735 |
/* |
2736 |
* Since this runs in task context, wake the threaded printers |
2737 |
* directly rather than scheduling irq_work to do it. |
2738 |
*/ |
2739 |
cookie = console_srcu_read_lock(); |
2740 |
for_each_console_srcu(con) { |
2741 |
flags = console_srcu_read_flags(con); |
2742 |
if (flags & CON_NBCON) |
2743 |
nbcon_kthread_wake(con); |
2744 |
} |
2745 |
console_srcu_read_unlock(cookie); |
2746 |
|
2747 |
wake_up_legacy_kthread(); |
2748 |
|
2582 |
pr_flush(1000, true); |
2749 |
pr_flush(1000, true); |
2583 |
} |
2750 |
} |
2584 |
|
2751 |
|
Lines 2593-2599
void resume_console(void)
Link Here
|
2593 |
*/ |
2760 |
*/ |
2594 |
static int console_cpu_notify(unsigned int cpu) |
2761 |
static int console_cpu_notify(unsigned int cpu) |
2595 |
{ |
2762 |
{ |
2596 |
if (!cpuhp_tasks_frozen) { |
2763 |
if (!cpuhp_tasks_frozen && printing_via_unlock && |
|
|
2764 |
!IS_ENABLED(CONFIG_PREEMPT_RT)) { |
2597 |
/* If trylock fails, someone else is doing the printing */ |
2765 |
/* If trylock fails, someone else is doing the printing */ |
2598 |
if (console_trylock()) |
2766 |
if (console_trylock()) |
2599 |
console_unlock(); |
2767 |
console_unlock(); |
Lines 2601-2626
static int console_cpu_notify(unsigned int cpu)
Link Here
|
2601 |
return 0; |
2769 |
return 0; |
2602 |
} |
2770 |
} |
2603 |
|
2771 |
|
2604 |
/* |
|
|
2605 |
* Return true if a panic is in progress on a remote CPU. |
2606 |
* |
2607 |
* On true, the local CPU should immediately release any printing resources |
2608 |
* that may be needed by the panic CPU. |
2609 |
*/ |
2610 |
bool other_cpu_in_panic(void) |
2611 |
{ |
2612 |
if (!panic_in_progress()) |
2613 |
return false; |
2614 |
|
2615 |
/* |
2616 |
* We can use raw_smp_processor_id() here because it is impossible for |
2617 |
* the task to be migrated to the panic_cpu, or away from it. If |
2618 |
* panic_cpu has already been set, and we're not currently executing on |
2619 |
* that CPU, then we never will be. |
2620 |
*/ |
2621 |
return atomic_read(&panic_cpu) != raw_smp_processor_id(); |
2622 |
} |
2623 |
|
2624 |
/** |
2772 |
/** |
2625 |
* console_lock - block the console subsystem from printing |
2773 |
* console_lock - block the console subsystem from printing |
2626 |
* |
2774 |
* |
Lines 2670-2711
int is_console_locked(void)
Link Here
|
2670 |
} |
2818 |
} |
2671 |
EXPORT_SYMBOL(is_console_locked); |
2819 |
EXPORT_SYMBOL(is_console_locked); |
2672 |
|
2820 |
|
2673 |
/* |
|
|
2674 |
* Check if the given console is currently capable and allowed to print |
2675 |
* records. |
2676 |
* |
2677 |
* Requires the console_srcu_read_lock. |
2678 |
*/ |
2679 |
static inline bool console_is_usable(struct console *con) |
2680 |
{ |
2681 |
short flags = console_srcu_read_flags(con); |
2682 |
|
2683 |
if (!(flags & CON_ENABLED)) |
2684 |
return false; |
2685 |
|
2686 |
if ((flags & CON_SUSPENDED)) |
2687 |
return false; |
2688 |
|
2689 |
if (!con->write) |
2690 |
return false; |
2691 |
|
2692 |
/* |
2693 |
* Console drivers may assume that per-cpu resources have been |
2694 |
* allocated. So unless they're explicitly marked as being able to |
2695 |
* cope (CON_ANYTIME) don't call them until this CPU is officially up. |
2696 |
*/ |
2697 |
if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) |
2698 |
return false; |
2699 |
|
2700 |
return true; |
2701 |
} |
2702 |
|
2703 |
static void __console_unlock(void) |
2821 |
static void __console_unlock(void) |
2704 |
{ |
2822 |
{ |
2705 |
console_locked = 0; |
2823 |
console_locked = 0; |
2706 |
up_console_sem(); |
2824 |
up_console_sem(); |
2707 |
} |
2825 |
} |
2708 |
|
2826 |
|
|
|
2827 |
static DEFINE_WAIT_OVERRIDE_MAP(printk_legacy_map, LD_WAIT_SLEEP); |
2828 |
|
2709 |
#ifdef CONFIG_PRINTK |
2829 |
#ifdef CONFIG_PRINTK |
2710 |
|
2830 |
|
2711 |
/* |
2831 |
/* |
Lines 2776-2783
void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped)
Link Here
|
2776 |
bool printk_get_next_message(struct printk_message *pmsg, u64 seq, |
2896 |
bool printk_get_next_message(struct printk_message *pmsg, u64 seq, |
2777 |
bool is_extended, bool may_suppress) |
2897 |
bool is_extended, bool may_suppress) |
2778 |
{ |
2898 |
{ |
2779 |
static int panic_console_dropped; |
|
|
2780 |
|
2781 |
struct printk_buffers *pbufs = pmsg->pbufs; |
2899 |
struct printk_buffers *pbufs = pmsg->pbufs; |
2782 |
const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf); |
2900 |
const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf); |
2783 |
const size_t outbuf_sz = sizeof(pbufs->outbuf); |
2901 |
const size_t outbuf_sz = sizeof(pbufs->outbuf); |
Lines 2805-2821
bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
Link Here
|
2805 |
pmsg->seq = r.info->seq; |
2923 |
pmsg->seq = r.info->seq; |
2806 |
pmsg->dropped = r.info->seq - seq; |
2924 |
pmsg->dropped = r.info->seq - seq; |
2807 |
|
2925 |
|
2808 |
/* |
|
|
2809 |
* Check for dropped messages in panic here so that printk |
2810 |
* suppression can occur as early as possible if necessary. |
2811 |
*/ |
2812 |
if (pmsg->dropped && |
2813 |
panic_in_progress() && |
2814 |
panic_console_dropped++ > 10) { |
2815 |
suppress_panic_printk = 1; |
2816 |
pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n"); |
2817 |
} |
2818 |
|
2819 |
/* Skip record that has level above the console loglevel. */ |
2926 |
/* Skip record that has level above the console loglevel. */ |
2820 |
if (may_suppress && suppress_message_printing(r.info->level)) |
2927 |
if (may_suppress && suppress_message_printing(r.info->level)) |
2821 |
goto out; |
2928 |
goto out; |
Lines 2881-2911
static bool console_emit_next_record(struct console *con, bool *handover, int co
Link Here
|
2881 |
con->dropped = 0; |
2988 |
con->dropped = 0; |
2882 |
} |
2989 |
} |
2883 |
|
2990 |
|
2884 |
/* |
|
|
2885 |
* While actively printing out messages, if another printk() |
2886 |
* were to occur on another CPU, it may wait for this one to |
2887 |
* finish. This task can not be preempted if there is a |
2888 |
* waiter waiting to take over. |
2889 |
* |
2890 |
* Interrupts are disabled because the hand over to a waiter |
2891 |
* must not be interrupted until the hand over is completed |
2892 |
* (@console_waiter is cleared). |
2893 |
*/ |
2894 |
printk_safe_enter_irqsave(flags); |
2895 |
console_lock_spinning_enable(); |
2896 |
|
2897 |
/* Do not trace print latency. */ |
2898 |
stop_critical_timings(); |
2899 |
|
2900 |
/* Write everything out to the hardware. */ |
2991 |
/* Write everything out to the hardware. */ |
2901 |
con->write(con, outbuf, pmsg.outbuf_len); |
|
|
2902 |
|
2992 |
|
2903 |
start_critical_timings(); |
2993 |
if (IS_ENABLED(CONFIG_PREEMPT_RT)) { |
|
|
2994 |
/* |
2995 |
* On PREEMPT_RT this function is either in a thread or |
2996 |
* panic context. So there is no need for concern about |
2997 |
* printk reentrance, handovers, or lockdep complaints. |
2998 |
*/ |
2904 |
|
2999 |
|
2905 |
con->seq = pmsg.seq + 1; |
3000 |
con->write(con, outbuf, pmsg.outbuf_len); |
|
|
3001 |
con->seq = pmsg.seq + 1; |
3002 |
} else { |
3003 |
/* |
3004 |
* While actively printing out messages, if another printk() |
3005 |
* were to occur on another CPU, it may wait for this one to |
3006 |
* finish. This task can not be preempted if there is a |
3007 |
* waiter waiting to take over. |
3008 |
* |
3009 |
* Interrupts are disabled because the hand over to a waiter |
3010 |
* must not be interrupted until the hand over is completed |
3011 |
* (@console_waiter is cleared). |
3012 |
*/ |
3013 |
printk_safe_enter_irqsave(flags); |
3014 |
console_lock_spinning_enable(); |
2906 |
|
3015 |
|
2907 |
*handover = console_lock_spinning_disable_and_check(cookie); |
3016 |
/* Do not trace print latency. */ |
2908 |
printk_safe_exit_irqrestore(flags); |
3017 |
stop_critical_timings(); |
|
|
3018 |
|
3019 |
lock_map_acquire_try(&printk_legacy_map); |
3020 |
con->write(con, outbuf, pmsg.outbuf_len); |
3021 |
lock_map_release(&printk_legacy_map); |
3022 |
|
3023 |
start_critical_timings(); |
3024 |
|
3025 |
con->seq = pmsg.seq + 1; |
3026 |
|
3027 |
*handover = console_lock_spinning_disable_and_check(cookie); |
3028 |
printk_safe_exit_irqrestore(flags); |
3029 |
} |
2909 |
skip: |
3030 |
skip: |
2910 |
return true; |
3031 |
return true; |
2911 |
} |
3032 |
} |
Lines 2958-2970
static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
Link Here
|
2958 |
|
3079 |
|
2959 |
cookie = console_srcu_read_lock(); |
3080 |
cookie = console_srcu_read_lock(); |
2960 |
for_each_console_srcu(con) { |
3081 |
for_each_console_srcu(con) { |
|
|
3082 |
short flags = console_srcu_read_flags(con); |
3083 |
u64 printk_seq; |
2961 |
bool progress; |
3084 |
bool progress; |
2962 |
|
3085 |
|
2963 |
if (!console_is_usable(con)) |
3086 |
/* |
|
|
3087 |
* console_flush_all() is only for legacy consoles, |
3088 |
* unless the nbcon console has no kthread printer. |
3089 |
*/ |
3090 |
if ((flags & CON_NBCON) && con->kthread) |
3091 |
continue; |
3092 |
|
3093 |
if (!console_is_usable(con, flags, true)) |
2964 |
continue; |
3094 |
continue; |
2965 |
any_usable = true; |
3095 |
any_usable = true; |
2966 |
|
3096 |
|
2967 |
progress = console_emit_next_record(con, handover, cookie); |
3097 |
if (flags & CON_NBCON) { |
|
|
3098 |
|
3099 |
lock_map_acquire_try(&printk_legacy_map); |
3100 |
progress = nbcon_atomic_emit_next_record(con, handover, cookie); |
3101 |
lock_map_release(&printk_legacy_map); |
3102 |
|
3103 |
printk_seq = nbcon_seq_read(con); |
3104 |
} else { |
3105 |
progress = console_emit_next_record(con, handover, cookie); |
3106 |
|
3107 |
printk_seq = con->seq; |
3108 |
} |
2968 |
|
3109 |
|
2969 |
/* |
3110 |
/* |
2970 |
* If a handover has occurred, the SRCU read lock |
3111 |
* If a handover has occurred, the SRCU read lock |
Lines 2974-2981
static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
Link Here
|
2974 |
return false; |
3115 |
return false; |
2975 |
|
3116 |
|
2976 |
/* Track the next of the highest seq flushed. */ |
3117 |
/* Track the next of the highest seq flushed. */ |
2977 |
if (con->seq > *next_seq) |
3118 |
if (printk_seq > *next_seq) |
2978 |
*next_seq = con->seq; |
3119 |
*next_seq = printk_seq; |
2979 |
|
3120 |
|
2980 |
if (!progress) |
3121 |
if (!progress) |
2981 |
continue; |
3122 |
continue; |
Lines 2998-3016
static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
Link Here
|
2998 |
return false; |
3139 |
return false; |
2999 |
} |
3140 |
} |
3000 |
|
3141 |
|
3001 |
/** |
3142 |
static void console_flush_and_unlock(void) |
3002 |
* console_unlock - unblock the console subsystem from printing |
|
|
3003 |
* |
3004 |
* Releases the console_lock which the caller holds to block printing of |
3005 |
* the console subsystem. |
3006 |
* |
3007 |
* While the console_lock was held, console output may have been buffered |
3008 |
* by printk(). If this is the case, console_unlock(); emits |
3009 |
* the output prior to releasing the lock. |
3010 |
* |
3011 |
* console_unlock(); may be called from any context. |
3012 |
*/ |
3013 |
void console_unlock(void) |
3014 |
{ |
3143 |
{ |
3015 |
bool do_cond_resched; |
3144 |
bool do_cond_resched; |
3016 |
bool handover; |
3145 |
bool handover; |
Lines 3054-3059
void console_unlock(void)
Link Here
|
3054 |
*/ |
3183 |
*/ |
3055 |
} while (prb_read_valid(prb, next_seq, NULL) && console_trylock()); |
3184 |
} while (prb_read_valid(prb, next_seq, NULL) && console_trylock()); |
3056 |
} |
3185 |
} |
|
|
3186 |
|
3187 |
/** |
3188 |
* console_unlock - unblock the console subsystem from printing |
3189 |
* |
3190 |
* Releases the console_lock which the caller holds to block printing of |
3191 |
* the console subsystem. |
3192 |
* |
3193 |
* While the console_lock was held, console output may have been buffered |
3194 |
* by printk(). If this is the case, console_unlock(); emits |
3195 |
* the output prior to releasing the lock. |
3196 |
* |
3197 |
* console_unlock(); may be called from any context. |
3198 |
*/ |
3199 |
void console_unlock(void) |
3200 |
{ |
3201 |
/* |
3202 |
* PREEMPT_RT relies on kthread and atomic consoles for printing. |
3203 |
* It never attempts to print from console_unlock(). |
3204 |
*/ |
3205 |
if (IS_ENABLED(CONFIG_PREEMPT_RT)) { |
3206 |
__console_unlock(); |
3207 |
return; |
3208 |
} |
3209 |
|
3210 |
console_flush_and_unlock(); |
3211 |
} |
3057 |
EXPORT_SYMBOL(console_unlock); |
3212 |
EXPORT_SYMBOL(console_unlock); |
3058 |
|
3213 |
|
3059 |
/** |
3214 |
/** |
Lines 3187-3193
void console_flush_on_panic(enum con_flush_mode mode)
Link Here
|
3187 |
console_srcu_read_unlock(cookie); |
3342 |
console_srcu_read_unlock(cookie); |
3188 |
} |
3343 |
} |
3189 |
|
3344 |
|
3190 |
console_flush_all(false, &next_seq, &handover); |
3345 |
nbcon_atomic_flush_all(); |
|
|
3346 |
|
3347 |
if (printing_via_unlock) |
3348 |
console_flush_all(false, &next_seq, &handover); |
3191 |
} |
3349 |
} |
3192 |
|
3350 |
|
3193 |
/* |
3351 |
/* |
Lines 3244-3256
EXPORT_SYMBOL(console_stop);
Link Here
|
3244 |
|
3402 |
|
3245 |
void console_start(struct console *console) |
3403 |
void console_start(struct console *console) |
3246 |
{ |
3404 |
{ |
|
|
3405 |
short flags; |
3406 |
|
3247 |
console_list_lock(); |
3407 |
console_list_lock(); |
3248 |
console_srcu_write_flags(console, console->flags | CON_ENABLED); |
3408 |
console_srcu_write_flags(console, console->flags | CON_ENABLED); |
|
|
3409 |
flags = console->flags; |
3249 |
console_list_unlock(); |
3410 |
console_list_unlock(); |
|
|
3411 |
|
3412 |
/* |
3413 |
* Ensure that all SRCU list walks have completed. The related |
3414 |
* printing context must be able to see it is enabled so that |
3415 |
* it is guaranteed to wake up and resume printing. |
3416 |
*/ |
3417 |
synchronize_srcu(&console_srcu); |
3418 |
|
3419 |
if (flags & CON_NBCON) |
3420 |
nbcon_kthread_wake(console); |
3421 |
else |
3422 |
wake_up_legacy_kthread(); |
3423 |
|
3250 |
__pr_flush(console, 1000, true); |
3424 |
__pr_flush(console, 1000, true); |
3251 |
} |
3425 |
} |
3252 |
EXPORT_SYMBOL(console_start); |
3426 |
EXPORT_SYMBOL(console_start); |
3253 |
|
3427 |
|
|
|
3428 |
#ifdef CONFIG_PRINTK |
3429 |
static bool printer_should_wake(void) |
3430 |
{ |
3431 |
bool available = false; |
3432 |
struct console *con; |
3433 |
int cookie; |
3434 |
|
3435 |
if (kthread_should_stop()) |
3436 |
return true; |
3437 |
|
3438 |
cookie = console_srcu_read_lock(); |
3439 |
for_each_console_srcu(con) { |
3440 |
short flags = console_srcu_read_flags(con); |
3441 |
u64 printk_seq; |
3442 |
|
3443 |
/* |
3444 |
* The legacy printer thread is only for legacy consoles, |
3445 |
* unless the nbcon console has no kthread printer. |
3446 |
*/ |
3447 |
if ((flags & CON_NBCON) && con->kthread) |
3448 |
continue; |
3449 |
|
3450 |
if (!console_is_usable(con, flags, true)) |
3451 |
continue; |
3452 |
|
3453 |
if (flags & CON_NBCON) { |
3454 |
printk_seq = nbcon_seq_read(con); |
3455 |
} else { |
3456 |
/* |
3457 |
* It is safe to read @seq because only this |
3458 |
* thread context updates @seq. |
3459 |
*/ |
3460 |
printk_seq = con->seq; |
3461 |
} |
3462 |
|
3463 |
if (prb_read_valid(prb, printk_seq, NULL)) { |
3464 |
available = true; |
3465 |
break; |
3466 |
} |
3467 |
} |
3468 |
console_srcu_read_unlock(cookie); |
3469 |
|
3470 |
return available; |
3471 |
} |
3472 |
|
3473 |
static int nbcon_legacy_kthread_func(void *unused) |
3474 |
{ |
3475 |
int error; |
3476 |
|
3477 |
for (;;) { |
3478 |
error = wait_event_interruptible(legacy_wait, printer_should_wake()); |
3479 |
|
3480 |
if (kthread_should_stop()) |
3481 |
break; |
3482 |
|
3483 |
if (error) |
3484 |
continue; |
3485 |
|
3486 |
console_lock(); |
3487 |
console_flush_and_unlock(); |
3488 |
} |
3489 |
|
3490 |
return 0; |
3491 |
} |
3492 |
|
3493 |
void nbcon_legacy_kthread_create(void) |
3494 |
{ |
3495 |
struct task_struct *kt; |
3496 |
|
3497 |
lockdep_assert_held(&console_mutex); |
3498 |
|
3499 |
if (!IS_ENABLED(CONFIG_PREEMPT_RT)) |
3500 |
return; |
3501 |
|
3502 |
if (!printk_threads_enabled || nbcon_legacy_kthread) |
3503 |
return; |
3504 |
|
3505 |
kt = kthread_run(nbcon_legacy_kthread_func, NULL, "pr/legacy"); |
3506 |
if (IS_ERR(kt)) { |
3507 |
pr_err("unable to start legacy printing thread\n"); |
3508 |
return; |
3509 |
} |
3510 |
|
3511 |
nbcon_legacy_kthread = kt; |
3512 |
|
3513 |
/* |
3514 |
* It is important that console printing threads are scheduled |
3515 |
* shortly after a printk call and with generous runtime budgets. |
3516 |
*/ |
3517 |
sched_set_normal(nbcon_legacy_kthread, -20); |
3518 |
} |
3519 |
#endif /* CONFIG_PRINTK */ |
3520 |
|
3254 |
static int __read_mostly keep_bootcon; |
3521 |
static int __read_mostly keep_bootcon; |
3255 |
|
3522 |
|
3256 |
static int __init keep_bootcon_setup(char *str) |
3523 |
static int __init keep_bootcon_setup(char *str) |
Lines 3382-3392
static void console_init_seq(struct console *newcon, bool bootcon_registered)
Link Here
|
3382 |
|
3649 |
|
3383 |
newcon->seq = prb_next_seq(prb); |
3650 |
newcon->seq = prb_next_seq(prb); |
3384 |
for_each_console(con) { |
3651 |
for_each_console(con) { |
3385 |
if ((con->flags & CON_BOOT) && |
3652 |
u64 seq; |
3386 |
(con->flags & CON_ENABLED) && |
3653 |
|
3387 |
con->seq < newcon->seq) { |
3654 |
if (!((con->flags & CON_BOOT) && |
3388 |
newcon->seq = con->seq; |
3655 |
(con->flags & CON_ENABLED))) { |
|
|
3656 |
continue; |
3389 |
} |
3657 |
} |
|
|
3658 |
|
3659 |
if (con->flags & CON_NBCON) |
3660 |
seq = nbcon_seq_read(con); |
3661 |
else |
3662 |
seq = con->seq; |
3663 |
|
3664 |
if (seq < newcon->seq) |
3665 |
newcon->seq = seq; |
3390 |
} |
3666 |
} |
3391 |
} |
3667 |
} |
3392 |
|
3668 |
|
Lines 3503-3510
void register_console(struct console *newcon)
Link Here
|
3503 |
newcon->dropped = 0; |
3779 |
newcon->dropped = 0; |
3504 |
console_init_seq(newcon, bootcon_registered); |
3780 |
console_init_seq(newcon, bootcon_registered); |
3505 |
|
3781 |
|
3506 |
if (newcon->flags & CON_NBCON) |
3782 |
if (newcon->flags & CON_NBCON) { |
|
|
3783 |
have_nbcon_console = true; |
3507 |
nbcon_init(newcon); |
3784 |
nbcon_init(newcon); |
|
|
3785 |
} else { |
3786 |
have_legacy_console = true; |
3787 |
nbcon_legacy_kthread_create(); |
3788 |
} |
3789 |
|
3790 |
if (newcon->flags & CON_BOOT) |
3791 |
have_boot_console = true; |
3508 |
|
3792 |
|
3509 |
/* |
3793 |
/* |
3510 |
* Put this console in the list - keep the |
3794 |
* Put this console in the list - keep the |
Lines 3558-3563
EXPORT_SYMBOL(register_console);
Link Here
|
3558 |
/* Must be called under console_list_lock(). */ |
3842 |
/* Must be called under console_list_lock(). */ |
3559 |
static int unregister_console_locked(struct console *console) |
3843 |
static int unregister_console_locked(struct console *console) |
3560 |
{ |
3844 |
{ |
|
|
3845 |
bool is_boot_con = (console->flags & CON_BOOT); |
3846 |
bool found_legacy_con = false; |
3847 |
bool found_nbcon_con = false; |
3848 |
bool found_boot_con = false; |
3849 |
struct console *c; |
3561 |
int res; |
3850 |
int res; |
3562 |
|
3851 |
|
3563 |
lockdep_assert_console_list_lock_held(); |
3852 |
lockdep_assert_console_list_lock_held(); |
Lines 3605-3610
static int unregister_console_locked(struct console *console)
Link Here
|
3605 |
if (console->exit) |
3894 |
if (console->exit) |
3606 |
res = console->exit(console); |
3895 |
res = console->exit(console); |
3607 |
|
3896 |
|
|
|
3897 |
/* |
3898 |
* With this console gone, the global flags tracking registered |
3899 |
* console types may have changed. Update them. |
3900 |
*/ |
3901 |
for_each_console(c) { |
3902 |
if (c->flags & CON_BOOT) |
3903 |
found_boot_con = true; |
3904 |
|
3905 |
if (c->flags & CON_NBCON) |
3906 |
found_nbcon_con = true; |
3907 |
else |
3908 |
found_legacy_con = true; |
3909 |
} |
3910 |
if (!found_boot_con) |
3911 |
have_boot_console = false; |
3912 |
if (!found_legacy_con) |
3913 |
have_legacy_console = false; |
3914 |
if (!found_nbcon_con) |
3915 |
have_nbcon_console = false; |
3916 |
|
3917 |
/* |
3918 |
* When the last boot console unregisters, start up the |
3919 |
* printing threads. |
3920 |
*/ |
3921 |
if (is_boot_con && !have_boot_console) { |
3922 |
for_each_console(c) |
3923 |
nbcon_kthread_create(c); |
3924 |
} |
3925 |
|
3926 |
#ifdef CONFIG_PRINTK |
3927 |
if (!printing_via_unlock && nbcon_legacy_kthread) { |
3928 |
kthread_stop(nbcon_legacy_kthread); |
3929 |
nbcon_legacy_kthread = NULL; |
3930 |
} |
3931 |
#endif |
3932 |
|
3608 |
return res; |
3933 |
return res; |
3609 |
} |
3934 |
} |
3610 |
|
3935 |
|
Lines 3755-3785
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre
Link Here
|
3755 |
u64 last_diff = 0; |
4080 |
u64 last_diff = 0; |
3756 |
u64 printk_seq; |
4081 |
u64 printk_seq; |
3757 |
short flags; |
4082 |
short flags; |
|
|
4083 |
bool locked; |
3758 |
int cookie; |
4084 |
int cookie; |
3759 |
u64 diff; |
4085 |
u64 diff; |
3760 |
u64 seq; |
4086 |
u64 seq; |
3761 |
|
4087 |
|
3762 |
might_sleep(); |
4088 |
might_sleep(); |
3763 |
|
4089 |
|
3764 |
seq = prb_next_seq(prb); |
4090 |
seq = prb_next_reserve_seq(prb); |
3765 |
|
4091 |
|
3766 |
/* Flush the consoles so that records up to @seq are printed. */ |
4092 |
/* |
3767 |
console_lock(); |
4093 |
* Flush the consoles so that records up to @seq are printed. |
3768 |
console_unlock(); |
4094 |
* Otherwise this function will just wait for the threaded printers |
|
|
4095 |
* to print up to @seq. |
4096 |
*/ |
4097 |
if (printing_via_unlock && !IS_ENABLED(CONFIG_PREEMPT_RT)) { |
4098 |
console_lock(); |
4099 |
console_unlock(); |
4100 |
} |
3769 |
|
4101 |
|
3770 |
for (;;) { |
4102 |
for (;;) { |
3771 |
unsigned long begin_jiffies; |
4103 |
unsigned long begin_jiffies; |
3772 |
unsigned long slept_jiffies; |
4104 |
unsigned long slept_jiffies; |
3773 |
|
4105 |
|
|
|
4106 |
locked = false; |
3774 |
diff = 0; |
4107 |
diff = 0; |
3775 |
|
4108 |
|
3776 |
/* |
4109 |
if (printing_via_unlock) { |
3777 |
* Hold the console_lock to guarantee safe access to |
4110 |
/* |
3778 |
* console->seq. Releasing console_lock flushes more |
4111 |
* Hold the console_lock to guarantee safe access to |
3779 |
* records in case @seq is still not printed on all |
4112 |
* console->seq. Releasing console_lock flushes more |
3780 |
* usable consoles. |
4113 |
* records in case @seq is still not printed on all |
3781 |
*/ |
4114 |
* usable consoles. |
3782 |
console_lock(); |
4115 |
*/ |
|
|
4116 |
console_lock(); |
4117 |
locked = true; |
4118 |
} |
3783 |
|
4119 |
|
3784 |
cookie = console_srcu_read_lock(); |
4120 |
cookie = console_srcu_read_lock(); |
3785 |
for_each_console_srcu(c) { |
4121 |
for_each_console_srcu(c) { |
Lines 3793-3804
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre
Link Here
|
3793 |
* that they make forward progress, so only increment |
4129 |
* that they make forward progress, so only increment |
3794 |
* @diff for usable consoles. |
4130 |
* @diff for usable consoles. |
3795 |
*/ |
4131 |
*/ |
3796 |
if (!console_is_usable(c)) |
4132 |
if (!console_is_usable(c, flags, true) && |
|
|
4133 |
!console_is_usable(c, flags, false)) { |
3797 |
continue; |
4134 |
continue; |
|
|
4135 |
} |
3798 |
|
4136 |
|
3799 |
if (flags & CON_NBCON) { |
4137 |
if (flags & CON_NBCON) { |
3800 |
printk_seq = nbcon_seq_read(c); |
4138 |
printk_seq = nbcon_seq_read(c); |
3801 |
} else { |
4139 |
} else { |
|
|
4140 |
WARN_ON_ONCE(!locked); |
3802 |
printk_seq = c->seq; |
4141 |
printk_seq = c->seq; |
3803 |
} |
4142 |
} |
3804 |
|
4143 |
|
Lines 3810-3816
static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progre
Link Here
|
3810 |
if (diff != last_diff && reset_on_progress) |
4149 |
if (diff != last_diff && reset_on_progress) |
3811 |
remaining_jiffies = timeout_jiffies; |
4150 |
remaining_jiffies = timeout_jiffies; |
3812 |
|
4151 |
|
3813 |
console_unlock(); |
4152 |
if (locked) |
|
|
4153 |
console_unlock(); |
3814 |
|
4154 |
|
3815 |
/* Note: @diff is 0 if there are no usable consoles. */ |
4155 |
/* Note: @diff is 0 if there are no usable consoles. */ |
3816 |
if (diff == 0 || remaining_jiffies == 0) |
4156 |
if (diff == 0 || remaining_jiffies == 0) |
Lines 3862-3870
static void wake_up_klogd_work_func(struct irq_work *irq_work)
Link Here
|
3862 |
int pending = this_cpu_xchg(printk_pending, 0); |
4202 |
int pending = this_cpu_xchg(printk_pending, 0); |
3863 |
|
4203 |
|
3864 |
if (pending & PRINTK_PENDING_OUTPUT) { |
4204 |
if (pending & PRINTK_PENDING_OUTPUT) { |
3865 |
/* If trylock fails, someone else is doing the printing */ |
4205 |
if (IS_ENABLED(CONFIG_PREEMPT_RT)) { |
3866 |
if (console_trylock()) |
4206 |
wake_up_interruptible(&legacy_wait); |
3867 |
console_unlock(); |
4207 |
} else { |
|
|
4208 |
/* |
4209 |
* If trylock fails, some other context |
4210 |
* will do the printing. |
4211 |
*/ |
4212 |
if (console_trylock()) |
4213 |
console_unlock(); |
4214 |
} |
3868 |
} |
4215 |
} |
3869 |
|
4216 |
|
3870 |
if (pending & PRINTK_PENDING_WAKEUP) |
4217 |
if (pending & PRINTK_PENDING_WAKEUP) |
Lines 3932-3942
void defer_console_output(void)
Link Here
|
3932 |
* New messages may have been added directly to the ringbuffer |
4279 |
* New messages may have been added directly to the ringbuffer |
3933 |
* using vprintk_store(), so wake any waiters as well. |
4280 |
* using vprintk_store(), so wake any waiters as well. |
3934 |
*/ |
4281 |
*/ |
3935 |
__wake_up_klogd(PRINTK_PENDING_WAKEUP | PRINTK_PENDING_OUTPUT); |
4282 |
int val = PRINTK_PENDING_WAKEUP; |
|
|
4283 |
|
4284 |
if (printing_via_unlock) |
4285 |
val |= PRINTK_PENDING_OUTPUT; |
4286 |
__wake_up_klogd(val); |
3936 |
} |
4287 |
} |
3937 |
|
4288 |
|
3938 |
void printk_trigger_flush(void) |
4289 |
void printk_trigger_flush(void) |
3939 |
{ |
4290 |
{ |
|
|
4291 |
nbcon_wake_threads(); |
3940 |
defer_console_output(); |
4292 |
defer_console_output(); |
3941 |
} |
4293 |
} |
3942 |
|
4294 |
|