Browse Source

kernel/timeout: Correctly clamp z_clock_set_timeout() argument

This function would correctly suppress attempts to set timeouts that
were too soon for the driver or farther out than what was already set,
but when it actually set the timeout it would use the requested value
and not clamp it to the minimum of it and the current timeout
expiration, leading to "too-long" timeouts being set at the driver.

In uniprocessor configurations, that turns out to have been benign
because something else would always come back along when timeout state
changed and fix the broken value before the expiration.

But in SMP, this opens up races.  For example, the idle thread on one
CPU can see that there are no active threads and schedule a maximum
value timeout at the same time as the other thread adds a new timeout
that expects a near-term expiration.  The broken code here would see
that the new timeout exists, decide that yes it needs to override, but
then set the K_TICKS_FOREVER value it got from the idle thread!

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
pull/32634/head
Andy Ross 4 years ago committed by Anas Nashif
parent
commit
bf99f3105f
  1. 2
      kernel/timeout.c

2
kernel/timeout.c

@ -224,7 +224,7 @@ void z_set_timeout_expiry(int32_t ticks, bool is_idle)
* in. * in.
*/ */
if (!imminent && (sooner || IS_ENABLED(CONFIG_SMP))) { if (!imminent && (sooner || IS_ENABLED(CONFIG_SMP))) {
z_clock_set_timeout(ticks, is_idle); z_clock_set_timeout(MIN(ticks, next_to), is_idle);
} }
} }
} }

Loading…
Cancel
Save