-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Description / Steps to reproduce the issue
I fully-agree @anchao said in #17517 (comment)
There are various implementation approaches for hrtimer, but the benefit it delivers to business users is a high-precision timer. We need to examine this issue from the perspective of applications and business stakeholders—otherwise, any implementation would merely be an exercise in self-indulgence for developers.
HRtimer is intended to provide users with high-precision timer APIs. However, this HRtimer implemantation is completely unusable for users. In the words of @anchao, it is purely a self-indulgent exercise for developers.
The HRTimer I used is from #17517.
My configuration is rv-virt:smp, with CONFIG_HRTIMER and CONFIG_SCHED_TICKLESS enabled.
The test case used is as follows. This test case simulates a very typical driver application scenario: a shared device driver uses a common timeout timer, which may be accessed by multiple threads and therefore should be protected by a spinlock or a big kernel lock.
I attempted three approaches, and either the timer would crash inside the critical section, or it would sleep inside the critical section.
The first approach: hrtimer_cancel → hrtimer_start. This failed because if the callback function is executing, the timer cannot be started, and the system crashes.
The second approach: hrtimer_cancel → loop hrtimer_start. This was expected to succeed, but the system still crashed. Even if it succeeded, there would be a spinning issue within the critical section.
The third approach: hrtimer_cancel_sync → hrtimer_start. This succeeded, but it calls sleep within the critical section, which is unacceptable.
This problem stems from a fundamental flaw in the hrtimer state machine design. Minor modifications cannot fix it. Therefore, I strongly suggest this implementation should be removed and replaced with a better and completely different implementation (#17556).
The test code and error report is showed as below.
/****************************************************************************
* apps/examples/hello/hello_main.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <nuttx/hrtimer.h>
#define HRTIMER_TEST_THREAD_NR (CONFIG_SMP_NCPUS * 8)
/****************************************************************************
* Public Functions
****************************************************************************/
static uint32_t test_callback(FAR struct hrtimer_s *hrtimer)
{
printf(".");
return 0;
}
static void* test_thread(void *arg)
{
irqstate_t flags;
hrtimer_t timer;
spinlock_t lock = SP_UNLOCKED;
hrtimer_init(&timer, test_callback, NULL);
while (1)
{
uint64_t delay = rand() % NSEC_PER_MSEC;
int ret;
/* Simulate the usage of driver->wait_dog. */
flags = spin_lock_irqsave(&lock);
/* The driver lock acquired */
/* First try, failed. Because hrtimer_start can not ensure the timer being started. */
ret = hrtimer_cancel(&timer);
// ret = hrtimer_start(&timer, 10 * NSEC_PER_USEC, HRTIMER_MODE_REL); /* May fail */
/* This try-loop start should be OK. But it failed again.
* Besides, we can not sleep or spin in the critical sections.
*/
while (hrtimer_start(&timer, 10 % NSEC_PER_USEC, HRTIMER_MODE_REL) != OK);
ret = OK;
/* Second try, Success, but we can not sleep or spin in the critical section. */
// ret = hrtimer_cancel_sync(&timer); /* Sleep in critical sections */
// ret = hrtimer_start(&timer, delay, HRTIMER_MODE_REL);
spin_unlock_irqrestore(&lock, flags);
if (ret != OK)
{
printf("hrtimer_start failed\n");
}
up_ndelay(delay);
}
return NULL;
}
/****************************************************************************
* hello_main
****************************************************************************/
int main(int argc, FAR char *argv[])
{
unsigned int thread_id;
pthread_attr_t attr;
pthread_t pthreads[HRTIMER_TEST_THREAD_NR];
printf("hrtimer_test start...\n");
ASSERT(pthread_attr_init(&attr) == 0);
/* Create wdog test thread */
for (thread_id = 0; thread_id < HRTIMER_TEST_THREAD_NR; thread_id++)
{
ASSERT(pthread_create(&pthreads[thread_id], &attr,
test_thread, NULL) == 0);
}
for (thread_id = 0; thread_id < HRTIMER_TEST_THREAD_NR; thread_id++)
{
pthread_join(pthreads[thread_id], NULL);
}
ASSERT(pthread_attr_destroy(&attr) == 0);
printf("hrtimer_test end...\n");
return 0;
}➜ qemu-system-riscv32 -semihosting -M virt,aclint=on -cpu rv32 -smp 8 -bios none -nographic -kernel nuttx -s
NuttShell (NSH) NuttX-12.10.0
nsh> hello
hrtimer_test start...
................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................[CPU0] EXCEPTION: Load access fault. MCAUSE: 00000005, EPC: 80005960, MTVAL: 00000000
[CPU0] PANIC!!! Exception = 00000005
[CPU0] Current Version: NuttX 12.10.0 3663e78f82e-dirty Dec 19 2025 10:56:02 risc-v
[CPU0] Assertion failed panic: at file: :0 task(CPU0): hello process: hello 0x80016b7c
[CPU0] EPC: 80005960
[CPU0] A0: 8002be34 A1: 80032c78 A2: 00000000 A3: 80032c78
[CPU0] A4: 00000001 A5: 00000000 A6: ee6b2800 A7: 00000002
[CPU0] T0: 80029530 T1: 80028d30 T2: 00000000 T3: 00000000
[CPU0] T4: 00000000 T5: 00000000 T6: 00000000
[CPU0] S0: 80032c78 S1: 80032c78 S2: 80033e38 S3: 8002be34
[CPU0] S4: 00000000 S5: 00000001 S6: 00000002 S7: 00000008
[CPU0] S8: 00000003 S9: acd2225e S10: 00000000 S11: 00000000
[CPU0] SP: 80029488 FP: 80032c78 TP: 00000000 RA: 80005a62
[CPU0] IRQ Stack:
[CPU0] base: 0x80028d30
[CPU0] size: 00002048
[CPU0] sp: 0x80029488
[CPU0] 0x80029468: 8002c000 0000002e 8003114c 2e007d90 8002c000 0000002e 80031148 8001b4ce
[CPU0] 0x80029488: 00000000 80007880 acd2696c 8002c000 8002c000 80007880 80033e38 800048cc
[CPU0] 0x800294a8: 800253fc 00000100 00000000 00000017 8002bd54 00000000 00000000 00000000
[CPU0] 0x800294c8: 80025448 3597c6e4 00000000 00000017 8002bd54 00000000 80029bd0 80009e30
[CPU0] 0x800294e8: 8002bd54 00000000 80029bd0 80000f64 00000000 00000000 80029bd0 80036084
[CPU0] 0x80029508: 8000000b 0000000a 00000002 80036210 80000007 80009de4 80029530 80000196
[CPU0] 0x80029528: 80036084 80006574 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] ERROR: Stack pointer 80029488 is not within the stack
[CPU0] User Stack:
[CPU0] base: 0x80035ac0
[CPU0] size: 00002032
[CPU0] 0x80036084: 80009de4 80006574 80036210 deadbeef 00000000 00000000 000b3650 00000000
[CPU0] 0x800360a4: 00000000 fffe712c 01ba5bb3 00000000 00000017 00000000 0200bffc 0200bff8
[CPU0] 0x800360c4: ee6b2800 00000002 8002be3c 00000002 00000002 3597c6e4 80025448 00000000
[CPU0] 0x800360e4: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x80036104: 80007880 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x80036124: 00000000 00000000 00000000 00000000 80007880 00000000 00000000 00000000
[CPU0] 0x80036144: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x80036164: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x80036184: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x800361a4: 00003880 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x800361c4: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x800361e4: 00000000 00000000 00000000 00000000 00000000 00000000 8002c000 80006080
[CPU0] 0x80036204: acc0949e 80036248 80004a30 00000000 00000000 00000002 358b009e 00000000
[CPU0] 0x80036224: 00000000 00000008 80006088 00000001 000f4240 000b3650 80016bee 00000000
[CPU0] 0x80036244: 00000000 00000000 00000000 80032398 00000000 00000000 80016bf6 00000000
[CPU0] 0x80036264: 00000000 acc0949e 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] 0x80036284: 00000000 800359d8 8001ab54 00000000 00000000 00000000 8001bec8 00000000
[CPU0] 0x800362a4: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[CPU0] Dump CPU1: RUNNING
[CPU0] Dump CPU2: RUNNING
[CPU0] Dump CPU3: RUNNING
[CPU0] Dump CPU4: RUNNING
[CPU0] Dump CPU5: RUNNING
[CPU0] Dump CPU6: RUNNING
[CPU0] Dump CPU7: RUNNING
[CPU0] PID GROUP CPU PRI POLICY TYPE NPX STATE EVENT SIGMASK STACKBASE STACKSIZE USED FILLED COMMAND
[CPU0] ---- --- 0 --- -------- ------- --- ------- ---------- ---------------- 0x80028d30 2048 120 5.8% irq
[CPU0] ---- --- 1 --- -------- ------- --- ------- ---------- ---------------- 0x80028530 2048 120 5.8% irq
[CPU0] ---- --- 2 --- -------- ------- --- ------- ---------- ---------------- 0x80027d30 2048 120 5.8% irq
[CPU0] ---- --- 3 --- -------- ------- --- ------- ---------- ---------------- 0x80027530 2048 120 5.8% irq
[CPU0] ---- --- 4 --- -------- ------- --- ------- ---------- ---------------- 0x80026d30 2048 120 5.8% irq
[CPU0] ---- --- 5 --- -------- ------- --- ------- ---------- ---------------- 0x80026530 2048 120 5.8% irq
[CPU0] ---- --- 6 --- -------- ------- --- ------- ---------- ---------------- 0x80025d30 2048 120 5.8% irq
[CPU0] ---- --- 7 --- -------- ------- --- ------- ---------- ---------------- 0x80025530 2048 120 5.8% irq
[CPU0] 0 0 0 0 FIFO Kthread - Assigned 0000000000000000 0x8002bef0 2032 492 24.2% CPU0 IDLE
[CPU0] 1 0 1 0 FIFO Kthread - Assigned 0000000000000000 0x8002c6f0 2032 828 40.7% CPU1 IDLE
[CPU0] 2 0 2 0 FIFO Kthread - Assigned 0000000000000000 0x8002cef0 2032 828 40.7% CPU2 IDLE
[CPU0] 3 0 3 0 FIFO Kthread - Assigned 0000000000000000 0x8002d6f0 2032 828 40.7% CPU3 IDLE
[CPU0] 4 0 4 0 FIFO Kthread - Assigned 0000000000000000 0x8002def0 2032 828 40.7% CPU4 IDLE
[CPU0] 5 0 5 0 FIFO Kthread - Assigned 0000000000000000 0x8002e6f0 2032 828 40.7% CPU5 IDLE
[CPU0] 6 0 6 0 FIFO Kthread - Assigned 0000000000000000 0x8002eef0 2032 860 42.3% CPU6 IDLE
[CPU0] 7 0 7 0 FIFO Kthread - Assigned 0000000000000000 0x8002f6f0 2032 828 40.7% CPU7 IDLE
[CPU0] 8 8 0 100 RR Task - Waiting Semaphore 0000000000000000 0x800305d0 2000 1004 50.2% nsh_main
[CPU0] 9 9 0 100 RR Task - Waiting Semaphore 0000000000000000 0x80031348 2008 924 46.0% hello
[CPU0] 10 9 1 100 RR pthread - Running 0000000000000000 0x80031c18 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 11 9 2 100 RR pthread - Running 0000000000000000 0x800324f8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 12 9 3 100 RR pthread - Running 0000000000000000 0x80032dd8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 13 9 4 100 RR pthread - Running 0000000000000000 0x800336b8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 14 9 5 100 RR pthread - Running 0000000000000000 0x80033f98 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 15 9 6 100 RR pthread - Running 0000000000000000 0x80034878 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 16 9 7 100 RR pthread - Running 0000000000000000 0x80035158 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 17 9 0 100 RR pthread - Running 0000000000000000 0x80035ac0 2032 556 27.3% hello 0x80016b7c 0
[CPU0] 18 9 0 100 RR pthread - Ready 0000000000000000 0x800363a0 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 19 9 0 100 RR pthread - Ready 0000000000000000 0x80036c80 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 20 9 0 100 RR pthread - Ready 0000000000000000 0x80037560 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 21 9 0 100 RR pthread - Ready 0000000000000000 0x80037e40 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 22 9 0 100 RR pthread - Ready 0000000000000000 0x80038720 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 23 9 0 100 RR pthread - Ready 0000000000000000 0x80039000 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 24 9 0 100 RR pthread - Ready 0000000000000000 0x800398e0 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 25 9 0 100 RR pthread - Ready 0000000000000000 0x8003a1c0 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 26 9 0 100 RR pthread - Ready 0000000000000000 0x8003aaa0 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 27 9 0 100 RR pthread - Ready 0000000000000000 0x8003b380 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 28 9 0 100 RR pthread - Ready 0000000000000000 0x8003bc60 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 29 9 0 100 RR pthread - Ready 0000000000000000 0x8003c540 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 30 9 0 100 RR pthread - Ready 0000000000000000 0x8003ce20 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 31 9 0 100 RR pthread - Ready 0000000000000000 0x8003d700 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 32 9 0 100 RR pthread - Ready 0000000000000000 0x8003dfe0 2032 396 19.4% hello 0x80016b7c 0
[CPU0] 33 9 0 100 RR pthread - Ready 0000000000000000 0x8003e9c8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 34 9 0 100 RR pthread - Ready 0000000000000000 0x8003f2a8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 35 9 0 100 RR pthread - Ready 0000000000000000 0x8003fb88 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 36 9 0 100 RR pthread - Ready 0000000000000000 0x80040468 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 37 9 0 100 RR pthread - Ready 0000000000000000 0x80040d48 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 38 9 0 100 RR pthread - Ready 0000000000000000 0x80041628 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 39 9 0 100 RR pthread - Ready 0000000000000000 0x80041f08 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 40 9 0 100 RR pthread - Ready 0000000000000000 0x800427e8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 41 9 0 100 RR pthread - Ready 0000000000000000 0x800430c8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 42 9 0 100 RR pthread - Ready 0000000000000000 0x800439a8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 43 9 0 100 RR pthread - Ready 0000000000000000 0x80044288 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 44 9 0 100 RR pthread - Ready 0000000000000000 0x80044b68 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 45 9 0 100 RR pthread - Ready 0000000000000000 0x80045448 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 46 9 0 100 RR pthread - Ready 0000000000000000 0x80045d28 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 47 9 0 100 RR pthread - Ready 0000000000000000 0x80046608 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 48 9 0 100 RR pthread - Ready 0000000000000000 0x80046ee8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 49 9 0 100 RR pthread - Ready 0000000000000000 0x800477c8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 50 9 0 100 RR pthread - Ready 0000000000000000 0x800480a8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 51 9 0 100 RR pthread - Ready 0000000000000000 0x80048988 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 52 9 0 100 RR pthread - Ready 0000000000000000 0x80049268 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 53 9 0 100 RR pthread - Ready 0000000000000000 0x80049b48 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 54 9 0 100 RR pthread - Ready 0000000000000000 0x8004a428 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 55 9 0 100 RR pthread - Ready 0000000000000000 0x8004ad08 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 56 9 0 100 RR pthread - Ready 0000000000000000 0x8004b5e8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 57 9 0 100 RR pthread - Ready 0000000000000000 0x8004bec8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 58 9 0 100 RR pthread - Ready 0000000000000000 0x8004c7a8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 59 9 0 100 RR pthread - Ready 0000000000000000 0x8004d088 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 60 9 0 100 RR pthread - Ready 0000000000000000 0x8004d968 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 61 9 0 100 RR pthread - Ready 0000000000000000 0x8004e248 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 62 9 0 100 RR pthread - Ready 0000000000000000 0x8004eb28 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 63 9 0 100 RR pthread - Ready 0000000000000000 0x8004f408 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 64 9 0 100 RR pthread - Ready 0000000000000000 0x8004fce8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 65 9 0 100 RR pthread - Ready 0000000000000000 0x800506f8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 66 9 0 100 RR pthread - Ready 0000000000000000 0x80050fd8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 67 9 0 100 RR pthread - Ready 0000000000000000 0x800518b8 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 68 9 0 100 RR pthread - Ready 0000000000000000 0x80052198 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 69 9 0 100 RR pthread - Ready 0000000000000000 0x80052a78 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 70 9 0 100 RR pthread - Ready 0000000000000000 0x80053358 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 71 9 0 100 RR pthread - Ready 0000000000000000 0x80053c38 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 72 9 0 100 RR pthread - Ready 0000000000000000 0x80054518 2024 396 19.5% hello 0x80016b7c 0
[CPU0] 73 9 0 100 RR pthread - Ready 0000000000000000 0x80054df8 2024 396 19.5% hello 0x80016b7c 0Additionally, I have to made some code changes to get it to compile. I suspect @wangchdo may not have tested or compiled his code.
diff --git a/sched/Makefile b/sched/Makefile
index 92989e81253..2d743dfd3bb 100644
--- a/sched/Makefile
+++ b/sched/Makefile
@@ -43,6 +43,7 @@ include timer/Make.defs
include tls/Make.defs
include wdog/Make.defs
include wqueue/Make.defs
+include hrtimer/Make.defs
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)sched
diff --git a/sched/hrtimer/hrtimer_cancel.c b/sched/hrtimer/hrtimer_cancel.c
index bf974d240aa..a33bd241d4c 100644
--- a/sched/hrtimer/hrtimer_cancel.c
+++ b/sched/hrtimer/hrtimer_cancel.c
@@ -28,6 +28,8 @@
#include <nuttx/arch.h>
#include <nuttx/clock.h>
+#include "sched/sched.h"
+
#include <errno.h>
#include "hrtimer/hrtimer.h"
diff --git a/sched/sched/sched_processhrtimer.c b/sched/sched/sched_processhrtimer.c
index 2f04a8da9f9..713498af950 100644
--- a/sched/sched/sched_processhrtimer.c
+++ b/sched/sched/sched_processhrtimer.c
@@ -96,7 +96,7 @@ static uint32_t nxsched_hrtimer_callback(FAR hrtimer_t *hrtimer)
int nxsched_hrtimer_start(clock_t ticks)
{
return hrtimer_start(&g_nxsched_hrtimer,
- hrtimer->expired + ticks * NSEC_PER_TICK,
+ (&g_nxsched_hrtimer)->expired + ticks * NSEC_PER_TICK,
HRTIMER_MODE_ABS);
}
#endif
On which OS does this issue occur?
[OS: Linux]
What is the version of your OS?
Ubuntu 22.04
NuttX Version
Issue Architecture
[Arch: risc-v]
Issue Area
[Area: OS Components]
Host information
No response
Verification
- I have verified before submitting the report.