1 #include <linux/sysdev.h> 2 #include <linux/cpu.h> 3 #include <linux/smp.h> 4 #include <linux/percpu.h> 5 #include <linux/init.h> 6 #include <linux/sched.h> 7 #include <linux/module.h> 8 #include <linux/nodemask.h> 9 #include <linux/cpumask.h> 10 #include <linux/notifier.h> 11 12 #include <asm/current.h> 13 #include <asm/processor.h> 14 #include <asm/cputable.h> 15 #include <asm/firmware.h> 16 #include <asm/hvcall.h> 17 #include <asm/prom.h> 18 #include <asm/paca.h> 19 #include <asm/lppaca.h> 20 #include <asm/machdep.h> 21 #include <asm/smp.h> 22 23 static DEFINE_PER_CPU(struct cpu, cpu_devices); 24 25 /* SMT stuff */ 26 27 #ifdef CONFIG_PPC_MULTIPLATFORM 28 /* default to snooze disabled */ 29 DEFINE_PER_CPU(unsigned long, smt_snooze_delay); 30 31 static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf, 32 size_t count) 33 { 34 struct cpu *cpu = container_of(dev, struct cpu, sysdev); 35 ssize_t ret; 36 unsigned long snooze; 37 38 ret = sscanf(buf, "%lu", &snooze); 39 if (ret != 1) 40 return -EINVAL; 41 42 per_cpu(smt_snooze_delay, cpu->sysdev.id) = snooze; 43 44 return count; 45 } 46 47 static ssize_t show_smt_snooze_delay(struct sys_device *dev, char *buf) 48 { 49 struct cpu *cpu = container_of(dev, struct cpu, sysdev); 50 51 return sprintf(buf, "%lu\n", per_cpu(smt_snooze_delay, cpu->sysdev.id)); 52 } 53 54 static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, 55 store_smt_snooze_delay); 56 57 /* Only parse OF options if the matching cmdline option was not specified */ 58 static int smt_snooze_cmdline; 59 60 static int __init smt_setup(void) 61 { 62 struct device_node *options; 63 const unsigned int *val; 64 unsigned int cpu; 65 66 if (!cpu_has_feature(CPU_FTR_SMT)) 67 return -ENODEV; 68 69 options = find_path_device("/options"); 70 if (!options) 71 return -ENODEV; 72 73 val = get_property(options, "ibm,smt-snooze-delay", NULL); 74 if (!smt_snooze_cmdline && val) { 75 for_each_possible_cpu(cpu) 76 per_cpu(smt_snooze_delay, cpu) = *val; 77 } 78 79 return 0; 80 } 81 __initcall(smt_setup); 82 83 static int __init setup_smt_snooze_delay(char *str) 84 { 85 unsigned int cpu; 86 int snooze; 87 88 if (!cpu_has_feature(CPU_FTR_SMT)) 89 return 1; 90 91 smt_snooze_cmdline = 1; 92 93 if (get_option(&str, &snooze)) { 94 for_each_possible_cpu(cpu) 95 per_cpu(smt_snooze_delay, cpu) = snooze; 96 } 97 98 return 1; 99 } 100 __setup("smt-snooze-delay=", setup_smt_snooze_delay); 101 102 #endif /* CONFIG_PPC_MULTIPLATFORM */ 103 104 /* 105 * Enabling PMCs will slow partition context switch times so we only do 106 * it the first time we write to the PMCs. 107 */ 108 109 static DEFINE_PER_CPU(char, pmcs_enabled); 110 111 void ppc64_enable_pmcs(void) 112 { 113 /* Only need to enable them once */ 114 if (__get_cpu_var(pmcs_enabled)) 115 return; 116 117 __get_cpu_var(pmcs_enabled) = 1; 118 119 if (ppc_md.enable_pmcs) 120 ppc_md.enable_pmcs(); 121 } 122 EXPORT_SYMBOL(ppc64_enable_pmcs); 123 124 /* XXX convert to rusty's on_one_cpu */ 125 static unsigned long run_on_cpu(unsigned long cpu, 126 unsigned long (*func)(unsigned long), 127 unsigned long arg) 128 { 129 cpumask_t old_affinity = current->cpus_allowed; 130 unsigned long ret; 131 132 /* should return -EINVAL to userspace */ 133 if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) 134 return 0; 135 136 ret = func(arg); 137 138 set_cpus_allowed(current, old_affinity); 139 140 return ret; 141 } 142 143 #define SYSFS_PMCSETUP(NAME, ADDRESS) \ 144 static unsigned long read_##NAME(unsigned long junk) \ 145 { \ 146 return mfspr(ADDRESS); \ 147 } \ 148 static unsigned long write_##NAME(unsigned long val) \ 149 { \ 150 ppc64_enable_pmcs(); \ 151 mtspr(ADDRESS, val); \ 152 return 0; \ 153 } \ 154 static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ 155 { \ 156 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ 157 unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ 158 return sprintf(buf, "%lx\n", val); \ 159 } \ 160 static ssize_t __attribute_used__ \ 161 store_##NAME(struct sys_device *dev, const char *buf, size_t count) \ 162 { \ 163 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ 164 unsigned long val; \ 165 int ret = sscanf(buf, "%lx", &val); \ 166 if (ret != 1) \ 167 return -EINVAL; \ 168 run_on_cpu(cpu->sysdev.id, write_##NAME, val); \ 169 return count; \ 170 } 171 172 SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); 173 SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); 174 SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); 175 SYSFS_PMCSETUP(pmc1, SPRN_PMC1); 176 SYSFS_PMCSETUP(pmc2, SPRN_PMC2); 177 SYSFS_PMCSETUP(pmc3, SPRN_PMC3); 178 SYSFS_PMCSETUP(pmc4, SPRN_PMC4); 179 SYSFS_PMCSETUP(pmc5, SPRN_PMC5); 180 SYSFS_PMCSETUP(pmc6, SPRN_PMC6); 181 SYSFS_PMCSETUP(pmc7, SPRN_PMC7); 182 SYSFS_PMCSETUP(pmc8, SPRN_PMC8); 183 SYSFS_PMCSETUP(purr, SPRN_PURR); 184 185 static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); 186 static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); 187 static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); 188 static SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1); 189 static SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2); 190 static SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3); 191 static SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4); 192 static SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5); 193 static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6); 194 static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); 195 static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); 196 static SYSDEV_ATTR(purr, 0600, show_purr, NULL); 197 198 static void register_cpu_online(unsigned int cpu) 199 { 200 struct cpu *c = &per_cpu(cpu_devices, cpu); 201 struct sys_device *s = &c->sysdev; 202 203 #ifndef CONFIG_PPC_ISERIES 204 if (cpu_has_feature(CPU_FTR_SMT)) 205 sysdev_create_file(s, &attr_smt_snooze_delay); 206 #endif 207 208 /* PMC stuff */ 209 210 sysdev_create_file(s, &attr_mmcr0); 211 sysdev_create_file(s, &attr_mmcr1); 212 213 if (cpu_has_feature(CPU_FTR_MMCRA)) 214 sysdev_create_file(s, &attr_mmcra); 215 216 if (cur_cpu_spec->num_pmcs >= 1) 217 sysdev_create_file(s, &attr_pmc1); 218 if (cur_cpu_spec->num_pmcs >= 2) 219 sysdev_create_file(s, &attr_pmc2); 220 if (cur_cpu_spec->num_pmcs >= 3) 221 sysdev_create_file(s, &attr_pmc3); 222 if (cur_cpu_spec->num_pmcs >= 4) 223 sysdev_create_file(s, &attr_pmc4); 224 if (cur_cpu_spec->num_pmcs >= 5) 225 sysdev_create_file(s, &attr_pmc5); 226 if (cur_cpu_spec->num_pmcs >= 6) 227 sysdev_create_file(s, &attr_pmc6); 228 if (cur_cpu_spec->num_pmcs >= 7) 229 sysdev_create_file(s, &attr_pmc7); 230 if (cur_cpu_spec->num_pmcs >= 8) 231 sysdev_create_file(s, &attr_pmc8); 232 233 if (cpu_has_feature(CPU_FTR_PURR)) 234 sysdev_create_file(s, &attr_purr); 235 } 236 237 #ifdef CONFIG_HOTPLUG_CPU 238 static void unregister_cpu_online(unsigned int cpu) 239 { 240 struct cpu *c = &per_cpu(cpu_devices, cpu); 241 struct sys_device *s = &c->sysdev; 242 243 BUG_ON(c->no_control); 244 245 #ifndef CONFIG_PPC_ISERIES 246 if (cpu_has_feature(CPU_FTR_SMT)) 247 sysdev_remove_file(s, &attr_smt_snooze_delay); 248 #endif 249 250 /* PMC stuff */ 251 252 sysdev_remove_file(s, &attr_mmcr0); 253 sysdev_remove_file(s, &attr_mmcr1); 254 255 if (cpu_has_feature(CPU_FTR_MMCRA)) 256 sysdev_remove_file(s, &attr_mmcra); 257 258 if (cur_cpu_spec->num_pmcs >= 1) 259 sysdev_remove_file(s, &attr_pmc1); 260 if (cur_cpu_spec->num_pmcs >= 2) 261 sysdev_remove_file(s, &attr_pmc2); 262 if (cur_cpu_spec->num_pmcs >= 3) 263 sysdev_remove_file(s, &attr_pmc3); 264 if (cur_cpu_spec->num_pmcs >= 4) 265 sysdev_remove_file(s, &attr_pmc4); 266 if (cur_cpu_spec->num_pmcs >= 5) 267 sysdev_remove_file(s, &attr_pmc5); 268 if (cur_cpu_spec->num_pmcs >= 6) 269 sysdev_remove_file(s, &attr_pmc6); 270 if (cur_cpu_spec->num_pmcs >= 7) 271 sysdev_remove_file(s, &attr_pmc7); 272 if (cur_cpu_spec->num_pmcs >= 8) 273 sysdev_remove_file(s, &attr_pmc8); 274 275 if (cpu_has_feature(CPU_FTR_PURR)) 276 sysdev_remove_file(s, &attr_purr); 277 } 278 #endif /* CONFIG_HOTPLUG_CPU */ 279 280 static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, 281 unsigned long action, void *hcpu) 282 { 283 unsigned int cpu = (unsigned int)(long)hcpu; 284 285 switch (action) { 286 case CPU_ONLINE: 287 register_cpu_online(cpu); 288 break; 289 #ifdef CONFIG_HOTPLUG_CPU 290 case CPU_DEAD: 291 unregister_cpu_online(cpu); 292 break; 293 #endif 294 } 295 return NOTIFY_OK; 296 } 297 298 static struct notifier_block __cpuinitdata sysfs_cpu_nb = { 299 .notifier_call = sysfs_cpu_notify, 300 }; 301 302 /* NUMA stuff */ 303 304 #ifdef CONFIG_NUMA 305 static void register_nodes(void) 306 { 307 int i; 308 309 for (i = 0; i < MAX_NUMNODES; i++) 310 register_one_node(i); 311 } 312 313 int sysfs_add_device_to_node(struct sys_device *dev, int nid) 314 { 315 struct node *node = &node_devices[nid]; 316 return sysfs_create_link(&node->sysdev.kobj, &dev->kobj, 317 kobject_name(&dev->kobj)); 318 } 319 320 void sysfs_remove_device_from_node(struct sys_device *dev, int nid) 321 { 322 struct node *node = &node_devices[nid]; 323 sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj)); 324 } 325 326 #else 327 static void register_nodes(void) 328 { 329 return; 330 } 331 332 #endif 333 334 EXPORT_SYMBOL_GPL(sysfs_add_device_to_node); 335 EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node); 336 337 /* Only valid if CPU is present. */ 338 static ssize_t show_physical_id(struct sys_device *dev, char *buf) 339 { 340 struct cpu *cpu = container_of(dev, struct cpu, sysdev); 341 342 return sprintf(buf, "%d\n", get_hard_smp_processor_id(cpu->sysdev.id)); 343 } 344 static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL); 345 346 static int __init topology_init(void) 347 { 348 int cpu; 349 350 register_nodes(); 351 register_cpu_notifier(&sysfs_cpu_nb); 352 353 for_each_possible_cpu(cpu) { 354 struct cpu *c = &per_cpu(cpu_devices, cpu); 355 356 /* 357 * For now, we just see if the system supports making 358 * the RTAS calls for CPU hotplug. But, there may be a 359 * more comprehensive way to do this for an individual 360 * CPU. For instance, the boot cpu might never be valid 361 * for hotplugging. 362 */ 363 if (!ppc_md.cpu_die) 364 c->no_control = 1; 365 366 if (cpu_online(cpu) || (c->no_control == 0)) { 367 register_cpu(c, cpu); 368 369 sysdev_create_file(&c->sysdev, &attr_physical_id); 370 } 371 372 if (cpu_online(cpu)) 373 register_cpu_online(cpu); 374 } 375 376 return 0; 377 } 378 __initcall(topology_init); 379