mirror of
https://github.com/apache/nuttx.git
synced 2026-05-25 01:39:44 +08:00
semaphore: fix corner case sem_waitirq assert crash
[ 11.041077] [25] [ EMERG] [ap] up_assert: Assertion failed at file:semaphore/sem_waitirq.c line: 84 task: thermal service
[ 11.041407] [25] [ EMERG] [ap] backtrace:
[ 11.041517] [25] [ EMERG] [ap] [25] [<0x2c687c9e>] up_backtrace+0xa/0x164
[ 11.041627] [25] [ EMERG] [ap] [25] [<0x2c676e6c>] sched_dumpstack+0x1c/0x5c
[ 11.041682] [25] [ EMERG] [ap] [25] [<0x2c68763a>] up_assert+0x42/0x24c
[ 11.041792] [25] [ EMERG] [ap] [25] [<0x2c67355e>] _assert+0x2/0xc
[ 11.041847] [25] [ EMERG] [ap] [25] [<0x2c65d536>] nxsem_wait_irq+0x3e/0x134
[ 11.042288] [25] [ EMERG] [ap] [25] [<0x2c65d378>] nxsem_timeout+0x24/0x34
[ 11.043169] [25] [ EMERG] [ap] [25] [<0x2c65f74c>] wd_timer+0xc0/0x104
[ 11.043995] [25] [ EMERG] [ap] [25] [<0x2c65c930>] nxsched_alarm_expiration+0x4c/0xdc
[ 11.044986] [25] [ EMERG] [ap] [25] [<0x2c670872>] oneshot_callback+0x16/0x24
[ 11.045867] [25] [ EMERG] [ap] [25] [<0x2c6822b8>] bes_oneshot_irq_handler+0x18/0x28
[ 11.046858] [25] [ EMERG] [ap] [25] [<0x57e5c>] up_irq_handler+0x4/0xc
[ 11.047684] [25] [ EMERG] [ap] [25] [<0x2c65a20e>] irq_dispatch+0x5a/0xb8
[ 11.048510] [25] [ EMERG] [ap] [25] [<0x2c6864d8>] arm_doirq+0x28/0x3c
[ 11.049336] [25] [ EMERG] [ap] [25] [<0x2c681732>] exception_common+0x4a/0xac
[ 11.050272] [25] [ EMERG] [ap] [25] [<0x2c65a324>] leave_critical_section+0x2c/0x54
[ 11.051208] [25] [ EMERG] [ap] [25] [<0x2c65f472>] timer_settime+0x9e/0x10c
There are 2 ways can caused this:
1. sem_timedwait
HW IRQ sem_post
TIMER IRQ do wd_timer -> nxsem_timeout -> crash
Note: The 2 IRQS happens amost at same time
2. sem_timedwait
TIMER IRQ do wd_timer -> wd_func1 sem_post
-> wd_func2 nxsem_timeout -> crash
Resolve:
Stop the watchdog when sem_post
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
@@ -147,6 +147,10 @@ int nxsem_post(FAR sem_t *sem)
|
||||
|
||||
nxsem_add_holder_tcb(stcb, sem);
|
||||
|
||||
/* Stop the watchdog timer */
|
||||
|
||||
wd_cancel(&stcb->waitdog);
|
||||
|
||||
/* It is, let the task take the semaphore */
|
||||
|
||||
stcb->waitsem = NULL;
|
||||
|
||||
Reference in New Issue
Block a user