]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ppc64: restore smt-enabled=off kernel command line option
authorAnton Blanchard <anton@samba.org>
Tue, 14 Sep 2004 00:42:54 +0000 (17:42 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 14 Sep 2004 00:42:54 +0000 (17:42 -0700)
Restore the smt-enabled=off kernel command line functionality:

- Remove the SMT_DYNAMIC state now that smt_snooze_delay allows for the
  same thing.
- Remove the early prom.c parsing for the option, put it into an
  early_param instead.
- In setup_cpu_maps honour the smt-enabled setting

Note to Nathan: In order to allow cpu hotplug add of secondary threads after
booting with smt-enabled=off, I had to initialise cpu_present_map to
cpu_online_map in smp_cpus_done.  Im not sure how you want to handle this but
it seems our present map currently does not allow cpus to be added into the
partition that werent there at boot (but were in the possible map).

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/ppc64/kernel/idle.c
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/setup.c
arch/ppc64/kernel/smp.c
include/asm-ppc64/memory.h
include/asm-ppc64/naca.h
include/asm-ppc64/smp.h

index 8ea8351313bd9d4d7c6be45281c69900f232c0a9..4d191a28657c9622de08a64ccb433cafea9afe83 100644 (file)
@@ -197,12 +197,7 @@ int dedicated_idle(void)
 
                                HMT_very_low(); /* Low power mode */
 
-                               /* If the SMT mode is system controlled & the 
-                                * partner thread is doing work, switch into
-                                * ST mode.
-                                */
-                               if((naca->smt_state == SMT_DYNAMIC) &&
-                                  (!(ppaca->lppaca.xIdle))) {
+                               if (!(ppaca->lppaca.xIdle)) {
                                        /* Indicate we are no longer polling for
                                         * work, and then clear need_resched.  If
                                         * need_resched was 1, set it back to 1
index a7097b592fdee3274576421f63a1c77197f6031d..4345f3d6a3d34748cd9fc55144ef9839019f9d75 100644 (file)
@@ -918,11 +918,7 @@ static void __init prom_hold_cpus(unsigned long mem)
                = (void *)virt_to_abs(&__secondary_hold_acknowledge);
        unsigned long secondary_hold
                = virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
-       struct systemcfg *_systemcfg = RELOC(systemcfg);
        struct prom_t *_prom = PTRRELOC(&prom);
-#ifdef CONFIG_SMP
-       struct naca_struct *_naca = RELOC(naca);
-#endif
 
        prom_debug("prom_hold_cpus: start...\n");
        prom_debug("    1) spinloop       = 0x%x\n", (unsigned long)spinloop);
@@ -1003,18 +999,18 @@ static void __init prom_hold_cpus(unsigned long mem)
                              (*acknowledge == ((unsigned long)-1)); i++ ) ;
 
                        if (*acknowledge == cpuid) {
-                               prom_printf("... done\n");
+                               prom_printf(" done\n");
                                /* We have to get every CPU out of OF,
                                 * even if we never start it. */
                                if (cpuid >= NR_CPUS)
                                        goto next;
                        } else {
-                               prom_printf("... failed: %x\n", *acknowledge);
+                               prom_printf(" failed: %x\n", *acknowledge);
                        }
                }
 #ifdef CONFIG_SMP
                else
-                       prom_printf("%x : booting  cpu %s\n", cpuid, path);
+                       prom_printf("%x : boot cpu     %s\n", cpuid, path);
 #endif
 next:
 #ifdef CONFIG_SMP
@@ -1023,13 +1019,6 @@ next:
                        cpuid++;
                        if (cpuid >= NR_CPUS)
                                continue;
-                       prom_printf("%x : preparing thread ... ",
-                                   interrupt_server[i]);
-                       if (_naca->smt_state) {
-                               prom_printf("available\n");
-                       } else {
-                               prom_printf("not available\n");
-                       }
                }
 #endif
                cpuid++;
@@ -1068,57 +1057,6 @@ next:
        prom_debug("prom_hold_cpus: end...\n");
 }
 
-static void __init smt_setup(void)
-{
-       char *p, *q;
-       char my_smt_enabled = SMT_DYNAMIC;
-       ihandle prom_options = 0;
-       char option[9];
-       unsigned long offset = reloc_offset();
-       struct naca_struct *_naca = RELOC(naca);
-       char found = 0;
-
-       if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) {
-               for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) {
-                       q = p + 12;
-                       if (p > RELOC(cmd_line) && p[-1] != ' ')
-                               continue;
-                       found = 1;
-                       if (q[0] == 'o' && q[1] == 'f' && 
-                           q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) {
-                               my_smt_enabled = SMT_OFF;
-                       } else if (q[0]=='o' && q[1] == 'n' && 
-                                  (q[2] == ' ' || q[2] == '\0')) {
-                               my_smt_enabled = SMT_ON;
-                       } else {
-                               my_smt_enabled = SMT_DYNAMIC;
-                       } 
-               }
-       }
-       if (!found) {
-               prom_options = call_prom("finddevice", 1, 1, ADDR("/options"));
-               if (prom_options != (ihandle) -1) {
-                       prom_getprop(prom_options, "ibm,smt-enabled",
-                                    option, sizeof(option));
-                       if (option[0] != 0) {
-                               found = 1;
-                               if (!strcmp(option, RELOC("off")))
-                                       my_smt_enabled = SMT_OFF;
-                               else if (!strcmp(option, RELOC("on")))
-                                       my_smt_enabled = SMT_ON;
-                               else
-                                       my_smt_enabled = SMT_DYNAMIC;
-                       }
-               }
-       }
-
-       if (!found )
-               my_smt_enabled = SMT_DYNAMIC; /* default to on */
-
-       _naca->smt_state = my_smt_enabled;
-}
-
-
 #ifdef CONFIG_BOOTX_TEXT
 
 /* This function will enable the early boot text when doing OF booting. This
@@ -1730,8 +1668,6 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
        /* Initialize some system info into the Naca early... */
        prom_initialize_naca();
 
-       smt_setup();
-
        /* If we are on an SMP machine, then we *MUST* do the
         * following, regardless of whether we have an SMP
         * kernel or not.
index 509bbbc6b202e51ad062b65f8d8988a08c318136..e84f42a750ef315602b74cb0d7a717166c2cf13f 100644 (file)
@@ -152,6 +152,50 @@ void __init disable_early_printk(void)
 }
 
 #if !defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
+
+static int smt_enabled_cmdline;
+
+/* Look for ibm,smt-enabled OF option */
+static void check_smt_enabled(void)
+{
+       struct device_node *dn;
+       char *smt_option;
+
+       /* Allow the command line to overrule the OF option */
+       if (smt_enabled_cmdline)
+               return;
+
+       dn = of_find_node_by_path("/options");
+
+       if (dn) {
+               smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL);
+
+                if (smt_option) {
+                       if (!strcmp(smt_option, "on"))
+                               smt_enabled_at_boot = 1;
+                       else if (!strcmp(smt_option, "off"))
+                               smt_enabled_at_boot = 0;
+                }
+        }
+}
+
+/* Look for smt-enabled= cmdline option */
+static int __init early_smt_enabled(char *p)
+{
+       smt_enabled_cmdline = 1;
+
+       if (!p)
+               return 0;
+
+       if (!strcmp(p, "on") || !strcmp(p, "1"))
+               smt_enabled_at_boot = 1;
+       else if (!strcmp(p, "off") || !strcmp(p, "0"))
+               smt_enabled_at_boot = 0;
+
+       return 0;
+}
+early_param("smt-enabled", early_smt_enabled);
+
 /**
  * setup_cpu_maps - initialize the following cpu maps:
  *                  cpu_possible_map
@@ -174,6 +218,8 @@ static void __init setup_cpu_maps(void)
        struct device_node *dn = NULL;
        int cpu = 0;
 
+       check_smt_enabled();
+
        while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
                u32 *intserv;
                int j, len = sizeof(u32), nthreads;
@@ -186,9 +232,16 @@ static void __init setup_cpu_maps(void)
                nthreads = len / sizeof(u32);
 
                for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
+                       /*
+                        * Only spin up secondary threads if SMT is enabled.
+                        * We must leave space in the logical map for the
+                        * threads.
+                        */
+                       if (j == 0 || smt_enabled_at_boot) {
+                               cpu_set(cpu, cpu_present_map);
+                               set_hard_smp_processor_id(cpu, intserv[j]);
+                       }
                        cpu_set(cpu, cpu_possible_map);
-                       cpu_set(cpu, cpu_present_map);
-                       set_hard_smp_processor_id(cpu, intserv[j]);
                        cpu++;
                }
        }
index 7321d27905d5ca1548b9643769f7aea3370afd3e..d627b2bbfc4463dc2e477605fd93efdb4982275b 100644 (file)
@@ -74,6 +74,8 @@ void smp_call_function_interrupt(void);
 extern long register_vpa(unsigned long flags, unsigned long proc,
                         unsigned long vpa);
 
+int smt_enabled_at_boot = 1;
+
 /* Low level assembly function used to backup CPU 0 state */
 extern void __save_cpu_setup(void);
 
@@ -942,4 +944,12 @@ void __init smp_cpus_done(unsigned int max_cpus)
        smp_threads_ready = 1;
 
        set_cpus_allowed(current, old_mask);
+
+       /*
+        * We know at boot the maximum number of cpus we can add to
+        * a partition and set cpu_possible_map accordingly. cpu_present_map
+        * needs to match for the hotplug code to allow us to hot add
+        * any offline cpus.
+        */
+       cpu_present_map = cpu_possible_map;
 }
index 40c4a6e4a8fc8be7af120d379da885e883f675a3..56e09face9a8409e03230d7618b0fd8038eebc1e 100644 (file)
@@ -56,14 +56,4 @@ static inline void isync(void)
 #define HMT_MEDIUM_HIGH "\tor   5,5,5           # medium high priority\n"
 #define HMT_HIGH       "\tor   3,3,3           # high priority\n"
 
-/* 
- * Various operational modes for SMT
- * Off    : never run threaded
- * On     : always run threaded
- * Dynamic: Allow the system to switch modes as needed
- */
-#define SMT_OFF      0
-#define SMT_ON       1
-#define SMT_DYNAMIC  2
-
 #endif
index 3c0b8d3a526271eba639c2522e80149621112183..04541849f8b4a8627400d7bb77a2793601e5ed83 100644 (file)
@@ -37,9 +37,6 @@ struct naca_struct {
        u32 dCacheL1LinesPerPage;       /* L1 d-cache lines / page   0x64 */
        u32 iCacheL1LogLineSize;        /* L1 i-cache line size Log2 0x68 */
        u32 iCacheL1LinesPerPage;       /* L1 i-cache lines / page   0x6c */
-       u8  smt_state;                  /* 0 = SMT off               0x70 */
-                                       /* 1 = SMT on                     */
-                                       /* 2 = SMT dynamic                */
        u8  resv0[15];                  /* Reserved           0x71 - 0x7F */
 };
 
index cac758f686e4b2371921a6841a76780228320a96..ff7685a339170520914e86566d52572ae53df669 100644 (file)
@@ -65,6 +65,8 @@ extern int query_cpu_stopped(unsigned int pcpu);
 #define set_hard_smp_processor_id(CPU, VAL) \
        do { (paca[(CPU)].hw_cpu_id = (VAL)); } while (0)
 
+extern int smt_enabled_at_boot;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* !(_PPC64_SMP_H) */