aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-02-03 22:33:54 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-02-03 22:33:54 -0500
commitefec959f63de850fbd2442189f7dfc9c38efe251 (patch)
tree63824395c5ddb427cbcd115f975154b09ebb1334 /arch/powerpc/kernel
parent28bb9ee13aa0ee4c57dc3568f539cc84920b43aa (diff)
powerpc/pseries: Pass more accurate number of supported cores to firmware
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>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/prom_init.c64
1 files changed, 63 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 59d5bd1c064d..5f306c4946e5 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -710,7 +710,12 @@ static unsigned char ibm_architecture_vec[] = {
710 0, 710 0,
711 0, 711 0,
712 0, 712 0,
713 W(NR_CPUS), /* number of cores supported*/ 713 /* WARNING: The offset of the "number of cores" field below
714 * must match by the macro below. Update the definition if
715 * the structure layout changes.
716 */
717#define IBM_ARCH_VEC_NRCORES_OFFSET 100
718 W(NR_CPUS), /* number of cores supported */
714 719
715 /* option vector 6: IBM PAPR hints */ 720 /* option vector 6: IBM PAPR hints */
716 4 - 2, /* length */ 721 4 - 2, /* length */
@@ -807,13 +812,70 @@ static struct fake_elf {
807 } 812 }
808}; 813};
809 814
815static int __init prom_count_smt_threads(void)
816{
817 phandle node;
818 char type[64];
819 unsigned int plen;
820
821 /* Pick up th first CPU node we can find */
822 for (node = 0; prom_next_node(&node); ) {
823 type[0] = 0;
824 prom_getprop(node, "device_type", type, sizeof(type));
825
826 if (strcmp(type, RELOC("cpu")))
827 continue;
828 /*
829 * There is an entry for each smt thread, each entry being
830 * 4 bytes long. All cpus should have the same number of
831 * smt threads, so return after finding the first.
832 */
833 plen = prom_getproplen(node, "ibm,ppc-interrupt-server#s");
834 if (plen == PROM_ERROR)
835 break;
836 plen >>= 2;
837 prom_debug("Found 0x%x smt threads per core\n", (unsigned long)plen);
838
839 /* Sanity check */
840 if (plen < 1 || plen > 64) {
841 prom_printf("Threads per core 0x%x out of bounds, assuming 1\n",
842 (unsigned long)plen);
843 return 1;
844 }
845 return plen;
846 }
847 prom_debug("No threads found, assuming 1 per core\n");
848
849 return 1;
850
851}
852
853
810static void __init prom_send_capabilities(void) 854static void __init prom_send_capabilities(void)
811{ 855{
812 ihandle elfloader, root; 856 ihandle elfloader, root;
813 prom_arg_t ret; 857 prom_arg_t ret;
858 u32 *cores;
814 859
815 root = call_prom("open", 1, 1, ADDR("/")); 860 root = call_prom("open", 1, 1, ADDR("/"));
816 if (root != 0) { 861 if (root != 0) {
862 /* We need to tell the FW about the number of cores we support.
863 *
864 * To do that, we count the number of threads on the first core
865 * (we assume this is the same for all cores) and use it to
866 * divide NR_CPUS.
867 */
868 cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]);
869 if (*cores != NR_CPUS) {
870 prom_printf("WARNING ! "
871 "ibm_architecture_vec structure inconsistent: 0x%x !\n",
872 *cores);
873 } else {
874 *cores = NR_CPUS / prom_count_smt_threads();
875 prom_printf("Max number of cores passed to firmware: 0x%x\n",
876 (unsigned long)*cores);
877 }
878
817 /* try calling the ibm,client-architecture-support method */ 879 /* try calling the ibm,client-architecture-support method */
818 prom_printf("Calling ibm,client-architecture-support..."); 880 prom_printf("Calling ibm,client-architecture-support...");
819 if (call_prom_ret("call-method", 3, 2, &ret, 881 if (call_prom_ret("call-method", 3, 2, &ret,