Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: serial_core: use guard()s

Use guards in the serial_core code. This improves readability, makes
error handling easier, and marks locked portions of code explicit. All
that while being sure the lock is unlocked.

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
Link: https://patch.msgid.link/20251119100140.830761-11-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jiri Slaby (SUSE) and committed by
Greg Kroah-Hartman
b844e638 f374a33e

+60 -77
+60 -77
drivers/tty/serial/serial_core.c
··· 1034 1034 { 1035 1035 struct uart_state *state = tty->driver_data; 1036 1036 struct tty_port *port = &state->port; 1037 - int retval; 1038 1037 1039 - down_write(&tty->termios_rwsem); 1038 + guard(rwsem_write)(&tty->termios_rwsem); 1040 1039 /* 1041 1040 * This semaphore protects port->count. It is also 1042 1041 * very useful to prevent opens. Also, take the ··· 1043 1044 * module insertion/removal doesn't change anything 1044 1045 * under us. 1045 1046 */ 1046 - mutex_lock(&port->mutex); 1047 - retval = uart_set_info(tty, port, state, ss); 1048 - mutex_unlock(&port->mutex); 1049 - up_write(&tty->termios_rwsem); 1050 - return retval; 1047 + guard(mutex)(&port->mutex); 1048 + return uart_set_info(tty, port, state, ss); 1051 1049 } 1052 1050 1053 1051 /** ··· 1558 1562 1559 1563 /* This ioctl doesn't rely on the hardware to be present. */ 1560 1564 if (cmd == TIOCSERCONFIG) { 1561 - down_write(&tty->termios_rwsem); 1562 - ret = uart_do_autoconfig(tty, state); 1563 - up_write(&tty->termios_rwsem); 1564 - return ret; 1565 + guard(rwsem_write)(&tty->termios_rwsem); 1566 + return uart_do_autoconfig(tty, state); 1565 1567 } 1566 1568 1567 1569 if (tty_io_error(tty)) ··· 1573 1579 if (cmd == TIOCSRS485) 1574 1580 down_write(&tty->termios_rwsem); 1575 1581 1576 - mutex_lock(&port->mutex); 1577 - uport = uart_port_check(state); 1582 + scoped_guard(mutex, &port->mutex) { 1583 + uport = uart_port_check(state); 1578 1584 1579 - if (!uport || tty_io_error(tty)) { 1580 - ret = -EIO; 1581 - goto out_up; 1585 + if (!uport || tty_io_error(tty)) { 1586 + ret = -EIO; 1587 + break; 1588 + } 1589 + 1590 + /* 1591 + * All these rely on hardware being present and need to be 1592 + * protected against the tty being hung up. 1593 + */ 1594 + 1595 + switch (cmd) { 1596 + case TIOCSERGETLSR: /* Get line status register */ 1597 + ret = uart_get_lsr_info(tty, state, uarg); 1598 + break; 1599 + 1600 + case TIOCGRS485: 1601 + ret = uart_get_rs485_config(uport, uarg); 1602 + break; 1603 + 1604 + case TIOCSRS485: 1605 + ret = uart_set_rs485_config(tty, uport, uarg); 1606 + break; 1607 + 1608 + case TIOCSISO7816: 1609 + ret = uart_set_iso7816_config(state->uart_port, uarg); 1610 + break; 1611 + 1612 + case TIOCGISO7816: 1613 + ret = uart_get_iso7816_config(state->uart_port, uarg); 1614 + break; 1615 + default: 1616 + if (uport->ops->ioctl) 1617 + ret = uport->ops->ioctl(uport, cmd, arg); 1618 + break; 1619 + } 1582 1620 } 1583 1621 1584 - /* 1585 - * All these rely on hardware being present and need to be 1586 - * protected against the tty being hung up. 1587 - */ 1588 - 1589 - switch (cmd) { 1590 - case TIOCSERGETLSR: /* Get line status register */ 1591 - ret = uart_get_lsr_info(tty, state, uarg); 1592 - break; 1593 - 1594 - case TIOCGRS485: 1595 - ret = uart_get_rs485_config(uport, uarg); 1596 - break; 1597 - 1598 - case TIOCSRS485: 1599 - ret = uart_set_rs485_config(tty, uport, uarg); 1600 - break; 1601 - 1602 - case TIOCSISO7816: 1603 - ret = uart_set_iso7816_config(state->uart_port, uarg); 1604 - break; 1605 - 1606 - case TIOCGISO7816: 1607 - ret = uart_get_iso7816_config(state->uart_port, uarg); 1608 - break; 1609 - default: 1610 - if (uport->ops->ioctl) 1611 - ret = uport->ops->ioctl(uport, cmd, arg); 1612 - break; 1613 - } 1614 - out_up: 1615 - mutex_unlock(&port->mutex); 1616 1622 if (cmd == TIOCSRS485) 1617 1623 up_write(&tty->termios_rwsem); 1618 1624 ··· 1628 1634 if (!tty_port_initialized(port)) 1629 1635 return; 1630 1636 1631 - mutex_lock(&state->port.mutex); 1637 + guard(mutex)(&state->port.mutex); 1632 1638 uport = uart_port_check(state); 1633 1639 if (uport && uport->ops->set_ldisc) 1634 1640 uport->ops->set_ldisc(uport, &tty->termios); 1635 - mutex_unlock(&state->port.mutex); 1636 1641 } 1637 1642 1638 1643 static void uart_set_termios(struct tty_struct *tty, ··· 1705 1712 1706 1713 state = drv->state + tty->index; 1707 1714 port = &state->port; 1708 - spin_lock_irq(&port->lock); 1715 + guard(spinlock_irq)(&port->lock); 1709 1716 --port->count; 1710 - spin_unlock_irq(&port->lock); 1711 1717 return; 1712 1718 } 1713 1719 ··· 1818 1826 struct uart_state *state = tty->driver_data; 1819 1827 struct tty_port *port = &state->port; 1820 1828 struct uart_port *uport; 1821 - unsigned long flags; 1822 1829 1823 1830 pr_debug("uart_hangup(%d)\n", tty->index); 1824 1831 1825 - mutex_lock(&port->mutex); 1832 + guard(mutex)(&port->mutex); 1826 1833 uport = uart_port_check(state); 1827 1834 WARN(!uport, "hangup of detached port!\n"); 1828 1835 1829 1836 if (tty_port_active(port)) { 1830 1837 uart_flush_buffer(tty); 1831 1838 uart_shutdown(tty, state); 1832 - spin_lock_irqsave(&port->lock, flags); 1833 - port->count = 0; 1834 - spin_unlock_irqrestore(&port->lock, flags); 1839 + scoped_guard(spinlock_irqsave, &port->lock) 1840 + port->count = 0; 1835 1841 tty_port_set_active(port, false); 1836 1842 tty_port_tty_set(port, NULL); 1837 1843 if (uport && !uart_console(uport)) ··· 1837 1847 wake_up_interruptible(&port->open_wait); 1838 1848 wake_up_interruptible(&port->delta_msr_wait); 1839 1849 } 1840 - mutex_unlock(&port->mutex); 1841 1850 } 1842 1851 1843 1852 /* uport == NULL if uart_port has already been removed */ ··· 2941 2952 struct uart_port *uport; 2942 2953 bool console = false; 2943 2954 2944 - mutex_lock(&port->mutex); 2945 - uport = uart_port_check(state); 2946 - if (uport) 2947 - console = uart_console_registered(uport); 2948 - mutex_unlock(&port->mutex); 2955 + scoped_guard(mutex, &port->mutex) { 2956 + uport = uart_port_check(state); 2957 + if (uport) 2958 + console = uart_console_registered(uport); 2959 + } 2949 2960 2950 2961 return sprintf(buf, "%c\n", console ? 'Y' : 'N'); 2951 2962 } ··· 3130 3141 struct tty_port *port = &state->port; 3131 3142 struct uart_port *uart_port; 3132 3143 3133 - mutex_lock(&port->mutex); 3134 - uart_port = uart_port_check(state); 3135 - if (uart_port != uport) 3136 - dev_alert(uport->dev, "Removing wrong port: %p != %p\n", 3137 - uart_port, uport); 3144 + scoped_guard(mutex, &port->mutex) { 3145 + uart_port = uart_port_check(state); 3146 + if (uart_port != uport) 3147 + dev_alert(uport->dev, "Removing wrong port: %p != %p\n", uart_port, uport); 3138 3148 3139 - if (!uart_port) { 3140 - mutex_unlock(&port->mutex); 3141 - return; 3149 + if (!uart_port) 3150 + return; 3142 3151 } 3143 - mutex_unlock(&port->mutex); 3144 3152 3145 3153 /* 3146 3154 * Remove the devices from the tty layer ··· 3166 3180 uport->type = PORT_UNKNOWN; 3167 3181 uport->port_dev = NULL; 3168 3182 3169 - mutex_lock(&port->mutex); 3183 + guard(mutex)(&port->mutex); 3170 3184 WARN_ON(atomic_dec_return(&state->refcount) < 0); 3171 3185 wait_event(state->remove_wait, !atomic_read(&state->refcount)); 3172 3186 state->uart_port = NULL; 3173 - mutex_unlock(&port->mutex); 3174 3187 } 3175 3188 3176 3189 /** ··· 3322 3337 struct serial_ctrl_device *ctrl_dev = serial_core_get_ctrl_dev(port_dev); 3323 3338 int ctrl_id = port->ctrl_id; 3324 3339 3325 - mutex_lock(&port_mutex); 3340 + guard(mutex)(&port_mutex); 3326 3341 3327 3342 port->flags |= UPF_DEAD; 3328 3343 ··· 3334 3349 /* Drop the serial core controller device if no ports are using it */ 3335 3350 if (!serial_core_ctrl_find(drv, phys_dev, ctrl_id)) 3336 3351 serial_base_ctrl_device_remove(ctrl_dev); 3337 - 3338 - mutex_unlock(&port_mutex); 3339 3352 } 3340 3353 3341 3354 /**