Skip to content
Commit 4a72b590 authored by Chris Friedt's avatar Chris Friedt Committed by Benjamin Cabé
Browse files

sys: timeutil: ensure safety of timespec conversion routines



Originally, the timespec_to_timeout() and timespec_from_timeout() tests
assumed that tv_sec and tv_nsec values divided evenly with the number of
ticks per second (CONFIG_SYS_CLOCK_TICKS_PER_SEC). However, those
assumptions broke down when testing with 32768 ticks/s .

Upon further investigation, there were additional corner cases
discovered that were not handled in an ideal or safe way.

Part of this fix involved identifying several "domains" and special
values that have semantic meaning that must be handled particularly
carefully.

Additional hidden-API constants were made to simplify the solution.

K_TICK_MIN (1)
K_TICK_MAX (UINT32_MAX-1 in 32-bit, INT64_MAX in 64-bit)

K_TIMESPEC_NO_WAIT (like K_NO_WAIT)
K_TIMESPEC_FOREVER (like K_FOREVER)

1. Converting a negative k_timeout_t

These only exist in 64-bit representation and actually encode absolute
timepoints via ticks. Since the stated purpose of the conversion
functions is to convert between durations, we must reject absolute
time points in timespec_from_timeout().

2. Converting a negative timespec

We assume that this duration means a timeout has already expired, and
round these up to K_NO_WAIT in timespec_to_timeout().

3. Due to the larger numeric space in the timespec representation,
the reverse mapping of timespec to k_timeout_t is "fuzzy". However,
K_NO_WAIT (K_TIMESPEC_NO_WAIT) and K_FOREVER (K_TIMESPEC_FOREVER) must
remain semantically equivalent. The previous implementation also held this
to be true, but the test cases are a bit clearer about it now.

4. Also, due to the larger numeric space in timespec representation,
there was a special requirement to round up to the nearest tick
boundary for any timespec in the strictly exclusive range
(K_TIMESPEC_NO_WAIT, K_TIMESPEC_MAX). We must round up, since
a) rounding down to K_NO_WAIT is most certainly not representative
   of a non-zero finite duration delay
b) the kernel operates on tick boundaries

5. Above the K_TIMESPEC_MAX boundary, which is the highest possible
timespec that can be represented by a tick, and specifically in the
64-bit timeout representation, there is a domain that cannot be
rounded up to K_TIMESPEC_FOREVER and should always be rounded down to
K_TIMESPEC_MAX.

This is to ensure that finite durations remain finite (even if
they are beyond the heat death of the universe).

Signed-off-by: default avatarChris Friedt <cfriedt@tenstorrent.com>
parent f68af2d4
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment