topology.c 3.9 KB

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