.. | .. |
---|
429 | 429 | printk_safe_exit_irqrestore(flags); \ |
---|
430 | 430 | } while (0) |
---|
431 | 431 | |
---|
| 432 | +#ifdef CONFIG_EARLY_PRINTK |
---|
| 433 | +struct console *early_console; |
---|
| 434 | + |
---|
| 435 | +static void early_vprintk(const char *fmt, va_list ap) |
---|
| 436 | +{ |
---|
| 437 | + if (early_console) { |
---|
| 438 | + char buf[512]; |
---|
| 439 | + int n = vscnprintf(buf, sizeof(buf), fmt, ap); |
---|
| 440 | + |
---|
| 441 | + early_console->write(early_console, buf, n); |
---|
| 442 | + } |
---|
| 443 | +} |
---|
| 444 | + |
---|
| 445 | +asmlinkage void early_printk(const char *fmt, ...) |
---|
| 446 | +{ |
---|
| 447 | + va_list ap; |
---|
| 448 | + |
---|
| 449 | + va_start(ap, fmt); |
---|
| 450 | + early_vprintk(fmt, ap); |
---|
| 451 | + va_end(ap); |
---|
| 452 | +} |
---|
| 453 | + |
---|
| 454 | +/* |
---|
| 455 | + * This is independent of any log levels - a global |
---|
| 456 | + * kill switch that turns off all of printk. |
---|
| 457 | + * |
---|
| 458 | + * Used by the NMI watchdog if early-printk is enabled. |
---|
| 459 | + */ |
---|
| 460 | +static bool __read_mostly printk_killswitch; |
---|
| 461 | + |
---|
| 462 | +static int __init force_early_printk_setup(char *str) |
---|
| 463 | +{ |
---|
| 464 | + printk_killswitch = true; |
---|
| 465 | + return 0; |
---|
| 466 | +} |
---|
| 467 | +early_param("force_early_printk", force_early_printk_setup); |
---|
| 468 | + |
---|
| 469 | +void printk_kill(void) |
---|
| 470 | +{ |
---|
| 471 | + printk_killswitch = true; |
---|
| 472 | +} |
---|
| 473 | + |
---|
| 474 | +#ifdef CONFIG_PRINTK |
---|
| 475 | +static int forced_early_printk(const char *fmt, va_list ap) |
---|
| 476 | +{ |
---|
| 477 | + if (!printk_killswitch) |
---|
| 478 | + return 0; |
---|
| 479 | + early_vprintk(fmt, ap); |
---|
| 480 | + return 1; |
---|
| 481 | +} |
---|
| 482 | +#endif |
---|
| 483 | + |
---|
| 484 | +#else |
---|
| 485 | +static inline int forced_early_printk(const char *fmt, va_list ap) |
---|
| 486 | +{ |
---|
| 487 | + return 0; |
---|
| 488 | +} |
---|
| 489 | +#endif |
---|
| 490 | + |
---|
432 | 491 | #ifdef CONFIG_PRINTK |
---|
433 | 492 | DECLARE_WAIT_QUEUE_HEAD(log_wait); |
---|
434 | 493 | /* the next printk record to read by syslog(READ) or /proc/kmsg */ |
---|
.. | .. |
---|
1517 | 1576 | u64 next_seq; |
---|
1518 | 1577 | u64 seq; |
---|
1519 | 1578 | u32 idx; |
---|
| 1579 | + int attempts = 0; |
---|
| 1580 | + int num_msg; |
---|
1520 | 1581 | |
---|
1521 | 1582 | text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); |
---|
1522 | 1583 | if (!text) |
---|
1523 | 1584 | return -ENOMEM; |
---|
1524 | 1585 | |
---|
1525 | 1586 | logbuf_lock_irq(); |
---|
| 1587 | + |
---|
| 1588 | +try_again: |
---|
| 1589 | + attempts++; |
---|
| 1590 | + if (attempts > 10) { |
---|
| 1591 | + len = -EBUSY; |
---|
| 1592 | + goto out; |
---|
| 1593 | + } |
---|
| 1594 | + num_msg = 0; |
---|
| 1595 | + |
---|
1526 | 1596 | /* |
---|
1527 | 1597 | * Find first record that fits, including all following records, |
---|
1528 | 1598 | * into the user-provided buffer for this dump. |
---|
.. | .. |
---|
1535 | 1605 | len += msg_print_text(msg, true, NULL, 0); |
---|
1536 | 1606 | idx = log_next(idx); |
---|
1537 | 1607 | seq++; |
---|
| 1608 | + num_msg++; |
---|
| 1609 | + if (num_msg > 5) { |
---|
| 1610 | + num_msg = 0; |
---|
| 1611 | + logbuf_unlock_irq(); |
---|
| 1612 | + logbuf_lock_irq(); |
---|
| 1613 | + if (clear_seq < log_first_seq) |
---|
| 1614 | + goto try_again; |
---|
| 1615 | + } |
---|
1538 | 1616 | } |
---|
1539 | 1617 | |
---|
1540 | 1618 | /* move first record forward until length fits into the buffer */ |
---|
.. | .. |
---|
1546 | 1624 | len -= msg_print_text(msg, true, NULL, 0); |
---|
1547 | 1625 | idx = log_next(idx); |
---|
1548 | 1626 | seq++; |
---|
| 1627 | + num_msg++; |
---|
| 1628 | + if (num_msg > 5) { |
---|
| 1629 | + num_msg = 0; |
---|
| 1630 | + logbuf_unlock_irq(); |
---|
| 1631 | + logbuf_lock_irq(); |
---|
| 1632 | + if (clear_seq < log_first_seq) |
---|
| 1633 | + goto try_again; |
---|
| 1634 | + } |
---|
1549 | 1635 | } |
---|
1550 | 1636 | |
---|
1551 | 1637 | /* last message fitting into this dump */ |
---|
.. | .. |
---|
1583 | 1669 | clear_seq = log_next_seq; |
---|
1584 | 1670 | clear_idx = log_next_idx; |
---|
1585 | 1671 | } |
---|
| 1672 | +out: |
---|
1586 | 1673 | logbuf_unlock_irq(); |
---|
1587 | 1674 | |
---|
1588 | 1675 | kfree(text); |
---|
.. | .. |
---|
1714 | 1801 | return do_syslog(type, buf, len, SYSLOG_FROM_READER); |
---|
1715 | 1802 | } |
---|
1716 | 1803 | |
---|
| 1804 | +#ifndef CONFIG_PREEMPT_RT_FULL |
---|
1717 | 1805 | /* |
---|
1718 | 1806 | * Special console_lock variants that help to reduce the risk of soft-lockups. |
---|
1719 | 1807 | * They allow to pass console_lock to another printk() call using a busy wait. |
---|
.. | .. |
---|
1854 | 1942 | return 1; |
---|
1855 | 1943 | } |
---|
1856 | 1944 | |
---|
| 1945 | +#else |
---|
| 1946 | + |
---|
| 1947 | +static int console_trylock_spinning(void) |
---|
| 1948 | +{ |
---|
| 1949 | + return console_trylock(); |
---|
| 1950 | +} |
---|
| 1951 | + |
---|
| 1952 | +#endif |
---|
| 1953 | + |
---|
1857 | 1954 | /* |
---|
1858 | 1955 | * Call the console drivers, asking them to write out |
---|
1859 | 1956 | * log_buf[start] to log_buf[end - 1]. |
---|
.. | .. |
---|
1872 | 1969 | if (!console_drivers) |
---|
1873 | 1970 | return; |
---|
1874 | 1971 | |
---|
| 1972 | + if (IS_ENABLED(CONFIG_PREEMPT_RT_BASE)) { |
---|
| 1973 | + if (in_irq() || in_nmi()) |
---|
| 1974 | + return; |
---|
| 1975 | + } |
---|
| 1976 | + |
---|
| 1977 | + migrate_disable(); |
---|
1875 | 1978 | for_each_console(con) { |
---|
1876 | 1979 | if (exclusive_console && con != exclusive_console) |
---|
1877 | 1980 | continue; |
---|
.. | .. |
---|
1887 | 1990 | else |
---|
1888 | 1991 | con->write(con, text, len); |
---|
1889 | 1992 | } |
---|
| 1993 | + migrate_enable(); |
---|
1890 | 1994 | } |
---|
1891 | 1995 | |
---|
1892 | 1996 | int printk_delay_msec __read_mostly; |
---|
.. | .. |
---|
2057 | 2161 | unsigned long flags; |
---|
2058 | 2162 | u64 curr_log_seq; |
---|
2059 | 2163 | |
---|
| 2164 | + /* |
---|
| 2165 | + * Fall back to early_printk if a debugging subsystem has |
---|
| 2166 | + * killed printk output |
---|
| 2167 | + */ |
---|
| 2168 | + if (unlikely(forced_early_printk(fmt, args))) |
---|
| 2169 | + return 1; |
---|
| 2170 | + |
---|
2060 | 2171 | if (level == LOGLEVEL_SCHED) { |
---|
2061 | 2172 | level = LOGLEVEL_DEFAULT; |
---|
2062 | 2173 | in_sched = true; |
---|
.. | .. |
---|
2074 | 2185 | |
---|
2075 | 2186 | /* If called from the scheduler, we can not call up(). */ |
---|
2076 | 2187 | if (!in_sched && pending_output) { |
---|
| 2188 | + int may_trylock = 1; |
---|
| 2189 | + |
---|
| 2190 | +#ifdef CONFIG_PREEMPT_RT_FULL |
---|
| 2191 | + /* |
---|
| 2192 | + * we can't take a sleeping lock with IRQs or preeption disabled |
---|
| 2193 | + * so we can't print in these contexts |
---|
| 2194 | + */ |
---|
| 2195 | + if (!(preempt_count() == 0 && !irqs_disabled())) |
---|
| 2196 | + may_trylock = 0; |
---|
| 2197 | +#endif |
---|
2077 | 2198 | /* |
---|
2078 | 2199 | * Disable preemption to avoid being preempted while holding |
---|
2079 | 2200 | * console_sem which would prevent anyone from printing to |
---|
2080 | 2201 | * console |
---|
2081 | 2202 | */ |
---|
2082 | | - preempt_disable(); |
---|
| 2203 | + migrate_disable(); |
---|
2083 | 2204 | /* |
---|
2084 | 2205 | * Try to acquire and then immediately release the console |
---|
2085 | 2206 | * semaphore. The release will print out buffers and wake up |
---|
2086 | 2207 | * /dev/kmsg and syslog() users. |
---|
2087 | 2208 | */ |
---|
2088 | | - if (console_trylock_spinning()) |
---|
| 2209 | + if (may_trylock && console_trylock_spinning()) |
---|
2089 | 2210 | console_unlock(); |
---|
2090 | | - preempt_enable(); |
---|
| 2211 | + migrate_enable(); |
---|
2091 | 2212 | } |
---|
2092 | 2213 | |
---|
2093 | 2214 | if (pending_output) |
---|
.. | .. |
---|
2200 | 2321 | static bool suppress_message_printing(int level) { return false; } |
---|
2201 | 2322 | |
---|
2202 | 2323 | #endif /* CONFIG_PRINTK */ |
---|
2203 | | - |
---|
2204 | | -#ifdef CONFIG_EARLY_PRINTK |
---|
2205 | | -struct console *early_console; |
---|
2206 | | - |
---|
2207 | | -asmlinkage __visible void early_printk(const char *fmt, ...) |
---|
2208 | | -{ |
---|
2209 | | - va_list ap; |
---|
2210 | | - char buf[512]; |
---|
2211 | | - int n; |
---|
2212 | | - |
---|
2213 | | - if (!early_console) |
---|
2214 | | - return; |
---|
2215 | | - |
---|
2216 | | - va_start(ap, fmt); |
---|
2217 | | - n = vscnprintf(buf, sizeof(buf), fmt, ap); |
---|
2218 | | - va_end(ap); |
---|
2219 | | - |
---|
2220 | | - early_console->write(early_console, buf, n); |
---|
2221 | | -} |
---|
2222 | | -#endif |
---|
2223 | 2324 | |
---|
2224 | 2325 | static int __add_preferred_console(char *name, int idx, char *options, |
---|
2225 | 2326 | char *brl_options) |
---|
.. | .. |
---|
2579 | 2680 | console_seq++; |
---|
2580 | 2681 | raw_spin_unlock(&logbuf_lock); |
---|
2581 | 2682 | |
---|
| 2683 | +#ifdef CONFIG_PREEMPT_RT_FULL |
---|
| 2684 | + printk_safe_exit_irqrestore(flags); |
---|
| 2685 | + call_console_drivers(ext_text, ext_len, text, len); |
---|
| 2686 | +#else |
---|
2582 | 2687 | /* |
---|
2583 | 2688 | * While actively printing out messages, if another printk() |
---|
2584 | 2689 | * were to occur on another CPU, it may wait for this one to |
---|
.. | .. |
---|
2601 | 2706 | } |
---|
2602 | 2707 | |
---|
2603 | 2708 | printk_safe_exit_irqrestore(flags); |
---|
| 2709 | +#endif |
---|
2604 | 2710 | |
---|
2605 | 2711 | if (do_cond_resched) |
---|
2606 | 2712 | cond_resched(); |
---|
.. | .. |
---|
2648 | 2754 | { |
---|
2649 | 2755 | struct console *c; |
---|
2650 | 2756 | |
---|
| 2757 | + if (IS_ENABLED(CONFIG_PREEMPT_RT_BASE)) { |
---|
| 2758 | + if (in_irq() || in_nmi()) |
---|
| 2759 | + return; |
---|
| 2760 | + } |
---|
| 2761 | + |
---|
2651 | 2762 | /* |
---|
2652 | 2763 | * console_unblank can no longer be called in interrupt context unless |
---|
2653 | 2764 | * oops_in_progress is set to 1.. |
---|