1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * This file contains NUMA specific variables and functions which can 7 * be split away from DISCONTIGMEM and are used on NUMA machines with 8 * contiguous memory. 9 * 2002/08/07 Erich Focht <efocht@ess.nec.de> 10 * Populate cpu entries in sysfs for non-numa systems as well 11 * Intel Corporation - Ashok Raj 12 * 02/27/2006 Zhang, Yanmin 13 * Populate cpu cache entries in sysfs for cpu cache info 14 */ 15 16 #include <linux/cpu.h> 17 #include <linux/kernel.h> 18 #include <linux/mm.h> 19 #include <linux/node.h> 20 #include <linux/slab.h> 21 #include <linux/init.h> 22 #include <linux/bootmem.h> 23 #include <linux/nodemask.h> 24 #include <linux/notifier.h> 25 #include <linux/export.h> 26 #include <asm/mmzone.h> 27 #include <asm/numa.h> 28 #include <asm/cpu.h> 29 30 static struct ia64_cpu *sysfs_cpus; 31 32 void arch_fix_phys_package_id(int num, u32 slot) 33 { 34 #ifdef CONFIG_SMP 35 if (cpu_data(num)->socket_id == -1) 36 cpu_data(num)->socket_id = slot; 37 #endif 38 } 39 EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); 40 41 42 #ifdef CONFIG_HOTPLUG_CPU 43 int __ref arch_register_cpu(int num) 44 { 45 #ifdef CONFIG_ACPI 46 /* 47 * If CPEI can be re-targeted or if this is not 48 * CPEI target, then it is hotpluggable 49 */ 50 if (can_cpei_retarget() || !is_cpu_cpei_target(num)) 51 sysfs_cpus[num].cpu.hotpluggable = 1; 52 map_cpu_to_node(num, node_cpuid[num].nid); 53 #endif 54 return register_cpu(&sysfs_cpus[num].cpu, num); 55 } 56 EXPORT_SYMBOL(arch_register_cpu); 57 58 void __ref arch_unregister_cpu(int num) 59 { 60 unregister_cpu(&sysfs_cpus[num].cpu); 61 #ifdef CONFIG_ACPI 62 unmap_cpu_from_node(num, cpu_to_node(num)); 63 #endif 64 } 65 EXPORT_SYMBOL(arch_unregister_cpu); 66 #else 67 static int __init arch_register_cpu(int num) 68 { 69 return register_cpu(&sysfs_cpus[num].cpu, num); 70 } 71 #endif /*CONFIG_HOTPLUG_CPU*/ 72 73 74 static int __init topology_init(void) 75 { 76 int i, err = 0; 77 78 #ifdef CONFIG_NUMA 79 /* 80 * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? 81 */ 82 for_each_online_node(i) { 83 if ((err = register_one_node(i))) 84 goto out; 85 } 86 #endif 87 88 sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL); 89 if (!sysfs_cpus) 90 panic("kzalloc in topology_init failed - NR_CPUS too big?"); 91 92 for_each_present_cpu(i) { 93 if((err = arch_register_cpu(i))) 94 goto out; 95 } 96 out: 97 return err; 98 } 99 100 subsys_initcall(topology_init); 101 102 103 /* 104 * Export cpu cache information through sysfs 105 */ 106 107 /* 108 * A bunch of string array to get pretty printing 109 */ 110 static const char *cache_types[] = { 111 "", /* not used */ 112 "Instruction", 113 "Data", 114 "Unified" /* unified */ 115 }; 116 117 static const char *cache_mattrib[]={ 118 "WriteThrough", 119 "WriteBack", 120 "", /* reserved */ 121 "" /* reserved */ 122 }; 123 124 struct cache_info { 125 pal_cache_config_info_t cci; 126 cpumask_t shared_cpu_map; 127 int level; 128 int type; 129 struct kobject kobj; 130 }; 131 132 struct cpu_cache_info { 133 struct cache_info *cache_leaves; 134 int num_cache_leaves; 135 struct kobject kobj; 136 }; 137 138 static struct cpu_cache_info all_cpu_cache_info[NR_CPUS] __cpuinitdata; 139 #define LEAF_KOBJECT_PTR(x,y) (&all_cpu_cache_info[x].cache_leaves[y]) 140 141 #ifdef CONFIG_SMP 142 static void __cpuinit cache_shared_cpu_map_setup( unsigned int cpu, 143 struct cache_info * this_leaf) 144 { 145 pal_cache_shared_info_t csi; 146 int num_shared, i = 0; 147 unsigned int j; 148 149 if (cpu_data(cpu)->threads_per_core <= 1 && 150 cpu_data(cpu)->cores_per_socket <= 1) { 151 cpu_set(cpu, this_leaf->shared_cpu_map); 152 return; 153 } 154 155 if (ia64_pal_cache_shared_info(this_leaf->level, 156 this_leaf->type, 157 0, 158 &csi) != PAL_STATUS_SUCCESS) 159 return; 160 161 num_shared = (int) csi.num_shared; 162 do { 163 for_each_possible_cpu(j) 164 if (cpu_data(cpu)->socket_id == cpu_data(j)->socket_id 165 && cpu_data(j)->core_id == csi.log1_cid 166 && cpu_data(j)->thread_id == csi.log1_tid) 167 cpu_set(j, this_leaf->shared_cpu_map); 168 169 i++; 170 } while (i < num_shared && 171 ia64_pal_cache_shared_info(this_leaf->level, 172 this_leaf->type, 173 i, 174 &csi) == PAL_STATUS_SUCCESS); 175 } 176 #else 177 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, 178 struct cache_info * this_leaf) 179 { 180 cpu_set(cpu, this_leaf->shared_cpu_map); 181 return; 182 } 183 #endif 184 185 static ssize_t show_coherency_line_size(struct cache_info *this_leaf, 186 char *buf) 187 { 188 return sprintf(buf, "%u\n", 1 << this_leaf->cci.pcci_line_size); 189 } 190 191 static ssize_t show_ways_of_associativity(struct cache_info *this_leaf, 192 char *buf) 193 { 194 return sprintf(buf, "%u\n", this_leaf->cci.pcci_assoc); 195 } 196 197 static ssize_t show_attributes(struct cache_info *this_leaf, char *buf) 198 { 199 return sprintf(buf, 200 "%s\n", 201 cache_mattrib[this_leaf->cci.pcci_cache_attr]); 202 } 203 204 static ssize_t show_size(struct cache_info *this_leaf, char *buf) 205 { 206 return sprintf(buf, "%uK\n", this_leaf->cci.pcci_cache_size / 1024); 207 } 208 209 static ssize_t show_number_of_sets(struct cache_info *this_leaf, char *buf) 210 { 211 unsigned number_of_sets = this_leaf->cci.pcci_cache_size; 212 number_of_sets /= this_leaf->cci.pcci_assoc; 213 number_of_sets /= 1 << this_leaf->cci.pcci_line_size; 214 215 return sprintf(buf, "%u\n", number_of_sets); 216 } 217 218 static ssize_t show_shared_cpu_map(struct cache_info *this_leaf, char *buf) 219 { 220 ssize_t len; 221 cpumask_t shared_cpu_map; 222 223 cpumask_and(&shared_cpu_map, 224 &this_leaf->shared_cpu_map, cpu_online_mask); 225 len = cpumask_scnprintf(buf, NR_CPUS+1, &shared_cpu_map); 226 len += sprintf(buf+len, "\n"); 227 return len; 228 } 229 230 static ssize_t show_type(struct cache_info *this_leaf, char *buf) 231 { 232 int type = this_leaf->type + this_leaf->cci.pcci_unified; 233 return sprintf(buf, "%s\n", cache_types[type]); 234 } 235 236 static ssize_t show_level(struct cache_info *this_leaf, char *buf) 237 { 238 return sprintf(buf, "%u\n", this_leaf->level); 239 } 240 241 struct cache_attr { 242 struct attribute attr; 243 ssize_t (*show)(struct cache_info *, char *); 244 ssize_t (*store)(struct cache_info *, const char *, size_t count); 245 }; 246 247 #ifdef define_one_ro 248 #undef define_one_ro 249 #endif 250 #define define_one_ro(_name) \ 251 static struct cache_attr _name = \ 252 __ATTR(_name, 0444, show_##_name, NULL) 253 254 define_one_ro(level); 255 define_one_ro(type); 256 define_one_ro(coherency_line_size); 257 define_one_ro(ways_of_associativity); 258 define_one_ro(size); 259 define_one_ro(number_of_sets); 260 define_one_ro(shared_cpu_map); 261 define_one_ro(attributes); 262 263 static struct attribute * cache_default_attrs[] = { 264 &type.attr, 265 &level.attr, 266 &coherency_line_size.attr, 267 &ways_of_associativity.attr, 268 &attributes.attr, 269 &size.attr, 270 &number_of_sets.attr, 271 &shared_cpu_map.attr, 272 NULL 273 }; 274 275 #define to_object(k) container_of(k, struct cache_info, kobj) 276 #define to_attr(a) container_of(a, struct cache_attr, attr) 277 278 static ssize_t cache_show(struct kobject * kobj, struct attribute * attr, char * buf) 279 { 280 struct cache_attr *fattr = to_attr(attr); 281 struct cache_info *this_leaf = to_object(kobj); 282 ssize_t ret; 283 284 ret = fattr->show ? fattr->show(this_leaf, buf) : 0; 285 return ret; 286 } 287 288 static const struct sysfs_ops cache_sysfs_ops = { 289 .show = cache_show 290 }; 291 292 static struct kobj_type cache_ktype = { 293 .sysfs_ops = &cache_sysfs_ops, 294 .default_attrs = cache_default_attrs, 295 }; 296 297 static struct kobj_type cache_ktype_percpu_entry = { 298 .sysfs_ops = &cache_sysfs_ops, 299 }; 300 301 static void __cpuinit cpu_cache_sysfs_exit(unsigned int cpu) 302 { 303 kfree(all_cpu_cache_info[cpu].cache_leaves); 304 all_cpu_cache_info[cpu].cache_leaves = NULL; 305 all_cpu_cache_info[cpu].num_cache_leaves = 0; 306 memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject)); 307 return; 308 } 309 310 static int __cpuinit cpu_cache_sysfs_init(unsigned int cpu) 311 { 312 unsigned long i, levels, unique_caches; 313 pal_cache_config_info_t cci; 314 int j; 315 long status; 316 struct cache_info *this_cache; 317 int num_cache_leaves = 0; 318 319 if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) { 320 printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status); 321 return -1; 322 } 323 324 this_cache=kzalloc(sizeof(struct cache_info)*unique_caches, 325 GFP_KERNEL); 326 if (this_cache == NULL) 327 return -ENOMEM; 328 329 for (i=0; i < levels; i++) { 330 for (j=2; j >0 ; j--) { 331 if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 332 PAL_STATUS_SUCCESS) 333 continue; 334 335 this_cache[num_cache_leaves].cci = cci; 336 this_cache[num_cache_leaves].level = i + 1; 337 this_cache[num_cache_leaves].type = j; 338 339 cache_shared_cpu_map_setup(cpu, 340 &this_cache[num_cache_leaves]); 341 num_cache_leaves ++; 342 } 343 } 344 345 all_cpu_cache_info[cpu].cache_leaves = this_cache; 346 all_cpu_cache_info[cpu].num_cache_leaves = num_cache_leaves; 347 348 memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject)); 349 350 return 0; 351 } 352 353 /* Add cache interface for CPU device */ 354 static int __cpuinit cache_add_dev(struct device * sys_dev) 355 { 356 unsigned int cpu = sys_dev->id; 357 unsigned long i, j; 358 struct cache_info *this_object; 359 int retval = 0; 360 cpumask_t oldmask; 361 362 if (all_cpu_cache_info[cpu].kobj.parent) 363 return 0; 364 365 oldmask = current->cpus_allowed; 366 retval = set_cpus_allowed_ptr(current, cpumask_of(cpu)); 367 if (unlikely(retval)) 368 return retval; 369 370 retval = cpu_cache_sysfs_init(cpu); 371 set_cpus_allowed_ptr(current, &oldmask); 372 if (unlikely(retval < 0)) 373 return retval; 374 375 retval = kobject_init_and_add(&all_cpu_cache_info[cpu].kobj, 376 &cache_ktype_percpu_entry, &sys_dev->kobj, 377 "%s", "cache"); 378 if (unlikely(retval < 0)) { 379 cpu_cache_sysfs_exit(cpu); 380 return retval; 381 } 382 383 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) { 384 this_object = LEAF_KOBJECT_PTR(cpu,i); 385 retval = kobject_init_and_add(&(this_object->kobj), 386 &cache_ktype, 387 &all_cpu_cache_info[cpu].kobj, 388 "index%1lu", i); 389 if (unlikely(retval)) { 390 for (j = 0; j < i; j++) { 391 kobject_put(&(LEAF_KOBJECT_PTR(cpu,j)->kobj)); 392 } 393 kobject_put(&all_cpu_cache_info[cpu].kobj); 394 cpu_cache_sysfs_exit(cpu); 395 return retval; 396 } 397 kobject_uevent(&(this_object->kobj), KOBJ_ADD); 398 } 399 kobject_uevent(&all_cpu_cache_info[cpu].kobj, KOBJ_ADD); 400 return retval; 401 } 402 403 /* Remove cache interface for CPU device */ 404 static int __cpuinit cache_remove_dev(struct device * sys_dev) 405 { 406 unsigned int cpu = sys_dev->id; 407 unsigned long i; 408 409 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) 410 kobject_put(&(LEAF_KOBJECT_PTR(cpu,i)->kobj)); 411 412 if (all_cpu_cache_info[cpu].kobj.parent) { 413 kobject_put(&all_cpu_cache_info[cpu].kobj); 414 memset(&all_cpu_cache_info[cpu].kobj, 415 0, 416 sizeof(struct kobject)); 417 } 418 419 cpu_cache_sysfs_exit(cpu); 420 421 return 0; 422 } 423 424 /* 425 * When a cpu is hot-plugged, do a check and initiate 426 * cache kobject if necessary 427 */ 428 static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, 429 unsigned long action, void *hcpu) 430 { 431 unsigned int cpu = (unsigned long)hcpu; 432 struct device *sys_dev; 433 434 sys_dev = get_cpu_device(cpu); 435 switch (action) { 436 case CPU_ONLINE: 437 case CPU_ONLINE_FROZEN: 438 cache_add_dev(sys_dev); 439 break; 440 case CPU_DEAD: 441 case CPU_DEAD_FROZEN: 442 cache_remove_dev(sys_dev); 443 break; 444 } 445 return NOTIFY_OK; 446 } 447 448 static struct notifier_block __cpuinitdata cache_cpu_notifier = 449 { 450 .notifier_call = cache_cpu_callback 451 }; 452 453 static int __init cache_sysfs_init(void) 454 { 455 int i; 456 457 for_each_online_cpu(i) { 458 struct device *sys_dev = get_cpu_device((unsigned int)i); 459 cache_add_dev(sys_dev); 460 } 461 462 register_hotcpu_notifier(&cache_cpu_notifier); 463 464 return 0; 465 } 466 467 device_initcall(cache_sysfs_init); 468 469