diff options
| -rw-r--r-- | kernel/printk/printk.c | 245 |
1 files changed, 148 insertions, 97 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 040fb948924e..3a475f58b749 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
| @@ -86,15 +86,8 @@ EXPORT_SYMBOL_GPL(console_drivers); | |||
| 86 | static struct lockdep_map console_lock_dep_map = { | 86 | static struct lockdep_map console_lock_dep_map = { |
| 87 | .name = "console_lock" | 87 | .name = "console_lock" |
| 88 | }; | 88 | }; |
| 89 | static struct lockdep_map console_owner_dep_map = { | ||
| 90 | .name = "console_owner" | ||
| 91 | }; | ||
| 92 | #endif | 89 | #endif |
| 93 | 90 | ||
| 94 | static DEFINE_RAW_SPINLOCK(console_owner_lock); | ||
| 95 | static struct task_struct *console_owner; | ||
| 96 | static bool console_waiter; | ||
| 97 | |||
| 98 | enum devkmsg_log_bits { | 91 | enum devkmsg_log_bits { |
| 99 | __DEVKMSG_LOG_BIT_ON = 0, | 92 | __DEVKMSG_LOG_BIT_ON = 0, |
| 100 | __DEVKMSG_LOG_BIT_OFF, | 93 | __DEVKMSG_LOG_BIT_OFF, |
| @@ -1551,6 +1544,146 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | |||
| 1551 | } | 1544 | } |
| 1552 | 1545 | ||
| 1553 | /* | 1546 | /* |
| 1547 | * Special console_lock variants that help to reduce the risk of soft-lockups. | ||
| 1548 | * They allow to pass console_lock to another printk() call using a busy wait. | ||
| 1549 | */ | ||
| 1550 | |||
| 1551 | #ifdef CONFIG_LOCKDEP | ||
| 1552 | static struct lockdep_map console_owner_dep_map = { | ||
| 1553 | .name = "console_owner" | ||
| 1554 | }; | ||
| 1555 | #endif | ||
| 1556 | |||
| 1557 | static DEFINE_RAW_SPINLOCK(console_owner_lock); | ||
| 1558 | static struct task_struct *console_owner; | ||
| 1559 | static bool console_waiter; | ||
| 1560 | |||
| 1561 | /** | ||
| 1562 | * console_lock_spinning_enable - mark beginning of code where another | ||
| 1563 | * thread might safely busy wait | ||
| 1564 | * | ||
| 1565 | * This basically converts console_lock into a spinlock. This marks | ||
| 1566 | * the section where the console_lock owner can not sleep, because | ||
| 1567 | * there may be a waiter spinning (like a spinlock). Also it must be | ||
| 1568 | * ready to hand over the lock at the end of the section. | ||
| 1569 | */ | ||
| 1570 | static void console_lock_spinning_enable(void) | ||
| 1571 | { | ||
| 1572 | raw_spin_lock(&console_owner_lock); | ||
| 1573 | console_owner = current; | ||
| 1574 | raw_spin_unlock(&console_owner_lock); | ||
| 1575 | |||
| 1576 | /* The waiter may spin on us after setting console_owner */ | ||
| 1577 | spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | /** | ||
| 1581 | * console_lock_spinning_disable_and_check - mark end of code where another | ||
| 1582 | * thread was able to busy wait and check if there is a waiter | ||
| 1583 | * | ||
| 1584 | * This is called at the end of the section where spinning is allowed. | ||
| 1585 | * It has two functions. First, it is a signal that it is no longer | ||
| 1586 | * safe to start busy waiting for the lock. Second, it checks if | ||
| 1587 | * there is a busy waiter and passes the lock rights to her. | ||
| 1588 | * | ||
| 1589 | * Important: Callers lose the lock if there was a busy waiter. | ||
| 1590 | * They must not touch items synchronized by console_lock | ||
| 1591 | * in this case. | ||
| 1592 | * | ||
| 1593 | * Return: 1 if the lock rights were passed, 0 otherwise. | ||
| 1594 | */ | ||
| 1595 | static int console_lock_spinning_disable_and_check(void) | ||
| 1596 | { | ||
| 1597 | int waiter; | ||
| 1598 | |||
| 1599 | raw_spin_lock(&console_owner_lock); | ||
| 1600 | waiter = READ_ONCE(console_waiter); | ||
| 1601 | console_owner = NULL; | ||
| 1602 | raw_spin_unlock(&console_owner_lock); | ||
| 1603 | |||
| 1604 | if (!waiter) { | ||
| 1605 | spin_release(&console_owner_dep_map, 1, _THIS_IP_); | ||
| 1606 | return 0; | ||
| 1607 | } | ||
| 1608 | |||
| 1609 | /* The waiter is now free to continue */ | ||
| 1610 | WRITE_ONCE(console_waiter, false); | ||
| 1611 | |||
| 1612 | spin_release(&console_owner_dep_map, 1, _THIS_IP_); | ||
| 1613 | |||
| 1614 | /* | ||
| 1615 | * Hand off console_lock to waiter. The waiter will perform | ||
| 1616 | * the up(). After this, the waiter is the console_lock owner. | ||
| 1617 | */ | ||
| 1618 | mutex_release(&console_lock_dep_map, 1, _THIS_IP_); | ||
| 1619 | return 1; | ||
| 1620 | } | ||
| 1621 | |||
| 1622 | /** | ||
| 1623 | * console_trylock_spinning - try to get console_lock by busy waiting | ||
| 1624 | * | ||
| 1625 | * This allows to busy wait for the console_lock when the current | ||
| 1626 | * owner is running in specially marked sections. It means that | ||
| 1627 | * the current owner is running and cannot reschedule until it | ||
| 1628 | * is ready to lose the lock. | ||
| 1629 | * | ||
| 1630 | * Return: 1 if we got the lock, 0 othrewise | ||
| 1631 | */ | ||
| 1632 | static int console_trylock_spinning(void) | ||
| 1633 | { | ||
| 1634 | struct task_struct *owner = NULL; | ||
| 1635 | bool waiter; | ||
| 1636 | bool spin = false; | ||
| 1637 | unsigned long flags; | ||
| 1638 | |||
| 1639 | if (console_trylock()) | ||
| 1640 | return 1; | ||
| 1641 | |||
| 1642 | printk_safe_enter_irqsave(flags); | ||
| 1643 | |||
| 1644 | raw_spin_lock(&console_owner_lock); | ||
| 1645 | owner = READ_ONCE(console_owner); | ||
| 1646 | waiter = READ_ONCE(console_waiter); | ||
| 1647 | if (!waiter && owner && owner != current) { | ||
| 1648 | WRITE_ONCE(console_waiter, true); | ||
| 1649 | spin = true; | ||
| 1650 | } | ||
| 1651 | raw_spin_unlock(&console_owner_lock); | ||
| 1652 | |||
| 1653 | /* | ||
| 1654 | * If there is an active printk() writing to the | ||
| 1655 | * consoles, instead of having it write our data too, | ||
| 1656 | * see if we can offload that load from the active | ||
| 1657 | * printer, and do some printing ourselves. | ||
| 1658 | * Go into a spin only if there isn't already a waiter | ||
| 1659 | * spinning, and there is an active printer, and | ||
| 1660 | * that active printer isn't us (recursive printk?). | ||
| 1661 | */ | ||
| 1662 | if (!spin) { | ||
| 1663 | printk_safe_exit_irqrestore(flags); | ||
| 1664 | return 0; | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | /* We spin waiting for the owner to release us */ | ||
| 1668 | spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); | ||
| 1669 | /* Owner will clear console_waiter on hand off */ | ||
| 1670 | while (READ_ONCE(console_waiter)) | ||
| 1671 | cpu_relax(); | ||
| 1672 | spin_release(&console_owner_dep_map, 1, _THIS_IP_); | ||
| 1673 | |||
| 1674 | printk_safe_exit_irqrestore(flags); | ||
| 1675 | /* | ||
| 1676 | * The owner passed the console lock to us. | ||
| 1677 | * Since we did not spin on console lock, annotate | ||
| 1678 | * this as a trylock. Otherwise lockdep will | ||
| 1679 | * complain. | ||
| 1680 | */ | ||
| 1681 | mutex_acquire(&console_lock_dep_map, 0, 1, _THIS_IP_); | ||
| 1682 | |||
| 1683 | return 1; | ||
| 1684 | } | ||
| 1685 | |||
| 1686 | /* | ||
| 1554 | * Call the console drivers, asking them to write out | 1687 | * Call the console drivers, asking them to write out |
| 1555 | * log_buf[start] to log_buf[end - 1]. | 1688 | * log_buf[start] to log_buf[end - 1]. |
| 1556 | * The console_lock must be held. | 1689 | * The console_lock must be held. |
| @@ -1760,56 +1893,8 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
| 1760 | * semaphore. The release will print out buffers and wake up | 1893 | * semaphore. The release will print out buffers and wake up |
| 1761 | * /dev/kmsg and syslog() users. | 1894 | * /dev/kmsg and syslog() users. |
| 1762 | */ | 1895 | */ |
| 1763 | if (console_trylock()) { | 1896 | if (console_trylock_spinning()) |
| 1764 | console_unlock(); | 1897 | console_unlock(); |
| 1765 | } else { | ||
| 1766 | struct task_struct *owner = NULL; | ||
| 1767 | bool waiter; | ||
| 1768 | bool spin = false; | ||
| 1769 | |||
| 1770 | printk_safe_enter_irqsave(flags); | ||
| 1771 | |||
| 1772 | raw_spin_lock(&console_owner_lock); | ||
| 1773 | owner = READ_ONCE(console_owner); | ||
| 1774 | waiter = READ_ONCE(console_waiter); | ||
| 1775 | if (!waiter && owner && owner != current) { | ||
| 1776 | WRITE_ONCE(console_waiter, true); | ||
| 1777 | spin = true; | ||
| 1778 | } | ||
| 1779 | raw_spin_unlock(&console_owner_lock); | ||
| 1780 | |||
| 1781 | /* | ||
| 1782 | * If there is an active printk() writing to the | ||
| 1783 | * consoles, instead of having it write our data too, | ||
| 1784 | * see if we can offload that load from the active | ||
| 1785 | * printer, and do some printing ourselves. | ||
| 1786 | * Go into a spin only if there isn't already a waiter | ||
| 1787 | * spinning, and there is an active printer, and | ||
| 1788 | * that active printer isn't us (recursive printk?). | ||
| 1789 | */ | ||
| 1790 | if (spin) { | ||
| 1791 | /* We spin waiting for the owner to release us */ | ||
| 1792 | spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); | ||
| 1793 | /* Owner will clear console_waiter on hand off */ | ||
| 1794 | while (READ_ONCE(console_waiter)) | ||
| 1795 | cpu_relax(); | ||
| 1796 | |||
| 1797 | spin_release(&console_owner_dep_map, 1, _THIS_IP_); | ||
| 1798 | printk_safe_exit_irqrestore(flags); | ||
| 1799 | |||
| 1800 | /* | ||
| 1801 | * The owner passed the console lock to us. | ||
| 1802 | * Since we did not spin on console lock, annotate | ||
| 1803 | * this as a trylock. Otherwise lockdep will | ||
