Re: [PATCH 3/4] ARM: imx6q: Fix missing need_resched() check after rcu_idle_enter()

2021-01-04 Thread Fabio Estevam
Hi Frederic,

On Mon, Jan 4, 2021 at 12:21 PM Frederic Weisbecker  wrote:
>
> Entering RCU idle mode may cause a deferred wake up of an RCU NOCB_GP
> kthread (rcuog) to be serviced.
>
> Usually a wake up happening while running the idle task is spotted in
> one of the need_resched() checks carefully placed within the idle loop
> that can break to the scheduler.
>
> Unfortunately imx6q_enter_wait() is beyond the last generic
> need_resched() check and it performs a wfi right away after the call to
> rcu_idle_enter(). We may halt the CPU with a resched request unhandled,
> leaving the task hanging.
>
> Fix this with performing a last minute need_resched() check after
> calling rcu_idle_enter().

Shouldn't tif_need_resched() be used instead of need_resched() in the
commit log?


[PATCH 3/4] ARM: imx6q: Fix missing need_resched() check after rcu_idle_enter()

2021-01-04 Thread Frederic Weisbecker
Entering RCU idle mode may cause a deferred wake up of an RCU NOCB_GP
kthread (rcuog) to be serviced.

Usually a wake up happening while running the idle task is spotted in
one of the need_resched() checks carefully placed within the idle loop
that can break to the scheduler.

Unfortunately imx6q_enter_wait() is beyond the last generic
need_resched() check and it performs a wfi right away after the call to
rcu_idle_enter(). We may halt the CPU with a resched request unhandled,
leaving the task hanging.

Fix this with performing a last minute need_resched() check after
calling rcu_idle_enter().

Reported-by: Paul E. McKenney 
Reviewed-by: Rafael J. Wysocki 
Fixes: 1a67b9263e06 (ARM: imx6q: Fixup RCU usage for cpuidle)
Cc: sta...@vger.kernel.org
Cc: Shawn Guo 
Cc: Sascha Hauer 
Cc: Pengutronix Kernel Team 
Cc: Fabio Estevam 
Cc: NXP Linux Team 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Signed-off-by: Frederic Weisbecker 
---
 arch/arm/mach-imx/cpuidle-imx6q.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c 
b/arch/arm/mach-imx/cpuidle-imx6q.c
index 094337dc1bc7..1115f4dc6d1d 100644
--- a/arch/arm/mach-imx/cpuidle-imx6q.c
+++ b/arch/arm/mach-imx/cpuidle-imx6q.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -25,7 +26,12 @@ static int imx6q_enter_wait(struct cpuidle_device *dev,
raw_spin_unlock(&cpuidle_lock);
 
rcu_idle_enter();
-   cpu_do_idle();
+   /*
+* Last need_resched() check must come after rcu_idle_enter()
+* which may wake up RCU internal tasks.
+*/
+   if (!tif_need_resched())
+   cpu_do_idle();
rcu_idle_exit();
 
raw_spin_lock(&cpuidle_lock);
-- 
2.25.1



[PATCH 3/4] ARM: imx6q: Fix missing need_resched() check after rcu_idle_enter()

2020-12-21 Thread Frederic Weisbecker
Entering RCU idle mode may cause a deferred wake up of an RCU NOCB_GP
kthread (rcuog) to be serviced.

Usually a wake up happening while running the idle task is spotted in
one of the need_resched() checks carefully placed within the idle loop
that can break to the scheduler.

Unfortunately imx6q_enter_wait() is beyond the last generic
need_resched() check and it performs a wfi right away after the call to
rcu_idle_enter(). We may halt the CPU with a resched request unhandled,
leaving the task hanging.

Fix this with performing a last minute need_resched() check after
calling rcu_idle_enter().

Reported-by: Paul E. McKenney 
Fixes: 1a67b9263e06 (ARM: imx6q: Fixup RCU usage for cpuidle)
Cc: sta...@vger.kernel.org
Cc: Shawn Guo 
Cc: Sascha Hauer 
Cc: Pengutronix Kernel Team 
Cc: Fabio Estevam 
Cc: NXP Linux Team 
Cc: Peter Zijlstra 
Cc: Rafael J. Wysocki 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Signed-off-by: Frederic Weisbecker 
---
 arch/arm/mach-imx/cpuidle-imx6q.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c 
b/arch/arm/mach-imx/cpuidle-imx6q.c
index 094337dc1bc7..31a60d257d3d 100644
--- a/arch/arm/mach-imx/cpuidle-imx6q.c
+++ b/arch/arm/mach-imx/cpuidle-imx6q.c
@@ -25,7 +25,12 @@ static int imx6q_enter_wait(struct cpuidle_device *dev,
raw_spin_unlock(&cpuidle_lock);
 
rcu_idle_enter();
-   cpu_do_idle();
+   /*
+* Last need_resched() check must come after rcu_idle_enter()
+* which may wake up RCU internal tasks.
+*/
+   if (!need_resched())
+   cpu_do_idle();
rcu_idle_exit();
 
raw_spin_lock(&cpuidle_lock);
-- 
2.25.1