Skip to content

Commit

Permalink
os: fix amp hang issue
Browse files Browse the repository at this point in the history
To pause the cpu, cpu should call `up_cpu_paused`. The call to `up_cpu_paused` will get missed when `g_cpu_irqlock` is unlocked (means none of the cpu having access to irqlock), `arm_pause_handler` rely on `enter_critical_section` to pause the cpu, it must handle `up_cpu_pausereq` without any fail, otherwise other cpu will wait forever in spinlock.

Change `while` loop to `do-while` loop in `irq_waitlock`, which will ensure there is no pending `up_cpu_pausereq` before getting lock on `g_cpu_irqlock` otherwise pause request will get missed.

The `SP_DMB` is needed to ensure both cpu read correct spinlock value.

The `spin_lock(&g_cpu_resumed[cpu])` is moved upward in code to avoid race condition between cpus.
  • Loading branch information
gSahitya-samsung committed Jan 10, 2025
1 parent 7cec09f commit 7482d8c
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 5 deletions.
7 changes: 4 additions & 3 deletions os/arch/arm/src/armv7-a/arm_cpupause.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,16 @@ int up_cpu_paused_save(void)

int up_cpu_paused(int cpu)
{
/* Ensure the CPU has been resumed to avoid causing a deadlock */

spin_lock(&g_cpu_resumed[cpu]);

/* Release the g_cpu_paused spinlock to synchronize with the
* requesting CPU.
*/

spin_unlock(&g_cpu_paused[cpu]);

/* Ensure the CPU has been resumed to avoid causing a deadlock */

spin_lock(&g_cpu_resumed[cpu]);

/* Wait for the spinlock to be released. The requesting CPU will release
* the spinlock when the CPU is resumed.
Expand Down
4 changes: 2 additions & 2 deletions os/kernel/irq/irq_csection.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static bool irq_waitlock(int cpu)
* for the deadlock condition.
*/

while (spin_trylock_wo_note(&g_cpu_irqlock) == SP_LOCKED) {
do {
/* Is a pause request pending? */

if (up_cpu_pausereq(cpu) || up_get_gating_flag_status(cpu) == 1) {
Expand All @@ -136,7 +136,7 @@ static bool irq_waitlock(int cpu)

return false;
}
}
} while(spin_trylock_wo_note(&g_cpu_irqlock) == SP_LOCKED);

/* We have g_cpu_irqlock! */

Expand Down

0 comments on commit 7482d8c

Please sign in to comment.