[PATCH] ARM: OMAP4: cpuidle: fix: call cpu_cluster_pm_exit conditionally

Kevin Hilman khilman at linaro.org
Tue Aug 27 11:54:06 EDT 2013


Vladimir Murzin <murzin.v at gmail.com> writes:

> We call cpu_cluster_pm_enter for dev->cpu == 0 only, but
> cpu_cluster_pm_exit called without that check.
>
> Because of that unhandled page fault may happen:
>
> [    3.803405] Unable to handle kernel paging request at virtual address 00002500
> [    3.810974] pgd = c0004000
> [    3.813812] [00002500] *pgd=00000000
> [    3.817596] Internal error: Oops: 5 [#1] SMP ARM
> [    3.822418] Modules linked in:
> [    3.825653] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.11.0-rc6+ #21
> [    3.832397] task: ed86ef40 ti: ed896000 task.ti: ed896000
> [    3.838073] PC is at irq_notifier+0x234/0x25c
> [    3.842651] LR is at irq_notifier+0x218/0x25c
> [    3.847229] pc : [<c0029ed8>]    lr : [<c0029ebc>]    psr: 80000193
> [    3.847229] sp : ed897ee8  ip : 00000005  fp : 00000001
> [    3.859283] r10: c0b395f0  r9 : c0b30594  r8 : c0b8c2ac
> [    3.864776] r7 : ffffffff  r6 : 00000000  r5 : 00000005  r4 : 00000000
> [    3.871643] r3 : 00002500  r2 : 00000000  r1 : 00000005  r0 : 44302244
> [    3.878479] Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
> [    3.886260] Control: 10c5387d  Table: 8000404a  DAC: 00000015
> [    3.892272] Process swapper/1 (pid: 0, stack limit = 0xed896240)
> [    3.898590] Stack: (0xed897ee8 to 0xed898000)
> [    3.903167] 7ee0:                   c0979c3a 00000001 ed897ef8 ed896000 c0014f7c 00000000
> [    3.911743] 7f00: 00000005 00000000 ffffffff c0b8c2ac c0b395f0 c077c04c c0c94b48 c0b3953c
> [    3.920318] 7f20: c0bcd928 00000002 c0b39524 c00cfad8 00000000 ffffffff 00000000 c00cfb10
> [    3.928924] 7f40: c14e62c0 c002c1c8 c002c0ac c14e62c0 00000002 e251c37d 00000000 c0b39548
> [    3.937499] 7f60: c0b395f0 c05a1bc4 e251c37d 00000000 00000005 c05a3870 edc90380 edc90380
> [    3.946105] 7f80: edc90394 c14e62c0 c0b39548 00000002 c0784064 c05a3c78 c0b395e0 c14e62c0
> [    3.954681] 7fa0: 00000002 c0b39548 c0bc9db8 00000000 00000001 c05a1dc0 ed896000 00000015
> [    3.963287] 7fc0: c0bc9db8 ed896000 8000406a c0b30594 c0784064 c000e504 00000746 c007a528
> [    3.971862] 7fe0: 00000001 0000001d 600001d3 c0bcc004 00000000 800086c4 ee0aa6a7 d2aabaa9
> [    3.980499] [<c0029ed8>] (irq_notifier+0x234/0x25c) from [<c077c04c>] (notifier_call_chain+0x38/0x68)
> [    3.990173] [<c077c04c>] (notifier_call_chain+0x38/0x68) from [<c00cfad8>] (cpu_pm_notify+0x20/0x38)
> [    3.999786] [<c00cfad8>] (cpu_pm_notify+0x20/0x38) from [<c00cfb10>] (cpu_cluster_pm_exit+0x20/0x50)
> [    4.009399] [<c00cfb10>] (cpu_cluster_pm_exit+0x20/0x50) from [<c002c1c8>] (omap_enter_idle_coupled+0x11c/0x14c)
> [    4.020111] [<c002c1c8>] (omap_enter_idle_coupled+0x11c/0x14c) from [<c05a1bc4>] (cpuidle_enter_state+0x40/0xec)
> [    4.030822] [<c05a1bc4>] (cpuidle_enter_state+0x40/0xec) from [<c05a3c78>] (cpuidle_enter_state_coupled+0x1f4/0x240)
> [    4.041870] [<c05a3c78>] (cpuidle_enter_state_coupled+0x1f4/0x240) from [<c05a1dc0>] (cpuidle_idle_call+0x150/0x228)
> [    4.052947] [<c05a1dc0>] (cpuidle_idle_call+0x150/0x228) from [<c000e504>] (arch_cpu_idle+0x8/0x38)
> [    4.062499] [<c000e504>] (arch_cpu_idle+0x8/0x38) from [<c007a528>] (cpu_startup_entry+0x178/0x1e4)
> [    4.071990] [<c007a528>] (cpu_startup_entry+0x178/0x1e4) from [<800086c4>] (0x800086c4)
> [    4.080383] Code: e5922288 03a03b0a 13a03c25 e0823003 (e5932000)
> [    4.086791] ---[ end trace d83954a84a6fa69e ]---
>
> It is supposed that sar_base is initialized in irq_save_context, which
> is called on CPU_CLUSTER_PM_ENTER notification. If this notification
> has been missed and CPU_CLUSTER_PM_EXIT is received sar_base is NULL.
>
> Fix it by calling CPU_CLUSTER_PM_{ENTER,EXIT} under the same condition.
>
> Signed-off-by: Vladimir Murzin <murzin.v at gmail.com>

Good catch.

Acked-by: Kevin Hilman <khilman at linaro.org>

> ---
>  arch/arm/mach-omap2/cpuidle44xx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index c443f2e..4c8982a 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> @@ -143,7 +143,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
>  	 * Call idle CPU cluster PM exit notifier chain
>  	 * to restore GIC and wakeupgen context.
>  	 */
> -	if ((cx->mpu_state == PWRDM_POWER_RET) &&
> +	if (dev->cpu == 0 && (cx->mpu_state == PWRDM_POWER_RET) &&
>  		(cx->mpu_logic_state == PWRDM_POWER_OFF))
>  		cpu_cluster_pm_exit();



More information about the linux-arm-kernel mailing list