Thread (15 messages) 15 messages, 4 authors, 2012-09-17

Re: [PATCH 01/10] alpha: Add missing RCU idle APIs on idle loop

From: Paul E. McKenney <hidden>
Date: 2012-08-23 12:25:43
Also in: lkml

On Thu, Aug 23, 2012 at 12:42:11PM +0200, Frederic Weisbecker wrote:
On Wed, Aug 22, 2012 at 12:01:09PM -0700, Paul E. McKenney wrote:
quoted
quoted
The current code is preemptable, at least it appears so because it calls
schedule() directly. And if I call rcu_idle_enter() in a preemptable section,
I'm in trouble because I'll schedule while in extended QS.

Thus I need to disable preemption here at least until I call rcu_idle_exit().

Now this is an endless loop so there is no need to re-enable
preemption after the loop. And schedule_preempt_disabled()
takes care of enabling preemption before schedule() and redisabling
it afterward.

quoted
							Thanx, Paul
quoted
 	while (1) {
 		/* FIXME -- EV6 and LCA45 know how to power down
 		   the CPU.  */

+		rcu_idle_enter();
 		while (!need_resched())
 			cpu_relax();
-		schedule();
+		rcu_idle_exit();
+		schedule_preempt_disabled();
 	}
Understood, but what I don't understand is why you don't need a
preempt_enable() right here.
Look, let's inline the content of schedule_preempt_disabled(), the code
then looks like:

void cpu_idle(void)
{
	set_thread_flag(TIF_POLLING_NRFLAG);

	preempt_disable();
	while (1) {
		/* FIXME -- EV6 and LCA45 know how to power down
		   the CPU.  */

		rcu_idle_enter();
		while (!need_resched())
			cpu_relax();
		rcu_idle_exit();

		sched_preempt_enable_no_resched();
	        schedule();
	        preempt_disable();
	}
	preempt_enable();  /* Why is this not needed? */
}

So there is a preempt_enable() before we schedule, then we re-disable
preemption after schedule.

Now I realize cpu_idle() is supposed to be called with preemption disabled
already so I shouldn't add an explicit preempt_disable() or it's going to be worse.
But that means there is an existing bug here in alpha, it should call schedule_preempt_disabled()
instead of schedule(). cpu_idle() is called with preemption disabled on the boot CPU.
And it should as well from the secondary CPUs entry but alpha doesn't seem to do that.

So I need to fix that first. I'll respin.
OK, look forward to seeing the respin.

							Thanx, Paul
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help