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@xxxxxxxxx> --- common/clock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/clock.c b/common/clock.c index 7f5cff232..2b218fb6a 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); -- 2.17.1 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox