Message ID | 1320265849-5744-28-git-send-email-paulmck@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
On Wed, Nov 02, 2011 at 01:30:49PM -0700, Paul E. McKenney wrote: > From: Paul E. McKenney <paul.mckenney@linaro.org> > > 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". Could you elaborate a bit on "recent changes"? It looks like you mean commit 908a3283728d92df36e0c7cd63304fd35e93a8a9; if so, could you add that reference to the commit message? Also, the hard-coded use of "current->pid != 0" concerns me. Could this use some existing function? Does idle_task() help? If no appropriate predicate exists, perhaps it should. is_idle_task(current)? - Josh Triplett
On Wed, Nov 02, 2011 at 09:55:09PM -0700, Josh Triplett wrote: > On Wed, Nov 02, 2011 at 01:30:49PM -0700, Paul E. McKenney wrote: > > From: Paul E. McKenney <paul.mckenney@linaro.org> > > > > 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". > > Could you elaborate a bit on "recent changes"? It looks like you mean > commit 908a3283728d92df36e0c7cd63304fd35e93a8a9; if so, could you add > that reference to the commit message? Will do! > Also, the hard-coded use of "current->pid != 0" concerns me. Could this > use some existing function? Does idle_task() help? If no appropriate > predicate exists, perhaps it should. is_idle_task(current)? I could use idle_task(), but that does quite a bit more work. The hard-coded "current->pid != 0" is used in a number of other places in the kernel, so there is precedent. Might be worth fixing globally as a separate fix, though. Thanx, Paul
On Thu, Nov 03, 2011 at 02:00:05PM -0700, Paul E. McKenney wrote: > On Wed, Nov 02, 2011 at 09:55:09PM -0700, Josh Triplett wrote: > > On Wed, Nov 02, 2011 at 01:30:49PM -0700, Paul E. McKenney wrote: > > > From: Paul E. McKenney <paul.mckenney@linaro.org> > > > > > > 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". > > > > Could you elaborate a bit on "recent changes"? It looks like you mean > > commit 908a3283728d92df36e0c7cd63304fd35e93a8a9; if so, could you add > > that reference to the commit message? > > Will do! > > > Also, the hard-coded use of "current->pid != 0" concerns me. Could this > > use some existing function? Does idle_task() help? If no appropriate > > predicate exists, perhaps it should. is_idle_task(current)? > > I could use idle_task(), but that does quite a bit more work. Doesn't seem that high-overhead, but *shrug*. > The hard-coded "current->pid != 0" is used in a number of other places > in the kernel, so there is precedent. Well, 2 is a number, yes: arch/sparc/kernel/setup_32.c: if(current->pid != 0) { kernel/events/core.c: if (!(event->attr.exclude_idle && current->pid == 0)) > Might be worth fixing globally > as a separate fix, though. Fair enough. - Josh Triplett
On Wed, 2011-11-02 at 21:55 -0700, Josh Triplett wrote: > On Wed, Nov 02, 2011 at 01:30:49PM -0700, Paul E. McKenney wrote: > > From: Paul E. McKenney <paul.mckenney@linaro.org> > > > > 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". > > Could you elaborate a bit on "recent changes"? It looks like you mean > commit 908a3283728d92df36e0c7cd63304fd35e93a8a9; if so, could you add > that reference to the commit message? Oh, that was unintended fallout, idle_cpu() was taken to mean is this cpu currently idle, and was changed to not return true when there's pending wakeups, since in that case the cpu isn't actually idle, even though it might still be running the idle task. > Also, the hard-coded use of "current->pid != 0" concerns me. Could this > use some existing function? Does idle_task() help? If no appropriate > predicate exists, perhaps it should. is_idle_task(current)? Right, current == idle_task(smp_processor_id()) will test if the current task is the idle task for the current cpu, regardless of whether the cpu is actually idle or not. Then again, the ->pid == 0 thing seems to be fairly solid as well, having just looked at the fork_idle() code etc..
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",