mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
arch/x86_64: do not wrap the HPET oneshot on a deadline that has passed.
Some checks failed
Build Documentation / build-html (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
Docker-Linux / push (push) Has been cancelled
Some checks failed
Build Documentation / build-html (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
Docker-Linux / push (push) Has been cancelled
intel64_timer_start_absolute() computed "expected - current_us" unsigned. A watchdog started with a delay of zero asks for a deadline that is already current, the subtraction wraps to nearly 2^64, and the comparator is set so far ahead that the timer never fires. The CONFIG_INTEL64_HPET_MIN_DELAY clamp in intel64_oneshot_start() cannot help: the wrapped value is enormous, not small. Ask for the shortest delay the hardware can take instead of wrapping, and let that existing minimum-delay logic pick it. It presents as ostest hanging in wdog_test with no output and no fault. apps/testing/ostest/wdog.c:281 calls wdtest_once(&test_wdog, param, 0), and NSEC2TICK() takes the next few delays (1ns, 10ns, ...) to zero ticks as well; wdtest_once() then spins forever in its "wait until the callback is triggered exactly once" loop. Impact: runtime, ARCH_INTEL64_HPET_ALARM only. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
This commit is contained in:
parent
97dcbc010b
commit
7fd17c9d7c
1 changed files with 5 additions and 1 deletions
|
|
@ -149,10 +149,14 @@ static void intel64_timer_start_absolute(struct oneshot_lowerhalf_s *lower,
|
|||
(struct intel64_oneshot_lowerhalf_s *)lower;
|
||||
irqstate_t flags = spin_lock_irqsave(&g_oneshotlow_spin);
|
||||
int ret = intel64_oneshot_current(&priv->oneshot, ¤t_us);
|
||||
uint64_t delta_us = expected - current_us;
|
||||
uint64_t delta_us;
|
||||
|
||||
DEBUGASSERT(ret == OK);
|
||||
|
||||
/* Use the shortest delay when the deadline has passed. */
|
||||
|
||||
delta_us = expected > current_us ? expected - current_us : 0;
|
||||
|
||||
ts.tv_sec = delta_us / USEC_PER_SEC;
|
||||
ts.tv_nsec = delta_us % USEC_PER_SEC * 1000ull;
|
||||
ret = intel64_oneshot_start(&priv->oneshot, intel64_oneshot_handler,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue