lkml.org 
[lkml]   [2014]   [Oct]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH -next 10/10] serial: core: Fix port count when uart_open() errors
    Date
    A port count mismatch occurs if mutex_lock_interruptible()
    exits uart_open() and the port has already been opened. This may
    prematurely close a port on an open tty. Since uart_close() is _always_
    called if uart_open() fails, the port count must be corrected if errors
    occur.

    Always increment the port count in uart_open(), regardless of errors;
    always decrement the port count in uart_close(). Note that
    tty_port_close_start() decrements the port count when uart_open()
    was successful.

    Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
    ---
    drivers/tty/serial/serial_core.c | 25 +++++++++++++++----------
    1 file changed, 15 insertions(+), 10 deletions(-)

    diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
    index 6a3571e..3f02c2b 100644
    --- a/drivers/tty/serial/serial_core.c
    +++ b/drivers/tty/serial/serial_core.c
    @@ -1337,8 +1337,16 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
    struct uart_port *uport;
    unsigned long flags;

    - if (!state)
    + if (!state) {
    + struct uart_driver *drv = tty->driver->driver_state;
    +
    + state = drv->state + tty->index;
    + port = &state->port;
    + spin_lock_irq(&port->lock);
    + --port->count;
    + spin_unlock_irq(&port->lock);
    return;
    + }

    uport = state->uart_port;
    port = &state->port;
    @@ -1555,6 +1563,10 @@ static int uart_open(struct tty_struct *tty, struct file *filp)

    pr_debug("uart_open(%d) called\n", line);

    + spin_lock_irq(&port->lock);
    + ++port->count;
    + spin_unlock_irq(&port->lock);
    +
    /*
    * We take the semaphore here to guarantee that we won't be re-entered
    * while allocating the state structure, or while we request any IRQs
    @@ -1567,17 +1579,11 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
    goto end;
    }

    - port->count++;
    if (!state->uart_port || state->uart_port->flags & UPF_DEAD) {
    retval = -ENXIO;
    - goto err_dec_count;
    + goto err_unlock;
    }

    - /*
    - * Once we set tty->driver_data here, we are guaranteed that
    - * uart_close() will decrement the driver module use count.
    - * Any failures from here onwards should not touch the count.
    - */
    tty->driver_data = state;
    state->uart_port->state = state;
    state->port.low_latency =
    @@ -1598,8 +1604,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)

    end:
    return retval;
    -err_dec_count:
    - port->count--;
    +err_unlock:
    mutex_unlock(&port->mutex);
    goto end;
    }
    --
    2.1.1


    \
     
     \ /
      Last update: 2014-10-17 00:41    [W:3.107 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site