Skip to content

Commit bc25382

Browse files
committed
kernel: fix handling of very large timeouts
When a very large timeout, like INT64_MAX passed by task_wdt_init(), is passed to z_add_timeout(), it could become a very small negative number when added to the timeout list. This would prevent any new timeout from being added correctly. Signed-off-by: Mike J. Chen <[email protected]>
1 parent 53c79c6 commit bc25382

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

kernel/timeout.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,21 @@ k_ticks_t z_add_timeout(struct _timeout *to, _timeout_func_t fn, k_timeout_t tim
132132
}
133133

134134
for (t = first(); t != NULL; t = next(t)) {
135-
if (t->dticks > to->dticks) {
135+
/* if timeout.ticks was a large positive number,
136+
* like INT64_MAX, the adding of 1 and elapsed()
137+
* above will likely flip it to a very small negative
138+
* number. since our insertion comparison
139+
* is to insert new timeouts in ascending order,
140+
* that negative dticks on the list will never
141+
* get replaced and new timeouts never get scheduled.
142+
* we could limit the dticks to always be positive,
143+
* or we could do unsigned comparisons here, which
144+
* would give us more range.
145+
*/
146+
if ((IS_ENABLED(CONFIG_TIMEOUT_64BIT) &&
147+
((uint64_t)t->dticks > (uint64_t)to->dticks)) ||
148+
(!IS_ENABLED(CONFIG_TIMEOUT_64BIT) &&
149+
((uint32_t)t->dticks > (uint32_t)to->dticks))) {
136150
t->dticks -= to->dticks;
137151
sys_dlist_insert(&t->node, &to->node);
138152
break;

0 commit comments

Comments
 (0)