Message ID | 20220608144518.073801916@infradead.org |
---|---|
State | New |
Headers | show |
Series | cpuidle,rcu: Cleanup the mess | expand |
* Peter Zijlstra <peterz@infradead.org> [220608 15:00]: > On Wed, Jun 08, 2022 at 04:27:57PM +0200, Peter Zijlstra wrote: > > @@ -254,11 +255,18 @@ void omap_sram_idle(void) > > */ > > if (save_state) > > omap34xx_save_context(omap3_arm_context); > > + > > + if (rcuidle) > > + cpuidle_rcu_enter(); > > + > > if (save_state == 1 || save_state == 3) > > cpu_suspend(save_state, omap34xx_do_sram_idle); > > else > > omap34xx_do_sram_idle(save_state); > > > > + if (rcuidle) > > + rcuidle_rcu_exit(); > > *sigh* so much for this having been exposed to the robots for >2 days :/ I tested your git branch of these patches, so: Reviewed-by: Tony Lindgren <tony@atomide.com> Tested-by: Tony Lindgren <tony@atomide.com>
On Mon, Jun 13, 2022 at 03:39:05PM +0300, Tony Lindgren wrote: > OMAP4 uses full SoC suspend modes as idle states, as such it needs the > whole power-domain and clock-domain code from the idle path. > > All that code is not suitable to run with RCU disabled, as such push > RCU-idle deeper still. > > Signed-off-by: Tony Lindgren <tony@atomide.com> > --- > > Peter here's one more for your series, looks like this is needed to avoid > warnings similar to what you did for omap3. Thanks Tony! I've had a brief look at omap2_pm_idle() and do I understand it right that something like the below patch would reduce it to a simple 'WFI'? What do I do with the rest of that code, because I don't think this thing has a cpuidle driver to take over, effectively turning it into dead code. --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -126,10 +126,20 @@ static int omap2_allow_mpu_retention(voi return 1; } -static void omap2_enter_mpu_retention(void) +static void omap2_do_wfi(void) { const int zero = 0; + /* WFI */ + asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); +} + +#if 0 +/* + * possible cpuidle implementation between WFI and full_retention above + */ +static void omap2_enter_mpu_retention(void) +{ /* The peripherals seem not to be able to wake up the MPU when * it is in retention mode. */ if (omap2_allow_mpu_retention()) { @@ -146,8 +157,7 @@ static void omap2_enter_mpu_retention(vo pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); } - /* WFI */ - asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); + omap2_do_wfi(); pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); } @@ -161,6 +171,7 @@ static int omap2_can_sleep(void) return 1; } +#endif static void omap2_pm_idle(void) { @@ -169,6 +180,7 @@ static void omap2_pm_idle(void) if (omap_irq_pending()) return; +#if 0 error = cpu_cluster_pm_enter(); if (error || !omap2_can_sleep()) { omap2_enter_mpu_retention(); @@ -179,6 +191,9 @@ static void omap2_pm_idle(void) out_cpu_cluster_pm: cpu_cluster_pm_exit(); +#else + omap2_do_wfi(); +#endif } static void __init prcm_setup_regs(void)
Hi, Adding Aaro Koskinen and Peter Vasil for pm24xx for n800 and n810 related idle. * Peter Zijlstra <peterz@infradead.org> [220614 22:07]: > On Mon, Jun 13, 2022 at 03:39:05PM +0300, Tony Lindgren wrote: > > OMAP4 uses full SoC suspend modes as idle states, as such it needs the > > whole power-domain and clock-domain code from the idle path. > > > > All that code is not suitable to run with RCU disabled, as such push > > RCU-idle deeper still. > > > > Signed-off-by: Tony Lindgren <tony@atomide.com> > > --- > > > > Peter here's one more for your series, looks like this is needed to avoid > > warnings similar to what you did for omap3. > > Thanks Tony! > > I've had a brief look at omap2_pm_idle() and do I understand it right > that something like the below patch would reduce it to a simple 'WFI'? Yes that should do for omap2_do_wfi(). > What do I do with the rest of that code, because I don't think this > thing has a cpuidle driver to take over, effectively turning it into > dead code. As we are establishing a policy where deeper idle states must be handled by cpuidle, and for most part that has been the case for at least 10 years, I'd just drop the unused functions with an explanation in the patch why we're doing it. Or the functions could be tagged with __maybe_unused if folks prefer that. In the pm24xx case we are not really causing a regression for users as there are still pending patches to make n800 and n810 truly usable with the mainline kernel. At least the PMIC and LCD related patches need some work [0]. The deeper idle states can be added back later using cpuidle as needed so we have a clear path. Aaro & Peter V, do you have any better suggestions here as this will mostly affect you guys currently? Regards, Tony [0] https://lore.kernel.org/linux-omap/20211224214512.1583430-1-peter.vasil@gmail.com/ > --- a/arch/arm/mach-omap2/pm24xx.c > +++ b/arch/arm/mach-omap2/pm24xx.c > @@ -126,10 +126,20 @@ static int omap2_allow_mpu_retention(voi > return 1; > } > > -static void omap2_enter_mpu_retention(void) > +static void omap2_do_wfi(void) > { > const int zero = 0; > > + /* WFI */ > + asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); > +} > + > +#if 0 > +/* > + * possible cpuidle implementation between WFI and full_retention above > + */ > +static void omap2_enter_mpu_retention(void) > +{ > /* The peripherals seem not to be able to wake up the MPU when > * it is in retention mode. */ > if (omap2_allow_mpu_retention()) { > @@ -146,8 +157,7 @@ static void omap2_enter_mpu_retention(vo > pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); > } > > - /* WFI */ > - asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); > + omap2_do_wfi(); > > pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); > } > @@ -161,6 +171,7 @@ static int omap2_can_sleep(void) > > return 1; > } > +#endif > > static void omap2_pm_idle(void) > { > @@ -169,6 +180,7 @@ static void omap2_pm_idle(void) > if (omap_irq_pending()) > return; > > +#if 0 > error = cpu_cluster_pm_enter(); > if (error || !omap2_can_sleep()) { > omap2_enter_mpu_retention(); > @@ -179,6 +191,9 @@ static void omap2_pm_idle(void) > > out_cpu_cluster_pm: > cpu_cluster_pm_exit(); > +#else > + omap2_do_wfi(); > +#endif > } > > static void __init prcm_setup_regs(void)
--- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -133,9 +133,7 @@ static int omap3_enter_idle(struct cpuid } /* Execute ARM wfi */ - cpuidle_rcu_enter(); - omap_sram_idle(); - cpuidle_rcu_exit(); + omap_sram_idle(true); /* * Call idle CPU PM enter notifier chain to restore --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -29,7 +29,7 @@ static inline int omap4_idle_init(void) extern void *omap3_secure_ram_storage; extern void omap3_pm_off_mode_enable(int); -extern void omap_sram_idle(void); +extern void omap_sram_idle(bool rcuidle); extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); #if defined(CONFIG_PM_OPP) --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -26,6 +26,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/of.h> +#include <linux/cpuidle.h> #include <trace/events/power.h> @@ -174,7 +175,7 @@ static int omap34xx_do_sram_idle(unsigne return 0; } -void omap_sram_idle(void) +void omap_sram_idle(bool rcuidle) { /* Variable to tell what needs to be saved and restored * in omap_sram_idle*/ @@ -254,11 +255,18 @@ void omap_sram_idle(void) */ if (save_state) omap34xx_save_context(omap3_arm_context); + + if (rcuidle) + cpuidle_rcu_enter(); + if (save_state == 1 || save_state == 3) cpu_suspend(save_state, omap34xx_do_sram_idle); else omap34xx_do_sram_idle(save_state); + if (rcuidle) + rcuidle_rcu_exit(); + /* Restore normal SDRC POWER settings */ if (cpu_is_omap3430() && omap_rev() >= OMAP3430_REV_ES3_0 && (omap_type() == OMAP2_DEVICE_TYPE_EMU || @@ -316,7 +324,7 @@ static int omap3_pm_suspend(void) omap3_intc_suspend(); - omap_sram_idle(); + omap_sram_idle(false); restore: /* Restore next_pwrsts */
OMAP3 uses full SoC suspend modes as idle states, as such it needs the whole power-domain and clock-domain code from the idle path. All that code is not suitable to run with RCU disabled, as such push RCU-idle deeper still. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- arch/arm/mach-omap2/cpuidle34xx.c | 4 +--- arch/arm/mach-omap2/pm.h | 2 +- arch/arm/mach-omap2/pm34xx.c | 12 ++++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-)