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