<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Dave Anderson wrote:
<blockquote TYPE=CITE> 
<br><tt>Sachin,</tt>
<p><tt>This may require help from the IBM ppc64 people out there,</tt>
<br><tt>but it appears that the issue at hand has something to do</tt>
<br><tt>with the uniprocessor aspect.</tt>
<p><tt>Your vmlinux is an SMP kernel, but I'm guessing that the wrong</tt>
<br><tt>choice of "runq" addresses is being made below:</tt>
<p><tt>        if (symbol_exists("per_cpu__runqueues")
&&</tt>
<br><tt>           
VALID_MEMBER(runqueue_idle)) {</tt>
<br><tt>               
runqbuf = GETBUF(SIZE(runqueue));</tt>
<br><tt>               
for (i = 0; i < nr_cpus; i++) {</tt>
<br><tt>                      

<b>if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF))
{</b></tt>
<br><b><tt>                               
runq = symbol_value("per_cpu__runqueues") +</tt></b>
<br><b><tt>                                       
kt->__per_cpu_offset[i];</tt></b>
<br><b><tt>                       
} else</tt></b>
<br><b><tt>                               
runq = symbol_value("per_cpu__runqueues");</tt></b>
<p><tt>                       
readmem(runq, KVADDR, runqbuf,</tt>
<br><tt>                               
SIZE(runqueue), "runqueues entry (per_cpu)",</tt>
<br><tt>                               
FAULT_ON_ERROR);</tt>
<br><tt>                       
tasklist[i] = ULONG(runqbuf + OFFSET(runqueue_idle));</tt>
<br><tt>                       
if (IS_KVADDR(tasklist[i]))</tt>
<br><tt>                               
cnt++;</tt>
<p><tt>I don't know what your "kt->flags" is showing at the</tt>
<br><tt>decision point above, but if you hack the code and force</tt>
<br><tt>it to select the "other" runq value, does it work OK?</tt>
<p><tt>When CONFIG_SMP is not configured into the kernel, then</tt>
<br><tt>the direct value of "per_cpu__runqueues" is used, whereas</tt>
<br><tt>with SMP kernels, the appropriate offset needs to be</tt>
<br><tt>applied.  At least that's how it works (has worked?) with</tt>
<br><tt>the other architectures.</tt>
<p><tt>Dave</tt></blockquote>
<tt>Looking at ppc64_paca_init(), it appears that this might be</tt>
<br><tt>the problem if SMP is not set in kt->flags:</tt><tt></tt>
<p><tt>static void</tt>
<br><tt>ppc64_paca_init()</tt>
<br><tt>{</tt>
<br><tt>        ...</tt><tt></tt>
<p><tt>        for (i = cpus = 0; i
< nr_paca; i++) {</tt>
<br><tt>               
div_t val = div(i, BITS_FOR_LONG);</tt>
<br><tt>               
/*</tt>
<br><tt>                
* CPU online?</tt>
<br><tt>                
*/</tt>
<br><tt>               
if (!(cpu_online_map[val.quot] & (0x1UL << val.rem)))</tt>
<br><tt>                       
continue;</tt><tt></tt>
<p><tt>               
readmem(symbol_value("paca") + (i * SIZE(ppc64_paca)),</tt>
<br><tt>                       
KVADDR, cpu_paca_buf, SIZE(ppc64_paca),</tt>
<br><tt>                       
"paca entry", FAULT_ON_ERROR);</tt><tt></tt>
<p><tt>               
kt->__per_cpu_offset[i] = ULONG(cpu_paca_buf + data_offset);</tt>
<br><tt>               
kt->flags |= PER_CPU_OFF;</tt>
<br><tt>               
cpus++;</tt>
<br><tt>        }</tt>
<br><tt>        kt->cpus = cpus;</tt>
<br><b><tt>        if (kt->cpus > 1)</tt></b>
<br><b><tt>               
kt->flags |= SMP;</tt></b>
<br><tt>}</tt><tt></tt>
<p><tt>If SMP is not set coming into this function, and therefore won't</tt>
<br><tt>get set above, then the wrong runq pointer would be selected later</tt>
<br><tt>on get_idle_threads().</tt><tt></tt>
<p><tt>Dave</tt>
<br><tt></tt> </html>