On Monday 02 November 2015 23:04:51 DengChao wrote:
> The bfin-uart code uses real time with struct timeval. This will
> cause problems on 32-bit architectures in 2038 when time_t
> overflows.
> Since the code just needs delta value of time, it is not
> necessary to record them in real time.
> This patch changes the code to use the monotonic time instead,
> replaces do_gettimeofday() and struct timeval with ktime_get()
> and ktime_t.
> 
> Signed-off-by: DengChao <[email protected]>
> ---
>  drivers/tty/serial/bfin_uart.c | 30 ++++++++++++++----------------
>  1 file changed, 14 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
> index ae3cf94..abfb988 100644
> --- a/drivers/tty/serial/bfin_uart.c
> +++ b/drivers/tty/serial/bfin_uart.c
> @@ -213,7 +213,7 @@ static void bfin_serial_stop_rx(struct uart_port *port)
>  static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
>  {
>       unsigned int status, ch, flg;
> -     static struct timeval anomaly_start = { .tv_sec = 0 };
> +     static time64_t anomaly_start;
>  
>       status = UART_GET_LSR(uart);

You store a nanosecond value in anomaly_start, so the time64_t type doesn't
really apply, as it is meant to store seconds. Better use 'u64' instead.

>       UART_CLEAR_LSR(uart);
> @@ -246,42 +246,40 @@ static void bfin_serial_rx_chars(struct 
> bfin_serial_port *uart)
>                * character time +/- some percent.  So 1.5 sounds good.  All 
> other
>                * Blackfin families operate properly.  Woo.
>                */
> -             if (anomaly_start.tv_sec) {
> -                     struct timeval curr;
> -                     suseconds_t usecs;
> +             if (anomaly_start >= NSEC_PER_SEC) {
> +                     ktime_t curr;
> +                     time64_t nsecs, threshold_ns;

Same here.

The '>= NSEC_PER_SEC' check will technically do the right thing, but it
is a bit misleading, as you are storing an absolute time value in
anomaly_start, so it will never be smaller than NSEC_PER_SEC unless
it is exactly zero.

>                       if ((~ch & (~ch + 1)) & 0xff)
>                               goto known_good_char;
>  
> -                     do_gettimeofday(&curr);
> -                     if (curr.tv_sec - anomaly_start.tv_sec > 1)
> +                     curr = ktime_get();
> +                     nsecs = ktime_to_ns(ktime_sub_ns(curr, anomaly_start));

This could be simpler if you use ktime_get_ns().

> +                     if (nsecs > NSEC_PER_SEC)
>                               goto known_good_char;

Note that this code is an optimization to avoid doing the full comparison
with anomaly_threshold, but by converting to a u64, there is very little
to gain. Maybe just drop this part and only do the real compare.
Alternatively, convert this into a check of the upper 32 bits, followed
by a 32-bit comparison with the threshold.

>       if (status & BI) {
>               if (ANOMALY_05000363)
>                       if (bfin_revid() < 5)
> -                             do_gettimeofday(&anomaly_start);
> +                             anomaly_start = ktime_to_ns(ktime_get());
>               uart->port.icount.brk++;
>               if (uart_handle_break(&uart->port))
>                       goto ignore_char;

ktime_get_ns() again.

        Arnd
_______________________________________________
Y2038 mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/y2038

Reply via email to