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
= (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);
(*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
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++;
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
/* 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.
}
#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
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;
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++;
}
}
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);
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;
}
#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
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 */
};
#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) */