Hi, On Wednesday, November 12, 2014 05:43:20 PM Daniel Lezcano wrote: > On 11/12/2014 04:13 PM, Bartlomiej Zolnierkiewicz wrote: > > > > Hi Bartlomiej, > > [ cut ] > > >>> - using arch_send_wakeup_ipi_mask() instead of dsb_sev() > >>> (this matches CPU hotplug code in arch/arm/mach-exynos/platsmp.c) > >> > >> I am curious. You experienced very rare hangs after running the tests a > >> few hours, right ? Is the SEV replaced by the IPI solving the issue ? If > >> yes, how did you catch it ? > > > > Rare hangs showed up after about 30-40 minutes of testing with the attached > > app and script (running of "./cpuidle_state1_test.sh script 2 500" has never > > completed on the umodified driver). > > > > The problem turned out to be in the following loop waiting for CPU1 to get > > stuck in the BOOT ROM: > > > > /* > > * Wait for cpu1 to get stuck in the boot rom > > */ > > while ((__raw_readl(BOOT_VECTOR) != 0) && > > !atomic_read(&cpu1_wakeup)) > > cpu_relax(); > > > > [ Removal of the loop fixed the problem. ] > > Just for my personal information, do you know why ? Unfortunately no. I just suspect that sometimes the BOOT_VECTOR register is not zeroed (or is zeroed and then overwritten) because of the bug in the firmware. > [ cut ] > > >>> +#ifdef CONFIG_ARM_EXYNOS_CPUIDLE > >>> + if (of_machine_is_compatible("samsung,exynos4210")) > >>> + exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data; > >>> +#endif > >> > >> You should not add those #ifdef. > > > > Without those #ifdef I get: > > > > LD init/built-in.o > > arch/arm/mach-exynos/built-in.o: In function `exynos_dt_machine_init': > > /home/bzolnier/sam/linux-sprc/arch/arm/mach-exynos/exynos.c:334: undefined reference to `cpuidle_coupled_exynos_data' > > make: *** [vmlinux] Error 1 > > > > when CONFIG_EXYNOS_CPU_SUSPEND is disabled. > > Here, we are introducing some dependencies I tried to drop in the > different drivers. > > I looked more closely at the code and especially the > 'cpuidle_coupled_exynos_data'. I don't think it is worth to have it > because it adds more complexity and you have to define this structure to > be visible from the drivers/cpuidle files. > > I suggest you create an simple function in "pm.c" > > int exynos_coupled_aftr(int cpu) > { > pre_enter... > > if (!cpu) > cpu0_enter_aftr() > else > cpu1_powerdown() > > post_enter... > } > > and in the cpuidle driver itself, you just use the already existing > anonymous callback 'exynos_enter_aftr' (and mutate it to conform the > parameters). > > You won't have to share any structure between the arch code and the > cpuidle driver. The reason why the separate callbacks are needed is that the cpuidle driver code uses coupled cpuidle barriers (I cannot move them to pm.c): +static int exynos_enter_coupled_lowpower(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int ret; + + exynos_cpuidle_pdata->pre_enter_aftr(); + + /* + * Waiting all cpus to reach this point at the same moment + */ + cpuidle_coupled_parallel_barrier(dev, &exynos_idle_barrier); + + /* + * Both cpus will reach this point at the same time + */ + ret = dev->cpu ? exynos_cpuidle_pdata->cpu1_powerdown() + : exynos_cpuidle_pdata->cpu0_enter_aftr(); + if (ret) + index = ret; + + /* + * Waiting all cpus to finish the power sequence before going further + */ + cpuidle_coupled_parallel_barrier(dev, &exynos_idle_barrier); + + exynos_cpuidle_pdata->post_enter_aftr(); + + return index; +} Could you please explain how the proposed pm.c::exynos_coupled_aftr() would operate without these barriers? Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html