Skip to content

Commit 79d076b

Browse files
SgrrZhfcarlescufi
authored andcommitted
drivers: timer: arm_arch_timer: Fix round up issue
Fast hardware with slow timer hardware can trigger and enter an interrupt and reach 'sys_clock_set_timeout' before the counter has advanced. That defeats the "round up" logic such that we end up scheduling timeouts a tick too soon (e.g. if the kernel requests an interrupt at the "X" tick, we would end up computing a comparator value representing the "X-1" tick!). Choose the bigger one between 1 and "curr_cycle - last_cycle" to correct. Signed-off-by: Huifeng Zhang <[email protected]>
1 parent 522e0b5 commit 79d076b

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

drivers/timer/arm_arch_timer.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,17 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
100100
uint64_t curr_cycle = arm_arch_timer_count();
101101
uint64_t req_cycle = ticks * CYC_PER_TICK;
102102

103-
/* Round up to next tick boundary */
104-
req_cycle += (curr_cycle - last_cycle) + (CYC_PER_TICK - 1);
103+
/*
104+
* Round up to next tick boundary, but an edge case should be handled.
105+
* Fast hardware with slow timer hardware can trigger and enter an
106+
* interrupt and reach this spot before the counter has advanced.
107+
* That defeats the "round up" logic such that we end up scheduling
108+
* timeouts a tick too soon (e.g. if the kernel requests an interrupt
109+
* at the "X" tick, we would end up computing a comparator value
110+
* representing the "X-1" tick!). Choose the bigger one between 1 and
111+
* "curr_cycle - last_cycle" to correct.
112+
*/
113+
req_cycle += MAX(curr_cycle - last_cycle, 1) + (CYC_PER_TICK - 1);
105114

106115
req_cycle = (req_cycle / CYC_PER_TICK) * CYC_PER_TICK;
107116

0 commit comments

Comments
 (0)