Commit b844e638 authored by Jiri Slaby (SUSE)'s avatar Jiri Slaby (SUSE) Committed by Greg Kroah-Hartman
Browse files

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: default avatarJiri Slaby (SUSE) <jirislaby@kernel.org>
Link: https://patch.msgid.link/20251119100140.830761-11-jirislaby@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f374a33e
Loading
Loading
Loading
Loading
+55 −72
Original line number Diff line number Diff line
@@ -1034,9 +1034,8 @@ static int uart_set_info_user(struct tty_struct *tty, struct serial_struct *ss)
{
	struct uart_state *state = tty->driver_data;
	struct tty_port *port = &state->port;
	int retval;

	down_write(&tty->termios_rwsem);
	guard(rwsem_write)(&tty->termios_rwsem);
	/*
	 * This semaphore protects port->count.  It is also
	 * very useful to prevent opens.  Also, take the
@@ -1044,11 +1043,8 @@ static int uart_set_info_user(struct tty_struct *tty, struct serial_struct *ss)
	 * module insertion/removal doesn't change anything
	 * under us.
	 */
	mutex_lock(&port->mutex);
	retval = uart_set_info(tty, port, state, ss);
	mutex_unlock(&port->mutex);
	up_write(&tty->termios_rwsem);
	return retval;
	guard(mutex)(&port->mutex);
	return uart_set_info(tty, port, state, ss);
}

/**
@@ -1562,10 +1558,8 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)

	/* This ioctl doesn't rely on the hardware to be present. */
	if (cmd == TIOCSERCONFIG) {
		down_write(&tty->termios_rwsem);
		ret = uart_do_autoconfig(tty, state);
		up_write(&tty->termios_rwsem);
		return ret;
		guard(rwsem_write)(&tty->termios_rwsem);
		return uart_do_autoconfig(tty, state);
	}

	if (tty_io_error(tty))
@@ -1579,12 +1573,12 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
	if (cmd == TIOCSRS485)
		down_write(&tty->termios_rwsem);

	mutex_lock(&port->mutex);
	scoped_guard(mutex, &port->mutex) {
		uport = uart_port_check(state);

		if (!uport || tty_io_error(tty)) {
			ret = -EIO;
		goto out_up;
			break;
		}

		/*
@@ -1617,8 +1611,8 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
				ret = uport->ops->ioctl(uport, cmd, arg);
			break;
		}
out_up:
	mutex_unlock(&port->mutex);
	}

	if (cmd == TIOCSRS485)
		up_write(&tty->termios_rwsem);

@@ -1634,11 +1628,10 @@ static void uart_set_ldisc(struct tty_struct *tty)
	if (!tty_port_initialized(port))
		return;

	mutex_lock(&state->port.mutex);
	guard(mutex)(&state->port.mutex);
	uport = uart_port_check(state);
	if (uport && uport->ops->set_ldisc)
		uport->ops->set_ldisc(uport, &tty->termios);
	mutex_unlock(&state->port.mutex);
}

static void uart_set_termios(struct tty_struct *tty,
@@ -1712,9 +1705,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp)

		state = drv->state + tty->index;
		port = &state->port;
		spin_lock_irq(&port->lock);
		guard(spinlock_irq)(&port->lock);
		--port->count;
		spin_unlock_irq(&port->lock);
		return;
	}

@@ -1826,20 +1818,18 @@ static void uart_hangup(struct tty_struct *tty)
	struct uart_state *state = tty->driver_data;
	struct tty_port *port = &state->port;
	struct uart_port *uport;
	unsigned long flags;

	pr_debug("uart_hangup(%d)\n", tty->index);

	mutex_lock(&port->mutex);
	guard(mutex)(&port->mutex);
	uport = uart_port_check(state);
	WARN(!uport, "hangup of detached port!\n");

	if (tty_port_active(port)) {
		uart_flush_buffer(tty);
		uart_shutdown(tty, state);
		spin_lock_irqsave(&port->lock, flags);
		scoped_guard(spinlock_irqsave, &port->lock)
			port->count = 0;
		spin_unlock_irqrestore(&port->lock, flags);
		tty_port_set_active(port, false);
		tty_port_tty_set(port, NULL);
		if (uport && !uart_console(uport))
@@ -1847,7 +1837,6 @@ static void uart_hangup(struct tty_struct *tty)
		wake_up_interruptible(&port->open_wait);
		wake_up_interruptible(&port->delta_msr_wait);
	}
	mutex_unlock(&port->mutex);
}

/* uport == NULL if uart_port has already been removed */
@@ -2952,11 +2941,11 @@ static ssize_t console_show(struct device *dev,
	struct uart_port *uport;
	bool console = false;

	mutex_lock(&port->mutex);
	scoped_guard(mutex, &port->mutex) {
		uport = uart_port_check(state);
		if (uport)
			console = uart_console_registered(uport);
	mutex_unlock(&port->mutex);
	}

	return sprintf(buf, "%c\n", console ? 'Y' : 'N');
}
@@ -3141,17 +3130,14 @@ static void serial_core_remove_one_port(struct uart_driver *drv,
	struct tty_port *port = &state->port;
	struct uart_port *uart_port;

	mutex_lock(&port->mutex);
	scoped_guard(mutex, &port->mutex) {
		uart_port = uart_port_check(state);
		if (uart_port != uport)
		dev_alert(uport->dev, "Removing wrong port: %p != %p\n",
			  uart_port, uport);
			dev_alert(uport->dev, "Removing wrong port: %p != %p\n", uart_port, uport);

	if (!uart_port) {
		mutex_unlock(&port->mutex);
		if (!uart_port)
			return;
	}
	mutex_unlock(&port->mutex);

	/*
	 * Remove the devices from the tty layer
@@ -3180,11 +3166,10 @@ static void serial_core_remove_one_port(struct uart_driver *drv,
	uport->type = PORT_UNKNOWN;
	uport->port_dev = NULL;

	mutex_lock(&port->mutex);
	guard(mutex)(&port->mutex);
	WARN_ON(atomic_dec_return(&state->refcount) < 0);
	wait_event(state->remove_wait, !atomic_read(&state->refcount));
	state->uart_port = NULL;
	mutex_unlock(&port->mutex);
}

/**
@@ -3337,7 +3322,7 @@ void serial_core_unregister_port(struct uart_driver *drv, struct uart_port *port
	struct serial_ctrl_device *ctrl_dev = serial_core_get_ctrl_dev(port_dev);
	int ctrl_id = port->ctrl_id;

	mutex_lock(&port_mutex);
	guard(mutex)(&port_mutex);

	port->flags |= UPF_DEAD;

@@ -3349,8 +3334,6 @@ void serial_core_unregister_port(struct uart_driver *drv, struct uart_port *port
	/* Drop the serial core controller device if no ports are using it */
	if (!serial_core_ctrl_find(drv, phys_dev, ctrl_id))
		serial_base_ctrl_device_remove(ctrl_dev);

	mutex_unlock(&port_mutex);
}

/**