diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2018-06-27 21:54:28 -0700 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-07-02 06:36:53 +0200 |
commit | e9d5e7a983b43e1bd4789098d4279c25f8ff7078 (patch) | |
tree | 4180008c610725a7be162bcf41764508259ba9b3 /common/clock.c | |
parent | 0ca998a69bb3f889141aad1872ff0fb53979605a (diff) | |
download | barebox-e9d5e7a983b43e1bd4789098d4279c25f8ff7078.tar.gz barebox-e9d5e7a983b43e1bd4789098d4279c25f8ff7078.tar.xz |
common: clock: Sample time before poller_call()
Change is_timeout() to sample current time before invoking poller
infrascructure to avoid occasional false timeout conditions.
Consider the following timeout loop (can be found in wait_on_timeout):
while (!(condition)) {
if (is_timeout(...)) {
return -ETIMEDOUT;
}
}
...
in the original logic of is_timeout() it was possible to end up in the
following situation:
1. Immediate check of of "condition" yeilds false (not enough
time for it to become true has passed yet)
2. is_timeout is called which, in turn, calls poller_call()
3. All registerd pollers take more than specified timeout time
to execute.
4. Sometime during poller_call() "contition" becomes true
5. As a result of #3 is_timeout() returns "true"
6. Code bails out with -ETIMEDOUT early even though timeout
condition didn't really occur.
One concrete example of this problem was discovered on ZII RDU1
board (poller_call() is long due to a serdev) when doing large data
transfers over SPI to attached DataFlash chip.
This commit changes is_timeout() to sample the value of time before
calling poller_call(). This way first call to is_timeout() will almost
always return false thus checking the condition at least twice before
declaring a timeout.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/clock.c')
-rw-r--r-- | common/clock.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/common/clock.c b/common/clock.c index f98176dd52..904bee0b46 100644 --- a/common/clock.c +++ b/common/clock.c @@ -181,10 +181,12 @@ EXPORT_SYMBOL(is_timeout_non_interruptible); int is_timeout(uint64_t start_ns, uint64_t time_offset_ns) { + int ret = is_timeout_non_interruptible(start_ns, time_offset_ns); + if (time_offset_ns >= 100 * USECOND) poller_call(); - return is_timeout_non_interruptible(start_ns, time_offset_ns); + return ret; } EXPORT_SYMBOL(is_timeout); |