topology.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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/io_apic.h>
  35. #include <asm/cpu.h>
  36. static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
  37. #ifdef CONFIG_HOTPLUG_CPU
  38. #ifdef CONFIG_BOOTPARAM_HOTPLUG_CPU0
  39. static int cpu0_hotpluggable = 1;
  40. #else
  41. static int cpu0_hotpluggable;
  42. static int __init enable_cpu0_hotplug(char *str)
  43. {
  44. cpu0_hotpluggable = 1;
  45. return 1;
  46. }
  47. __setup("cpu0_hotplug", enable_cpu0_hotplug);
  48. #endif
  49. #ifdef CONFIG_DEBUG_HOTPLUG_CPU0
  50. /*
  51. * This function offlines a CPU as early as possible and allows userspace to
  52. * boot up without the CPU. The CPU can be onlined back by user after boot.
  53. *
  54. * This is only called for debugging CPU offline/online feature.
  55. */
  56. int _debug_hotplug_cpu(int cpu, int action)
  57. {
  58. int ret;
  59. if (!cpu_is_hotpluggable(cpu))
  60. return -EINVAL;
  61. switch (action) {
  62. case 0:
  63. ret = remove_cpu(cpu);
  64. if (!ret)
  65. pr_info("DEBUG_HOTPLUG_CPU0: CPU %u is now offline\n", cpu);
  66. else
  67. pr_debug("Can't offline CPU%d.\n", cpu);
  68. break;
  69. case 1:
  70. ret = add_cpu(cpu);
  71. if (ret)
  72. pr_debug("Can't online CPU%d.\n", cpu);
  73. break;
  74. default:
  75. ret = -EINVAL;
  76. }
  77. return ret;
  78. }
  79. static int __init debug_hotplug_cpu(void)
  80. {
  81. _debug_hotplug_cpu(0, 0);
  82. return 0;
  83. }
  84. late_initcall_sync(debug_hotplug_cpu);
  85. #endif /* CONFIG_DEBUG_HOTPLUG_CPU0 */
  86. int arch_register_cpu(int num)
  87. {
  88. struct cpuinfo_x86 *c = &cpu_data(num);
  89. /*
  90. * Currently CPU0 is only hotpluggable on Intel platforms. Other
  91. * vendors can add hotplug support later.
  92. * Xen PV guests don't support CPU0 hotplug at all.
  93. */
  94. if (c->x86_vendor != X86_VENDOR_INTEL ||
  95. boot_cpu_has(X86_FEATURE_XENPV))
  96. cpu0_hotpluggable = 0;
  97. /*
  98. * Two known BSP/CPU0 dependencies: Resume from suspend/hibernate
  99. * depends on BSP. PIC interrupts depend on BSP.
  100. *
  101. * If the BSP depencies are under control, one can tell kernel to
  102. * enable BSP hotplug. This basically adds a control file and
  103. * one can attempt to offline BSP.
  104. */
  105. if (num == 0 && cpu0_hotpluggable) {
  106. unsigned int irq;
  107. /*
  108. * We won't take down the boot processor on i386 if some
  109. * interrupts only are able to be serviced by the BSP in PIC.
  110. */
  111. for_each_active_irq(irq) {
  112. if (!IO_APIC_IRQ(irq) && irq_has_action(irq)) {
  113. cpu0_hotpluggable = 0;
  114. break;
  115. }
  116. }
  117. }
  118. if (num || cpu0_hotpluggable)
  119. per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
  120. return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
  121. }
  122. EXPORT_SYMBOL(arch_register_cpu);
  123. void arch_unregister_cpu(int num)
  124. {
  125. unregister_cpu(&per_cpu(cpu_devices, num).cpu);
  126. }
  127. EXPORT_SYMBOL(arch_unregister_cpu);
  128. #else /* CONFIG_HOTPLUG_CPU */
  129. static int __init arch_register_cpu(int num)
  130. {
  131. return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
  132. }
  133. #endif /* CONFIG_HOTPLUG_CPU */
  134. static int __init topology_init(void)
  135. {
  136. int i;
  137. #ifdef CONFIG_NUMA
  138. for_each_online_node(i)
  139. register_one_node(i);
  140. #endif
  141. for_each_present_cpu(i)
  142. arch_register_cpu(i);
  143. return 0;
  144. }
  145. subsys_initcall(topology_init);