SMP: fix repeat entry oneshot_tick_start

Situation:

Assume we have 2 cpus.

CPU0                                CPU1
1. -> nxsched_alarm_expiration
2. -> nxshced_timer_start
3. -> ONESHOT_TICK_START
4. now timer in IRQ
                                    5. in thread
                                    6. -> wd_start
                                    7. -> nxshced_timer_start
                                    8. -> ONESHOT_TICK_START
                                    9. reentry timer crash

Fix:
Enter critical section before nxsched_timer_start

Signed-off-by: yangguangcai <yangguangcai@xiaomi.com>
This commit is contained in:
yangguangcai 2023-03-23 23:08:22 +08:00 committed by Xiang Xiao
parent d5041420a3
commit f324d1d8dd
1 changed files with 15 additions and 0 deletions

View File

@ -533,6 +533,18 @@ void nxsched_alarm_tick_expiration(clock_t ticks)
{
unsigned int elapsed;
unsigned int nexttime;
#ifdef CONFIG_SMP
irqstate_t flags;
/* If we are running on a single CPU architecture, then we know interrupts
* are disabled and there is no need to explicitly call
* enter_critical_section(). However, in the SMP case,
* enter_critical_section() is required prevent multiple cpu to enter
* oneshot_tick_start.
*/
flags = enter_critical_section();
#endif
/* Calculate elapsed */
@ -552,6 +564,9 @@ void nxsched_alarm_tick_expiration(clock_t ticks)
nexttime = nxsched_timer_process(elapsed, false);
nxsched_timer_start(nexttime);
#ifdef CONFIG_SMP
leave_critical_section(flags);
#endif
}
void nxsched_alarm_expiration(FAR const struct timespec *ts)