Re: [PATCH v1 1/2] serial: 8250_port: fix runtime PM use in __do_stop_tx_rs485()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2016-08-26 15:49 GMT+03:00 Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>:
> There are calls to serial8250_rpm_{get|put}() in __do_stop_tx_rs485() that are
> certainly placed in a wrong location. I dunno how it had been tested with
> runtime PM enabled because it is obvious "sleep in atomic context" error.
>
> Besides that serial8250_rpm_get() is called immediately after an IO just
> happened. It implies that the device is already powered on, see implementation
> of serial8250_em485_rts_after_send() and serial8250_clear_fifos() for the
> details.
>
> There is no bug have been seen due to, as I can guess, use of auto suspend mode
> when scheduled transaction to suspend is invoked quite lately than it's needed
> for a few writes to the port. It might be possible to trigger a warning if
> stop_tx_timer fires when device is suspended.
>
> Refactor the code to use runtime PM only in case of timer function.
>
> Cc: "Matwey V. Kornilov" <matwey@xxxxxxxxxx>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
> ---
>  drivers/tty/serial/8250/8250_port.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
> index 9bad1c5..bc7cd1a 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -1414,12 +1414,8 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p)
>         if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
>                 serial8250_clear_fifos(p);
>
> -               serial8250_rpm_get(p);
> -
>                 p->ier |= UART_IER_RLSI | UART_IER_RDI;
>                 serial_port_out(&p->port, UART_IER, p->ier);
> -
> -               serial8250_rpm_put(p);

This has been introduced by 0c66940d584d1aac92f6a78460dc0ba2efd3b7ba
Don't you mind add corresponding Fixes tag?

Fixes: 0c66940d584d ("tty/serial/8250: fix RS485 half-duplex RX")

And I would like also

Cc: Yegor Yefremov <yegorslists@xxxxxxxxxxxxxx>

>         }
>  }
>
> @@ -1429,6 +1425,7 @@ static void serial8250_em485_handle_stop_tx(unsigned long arg)
>         struct uart_8250_em485 *em485 = p->em485;
>         unsigned long flags;
>
> +       serial8250_rpm_get(p);
>         spin_lock_irqsave(&p->port.lock, flags);
>         if (em485 &&
>             em485->active_timer == &em485->stop_tx_timer) {
> @@ -1436,6 +1433,7 @@ static void serial8250_em485_handle_stop_tx(unsigned long arg)
>                 em485->active_timer = NULL;
>         }
>         spin_unlock_irqrestore(&p->port.lock, flags);
> +       serial8250_rpm_put(p);
>  }
>
>  static void __stop_tx_rs485(struct uart_8250_port *p)
> @@ -1475,7 +1473,7 @@ static inline void __stop_tx(struct uart_8250_port *p)
>                 unsigned char lsr = serial_in(p, UART_LSR);
>                 /*
>                  * To provide required timeing and allow FIFO transfer,
> -                * __stop_tx_rs485 must be called only when both FIFO and
> +                * __stop_tx_rs485() must be called only when both FIFO and
>                  * shift register are empty. It is for device driver to enable
>                  * interrupt on TEMT.
>                  */
> @@ -1484,9 +1482,10 @@ static inline void __stop_tx(struct uart_8250_port *p)
>
>                 del_timer(&em485->start_tx_timer);
>                 em485->active_timer = NULL;
> +
> +               __stop_tx_rs485(p);
>         }
>         __do_stop_tx(p);
> -       __stop_tx_rs485(p);
>  }
>
>  static void serial8250_stop_tx(struct uart_port *port)
> --
> 2.8.1
>



-- 
With best regards,
Matwey V. Kornilov.
Sternberg Astronomical Institute, Lomonosov Moscow State University, Russia
119991, Moscow, Universitetsky pr-k 13, +7 (495) 9392382
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux