-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys/ztimer: fix re-scheduling of timers #20924
Conversation
If the timer at the head of a ztimer clock's timer list is re-scheduled (ztimer_set() called on an already set timer) and the timer is no longer at the head after being re-scheduled, clock-ops->set() is never called from inside ztimer_set(), and the underlying timer is left with an ISR scheduled to expire at the timer's old time. The intended behavior is that the clock's lower level timer should always be set to expire at the time of the clocks head timer. This patch changes ztimer_set() to call _ztimer_update(), which sets the lower level timer according to the current list of timers, rather than setting the timer directly inside of ztimer_set().
That fix looks pretty straightforward! Please also add a test case that reproduced the bug. |
Backport provided in #20928 |
This reverts commit e3d0068. With RIOT-OS#20924 merged, this should no longer be needed.
Mostly yes. However, the timeout in there can also trigger early even when ztimer does not trigger early: The GNRC SOCK implementation uses an mbox to wait for a network message to be received. However, mbox has no timeout. Instead, ztimer will put a message to the mbox when it is triggered. If the mbox message related to a received network message is put into the mbox just before the timeout message, the next one to fetch something from the mbox will get the stale timeout message from the mbox directly. |
This reverts commit e3d0068, which added a work around for two bugs: - ztimer triggering too early (fixed in RIOT-OS#20924) - gnrc_sock_recv() returning when an old "timeout" message is still in the message queue (fixed in RIOT-OS#21113) With those bugs fixed, the work around should not longer be needed.
Contribution description
If the timer at the head of a ztimer clock's timer list is re-scheduled (
ztimer_set()
called on an already set timer) and the timer is no longer at the head after being re-scheduled,clock-ops->set()
is never called from insideztimer_set()
, and the underlying timer is left with an ISR scheduled to expire at the timer's old time. The intended behavior is that the clock's lower level timer should always be set to expire at the time of the clocks head timer.This patch changes
ztimer_set()
to call_ztimer_update()
, which sets the lower level timer according to the current list of timers, rather than setting the timer directly inside ofztimer_set()
.This is a fix we might consider back porting. As far as I can tell this bug has always existed in
ztimer
.Testing procedure
make -C examples/hello-world/ all term
Testbench patch
Sample of testbench's expected (good) behavior
Sample of testbench's behavior without this fix
Issues/PRs references
This bug is possible the cause of the early timeout worked around in this #19965. Perhaps that workaround could be removed?