diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-04-11 22:49:59 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-04-11 22:49:59 -0700 |
| commit | b7ceb1452399ef59ab14868337d2d74a9b5c4c8d (patch) | |
| tree | 0e3e0fd85a82b8daea774741a30e69e450f30ed2 | |
| parent | c3a85f1fb88cfa30ab4af65348eaf4290233cac8 (diff) | |
[PATCH] ppc64: Add smt_snooze_delay cpu sysfs attribute
From: Anton Blanchard <anton@samba.org>
Add smt_snooze_delay cpu sysfs attribute
| -rw-r--r-- | arch/ppc64/kernel/idle.c | 7 | ||||
| -rw-r--r-- | arch/ppc64/kernel/prom.c | 46 | ||||
| -rw-r--r-- | arch/ppc64/kernel/sysfs.c | 89 | ||||
| -rw-r--r-- | include/asm-ppc64/naca.h | 6 |
4 files changed, 95 insertions, 53 deletions
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index b30aea273974..a9a501df397c 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -161,13 +161,14 @@ int default_idle(void) #ifdef CONFIG_PPC_PSERIES -DECLARE_PER_CPU(smt_snooze_delay); +DECLARE_PER_CPU(unsigned long, smt_snooze_delay); int dedicated_idle(void) { long oldval; struct paca_struct *lpaca = get_paca(), *ppaca; unsigned long start_snooze; + unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); ppaca = &paca[smp_processor_id() ^ 1]; @@ -180,14 +181,14 @@ int dedicated_idle(void) if (!oldval) { set_thread_flag(TIF_POLLING_NRFLAG); start_snooze = __get_tb() + - naca->smt_snooze_delay*tb_ticks_per_usec; + *smt_snooze_delay * tb_ticks_per_usec; while (!need_resched()) { /* need_resched could be 1 or 0 at this * point. If it is 0, set it to 0, so * an IPI/Prod is sent. If it is 1, keep * it that way & schedule work. */ - if (naca->smt_snooze_delay == 0 || + if (*smt_snooze_delay == 0 || __get_tb() < start_snooze) { HMT_low(); /* Low thread priority */ continue; diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index f1cfd43dd39c..6748b2244e88 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -1254,7 +1254,6 @@ smt_setup(void) { char *p, *q; char my_smt_enabled = SMT_DYNAMIC; - unsigned long my_smt_snooze_delay; ihandle prom_options = NULL; char option[9]; unsigned long offset = reloc_offset(); @@ -1301,51 +1300,6 @@ smt_setup(void) if (!found ) my_smt_enabled = SMT_DYNAMIC; /* default to on */ - found = 0; - if (my_smt_enabled) { - if (strstr(RELOC(cmd_line), RELOC("smt-snooze-delay="))) { - for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-snooze-delay="))) != 0; ) { - q = p + 17; - if (p > RELOC(cmd_line) && p[-1] != ' ') - continue; - found = 1; - /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ - my_smt_snooze_delay = 0; - while (*q >= '0' && *q <= '9') { - my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; - q++; - } - } - } - - if (!found) { - prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); - if (prom_options != (ihandle) -1) { - call_prom(RELOC("getprop"), - 4, 1, prom_options, - RELOC("ibm,smt-snooze-delay"), - option, - sizeof(option)); - if (option[0] != 0) { - found = 1; - /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ - my_smt_snooze_delay = 0; - q = option; - while (*q >= '0' && *q <= '9') { - my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; - q++; - } - } - } - } - - if (!found) { - my_smt_snooze_delay = 0; /* default value */ - } - } else { - my_smt_snooze_delay = 0; /* default value */ - } - _naca->smt_snooze_delay = my_smt_snooze_delay; _naca->smt_state = my_smt_enabled; } diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index 05ef5291a737..3bcbdec74195 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c @@ -9,6 +9,90 @@ #include <asm/processor.h> #include <asm/cputable.h> #include <asm/hvcall.h> +#include <asm/prom.h> + + +/* SMT stuff */ + +#ifndef CONFIG_PPC_ISERIES + +/* default to snooze disabled */ +DEFINE_PER_CPU(unsigned long, smt_snooze_delay); + +static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf, + size_t count) +{ + struct cpu *cpu = container_of(dev, struct cpu, sysdev); + ssize_t ret; + unsigned long snooze; + + ret = sscanf(buf, "%lu", &snooze); + if (ret != 1) + return -EINVAL; + + per_cpu(smt_snooze_delay, cpu->sysdev.id) = snooze; + + return count; +} + +static ssize_t show_smt_snooze_delay(struct sys_device *dev, char *buf) +{ + struct cpu *cpu = container_of(dev, struct cpu, sysdev); + + return sprintf(buf, "%lu\n", per_cpu(smt_snooze_delay, cpu->sysdev.id)); +} + +static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, + store_smt_snooze_delay); + +/* Only parse OF options if the matching cmdline option was not specified */ +static int smt_snooze_cmdline; + +static int __init smt_setup(void) +{ + struct device_node *options; + unsigned int *val; + unsigned int cpu; + + if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + return 1; + + options = find_path_device("/options"); + if (!options) + return 1; + + val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", + NULL); + if (!smt_snooze_cmdline && val) { + for_each_cpu(cpu) + per_cpu(smt_snooze_delay, cpu) = *val; + } + + return 1; +} +__initcall(smt_setup); + +static int __init setup_smt_snooze_delay(char *str) +{ + unsigned int cpu; + int snooze; + + if (!cur_cpu_spec->cpu_features & CPU_FTR_SMT) + return 1; + + smt_snooze_cmdline = 1; + + if (get_option(&str, &snooze)) { + for_each_cpu(cpu) + per_cpu(smt_snooze_delay, cpu) = snooze; + } + + return 1; +} +__setup("smt-snooze-delay=", setup_smt_snooze_delay); + +#endif + /* PMC stuff */ @@ -235,6 +319,11 @@ static int __init topology_init(void) register_cpu_pmc(&c->sysdev); sysdev_create_file(&c->sysdev, &attr_physical_id); + +#ifndef CONFIG_PPC_ISERIES + if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) + sysdev_create_file(&c->sysdev, &attr_smt_snooze_delay); +#endif } return 0; diff --git a/include/asm-ppc64/naca.h b/include/asm-ppc64/naca.h index b93cdf160dd3..a50189402420 100644 --- a/include/asm-ppc64/naca.h +++ b/include/asm-ppc64/naca.h @@ -37,12 +37,10 @@ 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 */ - u64 smt_snooze_delay; /* Delay (in usec) before 0x70 */ - /* entering ST mode */ - u8 smt_state; /* 0 = SMT off 0x78 */ + u8 smt_state; /* 0 = SMT off 0x70 */ /* 1 = SMT on */ /* 2 = SMT dynamic */ - u8 resv0[7]; /* Reserved 0x70 - 0x7F */ + u8 resv0[15]; /* Reserved 0x71 - 0x7F */ }; extern struct naca_struct *naca; |
