Dave Anderson wrote:
 
Sachin,

This may require help from the IBM ppc64 people out there,
but it appears that the issue at hand has something to do
with the uniprocessor aspect.

Your vmlinux is an SMP kernel, but I'm guessing that the wrong
choice of "runq" addresses is being made below:

        if (symbol_exists("per_cpu__runqueues") &&
            VALID_MEMBER(runqueue_idle)) {
                runqbuf = GETBUF(SIZE(runqueue));
                for (i = 0; i < nr_cpus; i++) {
                       if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) {
                                runq = symbol_value("per_cpu__runqueues") +
                                        kt->__per_cpu_offset[i];
                        } else
                                runq = symbol_value("per_cpu__runqueues");

                        readmem(runq, KVADDR, runqbuf,
                                SIZE(runqueue), "runqueues entry (per_cpu)",
                                FAULT_ON_ERROR);
                        tasklist[i] = ULONG(runqbuf + OFFSET(runqueue_idle));
                        if (IS_KVADDR(tasklist[i]))
                                cnt++;

I don't know what your "kt->flags" is showing at the
decision point above, but if you hack the code and force
it to select the "other" runq value, does it work OK?

When CONFIG_SMP is not configured into the kernel, then
the direct value of "per_cpu__runqueues" is used, whereas
with SMP kernels, the appropriate offset needs to be
applied.  At least that's how it works (has worked?) with
the other architectures.

Dave

Looking at ppc64_paca_init(), it appears that this might be
the problem if SMP is not set in kt->flags:

static void
ppc64_paca_init()
{
        ...

        for (i = cpus = 0; i < nr_paca; i++) {
                div_t val = div(i, BITS_FOR_LONG);
                /*
                 * CPU online?
                 */
                if (!(cpu_online_map[val.quot] & (0x1UL << val.rem)))
                        continue;

                readmem(symbol_value("paca") + (i * SIZE(ppc64_paca)),
                        KVADDR, cpu_paca_buf, SIZE(ppc64_paca),
                        "paca entry", FAULT_ON_ERROR);

                kt->__per_cpu_offset[i] = ULONG(cpu_paca_buf + data_offset);
                kt->flags |= PER_CPU_OFF;
                cpus++;
        }
        kt->cpus = cpus;
        if (kt->cpus > 1)
                kt->flags |= SMP;
}

If SMP is not set coming into this function, and therefore won't
get set above, then the wrong runq pointer would be selected later
on get_idle_threads().

Dave