Skip to content

Commit

Permalink
powerpc/pseries: Pass more accurate number of supported cores to firm…
Browse files Browse the repository at this point in the history
…ware

Updated variant of a patch by Joel Schopp.

The field containing the number of supported cores which we pass to
firmware via the ibm,client-architecture call was set by a previous
patch statically as high as is possible (NR_CPUS).

However, that value isn't quite right for a system that supports
multiple threads per core, thus permitting the firmware to assign
more cores to a Linux partition than it can really cope with.

This patch improves it by using the device-tree to determine the
number of threads supported by the processors in order to adjust
the value passed to firmware.

Signed-off-by: Joel Schopp <jschopp@austin.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Benjamin Herrenschmidt committed Feb 4, 2010
1 parent 28bb9ee commit efec959
Showing 1 changed file with 63 additions and 1 deletion.
64 changes: 63 additions & 1 deletion arch/powerpc/kernel/prom_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,12 @@ static unsigned char ibm_architecture_vec[] = {
0,
0,
0,
W(NR_CPUS), /* number of cores supported*/
/* WARNING: The offset of the "number of cores" field below
* must match by the macro below. Update the definition if
* the structure layout changes.
*/
#define IBM_ARCH_VEC_NRCORES_OFFSET 100
W(NR_CPUS), /* number of cores supported */

/* option vector 6: IBM PAPR hints */
4 - 2, /* length */
Expand Down Expand Up @@ -807,13 +812,70 @@ static struct fake_elf {
}
};

static int __init prom_count_smt_threads(void)
{
phandle node;
char type[64];
unsigned int plen;

/* Pick up th first CPU node we can find */
for (node = 0; prom_next_node(&node); ) {
type[0] = 0;
prom_getprop(node, "device_type", type, sizeof(type));

if (strcmp(type, RELOC("cpu")))
continue;
/*
* There is an entry for each smt thread, each entry being
* 4 bytes long. All cpus should have the same number of
* smt threads, so return after finding the first.
*/
plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
if (plen == PROM_ERROR)
break;
plen >>= 2;
prom_debug("Found 0x%x smt threads per core\n", (unsigned long)plen);

/* Sanity check */
if (plen < 1 || plen > 64) {
prom_printf("Threads per core 0x%x out of bounds, assuming 1\n",
(unsigned long)plen);
return 1;
}
return plen;
}
prom_debug("No threads found, assuming 1 per core\n");

return 1;

}


static void __init prom_send_capabilities(void)
{
ihandle elfloader, root;
prom_arg_t ret;
u32 *cores;

root = call_prom("open", 1, 1, ADDR("/"));
if (root != 0) {
/* We need to tell the FW about the number of cores we support.
*
* To do that, we count the number of threads on the first core
* (we assume this is the same for all cores) and use it to
* divide NR_CPUS.
*/
cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]);
if (*cores != NR_CPUS) {
prom_printf("WARNING ! "
"ibm_architecture_vec structure inconsistent: 0x%x !\n",
*cores);
} else {
*cores = NR_CPUS / prom_count_smt_threads();
prom_printf("Max number of cores passed to firmware: 0x%x\n",
(unsigned long)*cores);
}

/* try calling the ibm,client-architecture-support method */
prom_printf("Calling ibm,client-architecture-support...");
if (call_prom_ret("call-method", 3, 2, &ret,
Expand Down

0 comments on commit efec959

Please sign in to comment.