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