I think I have finally found the cause of the random lockups on the uEVM and Pyra. Need to do some more testing, but it seems stable so far and I would appreciate feedback on this. It matches what the OMAP4 does, and some similar code - albeit using clockevents_notify directly - is also in the old TI 3.8 kernel.
Best
David
Seems to fix some occasional random lockups. The original TI code does something analagous to this.
Signed-off-by: David Shah dave@ds0.me --- arch/arm/mach-omap2/cpuidle44xx.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index de94173ce531..5b4befb1c5ae 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -110,6 +110,12 @@ static int omap_enter_idle_smp(struct cpuidle_device *dev, struct idle_statedata *cx = state_ptr + index; unsigned long flag;
+ /* Enter broadcast mode for periodic timers */ + tick_broadcast_enable(); + + /* Enter broadcast mode for one-shot timers */ + tick_broadcast_enter(); + raw_spin_lock_irqsave(&mpu_lock, flag); cx->mpu_state_vote++; if (cx->mpu_state_vote == num_online_cpus()) { @@ -126,6 +132,8 @@ static int omap_enter_idle_smp(struct cpuidle_device *dev, cx->mpu_state_vote--; raw_spin_unlock_irqrestore(&mpu_lock, flag);
+ tick_broadcast_exit(); + return index; }
Seems I spoke too soon, it did eventually lock up with this added - although it did seem to make things more reliable. Wondering if there is still some benefit to adding it, or whether it is just coincidence that it made things more stable (anything that adds delay to switching in/out of retention mode seems to improve stability, which makes it hard to debug...)
Best
David
On Wed, 2020-08-05 at 16:59 +0100, David Shah wrote:
Seems to fix some occasional random lockups. The original TI code does something analagous to this.
Signed-off-by: David Shah dave@ds0.me
arch/arm/mach-omap2/cpuidle44xx.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach- omap2/cpuidle44xx.c index de94173ce531..5b4befb1c5ae 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -110,6 +110,12 @@ static int omap_enter_idle_smp(struct cpuidle_device *dev, struct idle_statedata *cx = state_ptr + index; unsigned long flag;
- /* Enter broadcast mode for periodic timers */
- tick_broadcast_enable();
- /* Enter broadcast mode for one-shot timers */
- tick_broadcast_enter();
- raw_spin_lock_irqsave(&mpu_lock, flag); cx->mpu_state_vote++; if (cx->mpu_state_vote == num_online_cpus()) {
@@ -126,6 +132,8 @@ static int omap_enter_idle_smp(struct cpuidle_device *dev, cx->mpu_state_vote--; raw_spin_unlock_irqrestore(&mpu_lock, flag);
- tick_broadcast_exit();
- return index;
}