numa.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * NUMA support for s390
  3. *
  4. * Implement NUMA core code.
  5. *
  6. * Copyright IBM Corp. 2015
  7. */
  8. #define KMSG_COMPONENT "numa"
  9. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  10. #include <linux/kernel.h>
  11. #include <linux/mmzone.h>
  12. #include <linux/cpumask.h>
  13. #include <linux/bootmem.h>
  14. #include <linux/memblock.h>
  15. #include <linux/slab.h>
  16. #include <linux/node.h>
  17. #include <asm/numa.h>
  18. #include "numa_mode.h"
  19. pg_data_t *node_data[MAX_NUMNODES];
  20. EXPORT_SYMBOL(node_data);
  21. cpumask_t node_to_cpumask_map[MAX_NUMNODES];
  22. EXPORT_SYMBOL(node_to_cpumask_map);
  23. static void plain_setup(void)
  24. {
  25. node_set(0, node_possible_map);
  26. }
  27. const struct numa_mode numa_mode_plain = {
  28. .name = "plain",
  29. .setup = plain_setup,
  30. };
  31. static const struct numa_mode *mode = &numa_mode_plain;
  32. int numa_pfn_to_nid(unsigned long pfn)
  33. {
  34. return mode->__pfn_to_nid ? mode->__pfn_to_nid(pfn) : 0;
  35. }
  36. void numa_update_cpu_topology(void)
  37. {
  38. if (mode->update_cpu_topology)
  39. mode->update_cpu_topology();
  40. }
  41. int __node_distance(int a, int b)
  42. {
  43. return mode->distance ? mode->distance(a, b) : 0;
  44. }
  45. int numa_debug_enabled;
  46. /*
  47. * alloc_node_data() - Allocate node data
  48. */
  49. static __init pg_data_t *alloc_node_data(void)
  50. {
  51. pg_data_t *res;
  52. res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 8);
  53. memset(res, 0, sizeof(pg_data_t));
  54. return res;
  55. }
  56. /*
  57. * numa_setup_memory() - Assign bootmem to nodes
  58. *
  59. * The memory is first added to memblock without any respect to nodes.
  60. * This is fixed before remaining memblock memory is handed over to the
  61. * buddy allocator.
  62. * An important side effect is that large bootmem allocations might easily
  63. * cross node boundaries, which can be needed for large allocations with
  64. * smaller memory stripes in each node (i.e. when using NUMA emulation).
  65. *
  66. * Memory defines nodes:
  67. * Therefore this routine also sets the nodes online with memory.
  68. */
  69. static void __init numa_setup_memory(void)
  70. {
  71. unsigned long cur_base, align, end_of_dram;
  72. int nid = 0;
  73. end_of_dram = memblock_end_of_DRAM();
  74. align = mode->align ? mode->align() : ULONG_MAX;
  75. /*
  76. * Step through all available memory and assign it to the nodes
  77. * indicated by the mode implementation.
  78. * All nodes which are seen here will be set online.
  79. */
  80. cur_base = 0;
  81. do {
  82. nid = numa_pfn_to_nid(PFN_DOWN(cur_base));
  83. node_set_online(nid);
  84. memblock_set_node(cur_base, align, &memblock.memory, nid);
  85. cur_base += align;
  86. } while (cur_base < end_of_dram);
  87. /* Allocate and fill out node_data */
  88. for (nid = 0; nid < MAX_NUMNODES; nid++)
  89. NODE_DATA(nid) = alloc_node_data();
  90. for_each_online_node(nid) {
  91. unsigned long start_pfn, end_pfn;
  92. unsigned long t_start, t_end;
  93. int i;
  94. start_pfn = ULONG_MAX;
  95. end_pfn = 0;
  96. for_each_mem_pfn_range(i, nid, &t_start, &t_end, NULL) {
  97. if (t_start < start_pfn)
  98. start_pfn = t_start;
  99. if (t_end > end_pfn)
  100. end_pfn = t_end;
  101. }
  102. NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
  103. NODE_DATA(nid)->node_id = nid;
  104. }
  105. }
  106. /*
  107. * numa_setup() - Earliest initialization
  108. *
  109. * Assign the mode and call the mode's setup routine.
  110. */
  111. void __init numa_setup(void)
  112. {
  113. pr_info("NUMA mode: %s\n", mode->name);
  114. nodes_clear(node_possible_map);
  115. if (mode->setup)
  116. mode->setup();
  117. numa_setup_memory();
  118. memblock_dump_all();
  119. }
  120. /*
  121. * numa_init_early() - Initialization initcall
  122. *
  123. * This runs when only one CPU is online and before the first
  124. * topology update is called for by the scheduler.
  125. */
  126. static int __init numa_init_early(void)
  127. {
  128. /* Attach all possible CPUs to node 0 for now. */
  129. cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask);
  130. return 0;
  131. }
  132. early_initcall(numa_init_early);
  133. /*
  134. * numa_init_late() - Initialization initcall
  135. *
  136. * Register NUMA nodes.
  137. */
  138. static int __init numa_init_late(void)
  139. {
  140. int nid;
  141. for_each_online_node(nid)
  142. register_one_node(nid);
  143. return 0;
  144. }
  145. arch_initcall(numa_init_late);
  146. static int __init parse_debug(char *parm)
  147. {
  148. numa_debug_enabled = 1;
  149. return 0;
  150. }
  151. early_param("numa_debug", parse_debug);
  152. static int __init parse_numa(char *parm)
  153. {
  154. if (strcmp(parm, numa_mode_plain.name) == 0)
  155. mode = &numa_mode_plain;
  156. #ifdef CONFIG_NUMA_EMU
  157. if (strcmp(parm, numa_mode_emu.name) == 0)
  158. mode = &numa_mode_emu;
  159. #endif
  160. return 0;
  161. }
  162. early_param("numa", parse_numa);