Subject: Re: Worst case performance of up()

From: Adrian Cox <[email-masked]>
Date: Mon, 04 Dec 2006 13:43:14 +0000

On Sun, 2006-12-03 at 07:52 +1100, Benjamin Herrenschmidt wrote:
> On Sat, 2006-12-02 at 11:54 +0000, Adrian Cox wrote:
> > On Sat, 2006-12-02 at 22:15 +1100, Benjamin Herrenschmidt wrote:
> > > I think we are hitting a livelock due to both CPUs trying to perform an
> > > atomic operation on the same cache line (or same variable even).
> > 
> > I agree.

I now have this one identified and fixed. The cure is actually simple:
on 32-bit SMP machines, rather than setting powersave_nap to 0, set
ppc_md.power_save to NULL.

CPU A is attempting to reschedule the idle thread on CPU B:
set_tsk_thread_flag(p, TIF_NEED_RESCHED);

CPU B is in the idle loop, but does not support nap. The result is that
ppc6xx_idle() returns immediately, and CPU B runs in a tight loop:
while(...) {
	set_thread_flag(TIF_POLLING_NRFLAG);
	...
	clear_thread_flag(TIF_POLLING_NRFLAG);
}

If ppc_md.power_save is NULL, then the idle loop does not touch the flag
word of the idle thread, and everything works.

-- 
Adrian Cox <[email-masked]>