[PATCH v3 02/10] common: clock: Sample time before poller_call()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux