-
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
xtimer: Fix race condition in _xtimer_set_absolute #6937
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice find, the debug message needs an update as well
Unfortunately xtimer_now() is not safe to use within iISRs or with IRQs disabled, when not running on 32bit timers, so this solution will cause problems. |
Ah, never mind. We need to review this further |
@samkumar Could you elaborate on the race condition? I don't get it with my tired eyes. ;) |
@kaspar030 This race condition is as follows. If an interrupt occurs after checking "(target >= now) && ((target - XTIMER_BACKOFF) < now)" but before the call to _lltimer_set, the timer could be set when "target" represents a time in the past. |
d163e8a
to
f823c8d
Compare
@kaspar030 Thanks for mentioning that xtimer_now should not be called with interrupts disabled. I have updated the commit accordingly. |
Maybe I'm mistaken about this, but shouldn't the check
come before checking if we should spin-wait? |
f823c8d
to
7c36ba8
Compare
I suppose there is a more fundamental issue... this same race condition shows up in _xtimer_set. An interrupt may occur in between "target" being computed, and "_xtimer_set_absolute" being called, which could cause the timer to be set in the past. I've fixed this issue as well (see updated commit) but now we are again calling xtimer_now in with interrupts disabled. One solution would be for _xtimer_set_absolute to check:
This would let us avoid calling xtimer_now with interrupts disabled, but it seems kind of hacky to me... |
Also fixed by: #7053 |
@kaspar030 can you elaborate a bit more on why xtimer_now cannot be called with IRQs disabled? |
On <32bit |
discussion inconclusive, remove milestone |
@kaspar030, @gebart. Especially because RIOT provides preemptive multithreading, any time-critical operation must be protected from an interrupt. Timer operation initiated from a low-priority thread can be preempted by a high-priority thread, which causes significant misbehavior ("target_time" becomes less than "now", which means that the timer expires one whole cycle later). Even a short interrupt handler execution can cause a problem theoretically. Here is an issue. To this end, xtimer_now should be executed after IRQs disabled, since it is the basis of all timer operation. If 16-bit platforms do not support timer access with IRQs disabled, I'm not sure if these platforms fit with preemptive multithreading concurrency model, strictly saying. I think it is too much loss that RIOT becomes a "toy" OS without robustness due to lack of this very simple fix. Further discussion is welcome! At least, it would be good to have #ifdef for 32-bit platforms. Is there any option for that? |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
This pull request fixes a race condition in the xtimer module.