topology.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Populate sysfs with topology information
  3. *
  4. * Written by: Matthew Dobson, IBM Corporation
  5. * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
  6. *
  7. * Copyright (C) 2002, IBM Corp.
  8. *
  9. * All rights reserved.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful, but
  17. * WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  19. * NON INFRINGEMENT. See the GNU General Public License for more
  20. * details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25. *
  26. * Send feedback to <colpatch@us.ibm.com>
  27. */
  28. #include <linux/nodemask.h>
  29. #include <linux/export.h>
  30. #include <linux/mmzone.h>
  31. #include <linux/init.h>
  32. #include <linux/smp.h>
  33. #include <linux/irq.h>
  34. #include <asm/cpu.h>
  35. static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
  36. #ifdef CONFIG_HOTPLUG_CPU
  37. #ifdef CONFIG_BOOTPARAM_HOTPLUG_CPU0
  38. static int cpu0_hotpluggable = 1;
  39. #else
  40. static int cpu0_hotpluggable;
  41. static int __init enable_cpu0_hotplug(char *str)
  42. {
  43. cpu0_hotpluggable = 1;
  44. return 1;
  45. }
  46. __setup("cpu0_hotplug", enable_cpu0_hotplug);
  47. #endif
  48. #ifdef CONFIG_DEBUG_HOTPLUG_CPU0
  49. /*
  50. * This function offlines a CPU as early as possible and allows userspace to
  51. * boot up without the CPU. The CPU can be onlined back by user after boot.
  52. *
  53. * This is only called for debugging CPU offline/online feature.
  54. */
  55. int _debug_hotplug_cpu(int cpu, int action)
  56. {
  57. struct device *dev = get_cpu_device(cpu);
  58. int ret;
  59. if (!cpu_is_hotpluggable(cpu))
  60. return -EINVAL;
  61. lock_device_hotplug();
  62. switch (action) {
  63. case 0:
  64. ret = cpu_down(cpu);
  65. if (!ret) {
  66. pr_info("CPU %u is now offline\n", cpu);
  67. dev->offline = true;
  68. kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
  69. } else
  70. pr_debug("Can't offline CPU%d.\n", cpu);
  71. break;
  72. case 1:
  73. ret = cpu_up(cpu);
  74. if (!ret) {
  75. dev->offline = false;
  76. kobject_uevent(&dev->kobj, KOBJ_ONLINE);
  77. } else {
  78. pr_debug("Can't online CPU%d.\n", cpu);
  79. }
  80. break;
  81. default:
  82. ret = -EINVAL;
  83. }
  84. unlock_device_hotplug();
  85. return ret;
  86. }
  87. static int __init debug_hotplug_cpu(void)
  88. {
  89. _debug_hotplug_cpu(0, 0);
  90. return 0;
  91. }
  92. late_initcall_sync(debug_hotplug_cpu);
  93. #endif /* CONFIG_DEBUG_HOTPLUG_CPU0 */
  94. int arch_register_cpu(int num)
  95. {
  96. struct cpuinfo_x86 *c = &cpu_data(num);
  97. /*
  98. * Currently CPU0 is only hotpluggable on Intel platforms. Other
  99. * vendors can add hotplug support later.
  100. */
  101. if (c->x86_vendor != X86_VENDOR_INTEL)
  102. cpu0_hotpluggable = 0;
  103. /*
  104. * Two known BSP/CPU0 dependencies: Resume from suspend/hibernate
  105. * depends on BSP. PIC interrupts depend on BSP.
  106. *
  107. * If the BSP depencies are under control, one can tell kernel to
  108. * enable BSP hotplug. This basically adds a control file and
  109. * one can attempt to offline BSP.
  110. */
  111. if (num == 0 && cpu0_hotpluggable) {
  112. unsigned int irq;
  113. /*
  114. * We won't take down the boot processor on i386 if some
  115. * interrupts only are able to be serviced by the BSP in PIC.
  116. */
  117. for_each_active_irq(irq) {
  118. if (!IO_APIC_IRQ(irq) && irq_has_action(irq)) {
  119. cpu0_hotpluggable = 0;
  120. break;
  121. }
  122. }
  123. }
  124. if (num || cpu0_hotpluggable)
  125. per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
  126. return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
  127. }
  128. EXPORT_SYMBOL(arch_register_cpu);
  129. void arch_unregister_cpu(int num)
  130. {
  131. unregister_cpu(&per_cpu(cpu_devices, num).cpu);
  132. }
  133. EXPORT_SYMBOL(arch_unregister_cpu);
  134. #else /* CONFIG_HOTPLUG_CPU */
  135. static int __init arch_register_cpu(int num)
  136. {
  137. return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
  138. }
  139. #endif /* CONFIG_HOTPLUG_CPU */
  140. static int __init topology_init(void)
  141. {
  142. int i;
  143. #ifdef CONFIG_NUMA
  144. for_each_online_node(i)
  145. register_one_node(i);
  146. #endif
  147. for_each_present_cpu(i)
  148. arch_register_cpu(i);
  149. return 0;
  150. }
  151. subsys_initcall(topology_init);