Messages in this thread Patch in this message | | | Date | Wed, 2 Nov 2011 07:44:03 -0700 | From | "Paul E. McKenney" <> | Subject | Re: linux-next 20111025: warnings in rcu_idle_exit_common()/rcu_idle_enter_common() |
| |
On Wed, Nov 02, 2011 at 12:32:12AM +0800, Wu Fengguang wrote: > > Hmmmm... Please see below for a diagnostic patch that prints out who > > the kernel believes the idle thread is. Could you please give this > > a go? > > Sure. Here it goes :)
And here is a possible fix. Could you please test it?
Thanx, Paul
------------------------------------------------------------------------
rcu: Fix idle-task checks
RCU has traditionally relied on idle_cpu() to determine whether a given CPU is running in the context of an idle task, but recent changes have invalidated this approach. This commit therefore switches from idle_cpu to "current->pid != 0".
Suggested-by: Carsten Emde <C.Emde@osadl.org> Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index f4e7bc3..35f8a07 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c @@ -65,7 +65,7 @@ static void rcu_idle_enter_common(long long oldval) return; } RCU_TRACE(trace_rcu_dyntick("Start", oldval, rcu_dynticks_nesting)); - if (!idle_cpu(smp_processor_id())) { + if (current->pid != 0) { struct task_struct *idle = idle_task(smp_processor_id()); RCU_TRACE(trace_rcu_dyntick("Error on entry: not idle task", @@ -119,7 +119,7 @@ static void rcu_idle_exit_common(long long oldval) return; } RCU_TRACE(trace_rcu_dyntick("End", oldval, rcu_dynticks_nesting)); - if (!idle_cpu(smp_processor_id())) { + if (!current->pid != 0) { struct task_struct *idle = idle_task(smp_processor_id()); RCU_TRACE(trace_rcu_dyntick("Error on exit: not idle task", diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 3d7b474..414af68 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -355,7 +355,7 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval) return; } trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting); - if (!idle_cpu(smp_processor_id())) { + if (current->pid != 0) { struct task_struct *idle = idle_task(smp_processor_id()); trace_rcu_dyntick("Error on entry: not idle task", @@ -449,7 +449,7 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval) smp_mb__after_atomic_inc(); /* See above. */ WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); trace_rcu_dyntick("End", oldval, rdtp->dynticks_nesting); - if (!idle_cpu(smp_processor_id())) { + if (current->pid != 0) { struct task_struct *idle = idle_task(smp_processor_id()); trace_rcu_dyntick("Error on exit: not idle task",
| |