topology.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * arch/arm64/kernel/topology.c
  3. *
  4. * Copyright (C) 2011,2013,2014 Linaro Limited.
  5. *
  6. * Based on the arm32 version written by Vincent Guittot in turn based on
  7. * arch/sh/kernel/topology.c
  8. *
  9. * This file is subject to the terms and conditions of the GNU General Public
  10. * License. See the file "COPYING" in the main directory of this archive
  11. * for more details.
  12. */
  13. #include <linux/cpu.h>
  14. #include <linux/cpumask.h>
  15. #include <linux/init.h>
  16. #include <linux/percpu.h>
  17. #include <linux/node.h>
  18. #include <linux/nodemask.h>
  19. #include <linux/of.h>
  20. #include <linux/sched.h>
  21. #include <asm/cputype.h>
  22. #include <asm/topology.h>
  23. static int __init get_cpu_for_node(struct device_node *node)
  24. {
  25. struct device_node *cpu_node;
  26. int cpu;
  27. cpu_node = of_parse_phandle(node, "cpu", 0);
  28. if (!cpu_node)
  29. return -1;
  30. for_each_possible_cpu(cpu) {
  31. if (of_get_cpu_node(cpu, NULL) == cpu_node) {
  32. of_node_put(cpu_node);
  33. return cpu;
  34. }
  35. }
  36. pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
  37. of_node_put(cpu_node);
  38. return -1;
  39. }
  40. static int __init parse_core(struct device_node *core, int cluster_id,
  41. int core_id)
  42. {
  43. char name[10];
  44. bool leaf = true;
  45. int i = 0;
  46. int cpu;
  47. struct device_node *t;
  48. do {
  49. snprintf(name, sizeof(name), "thread%d", i);
  50. t = of_get_child_by_name(core, name);
  51. if (t) {
  52. leaf = false;
  53. cpu = get_cpu_for_node(t);
  54. if (cpu >= 0) {
  55. cpu_topology[cpu].cluster_id = cluster_id;
  56. cpu_topology[cpu].core_id = core_id;
  57. cpu_topology[cpu].thread_id = i;
  58. } else {
  59. pr_err("%s: Can't get CPU for thread\n",
  60. t->full_name);
  61. of_node_put(t);
  62. return -EINVAL;
  63. }
  64. of_node_put(t);
  65. }
  66. i++;
  67. } while (t);
  68. cpu = get_cpu_for_node(core);
  69. if (cpu >= 0) {
  70. if (!leaf) {
  71. pr_err("%s: Core has both threads and CPU\n",
  72. core->full_name);
  73. return -EINVAL;
  74. }
  75. cpu_topology[cpu].cluster_id = cluster_id;
  76. cpu_topology[cpu].core_id = core_id;
  77. } else if (leaf) {
  78. pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
  79. return -EINVAL;
  80. }
  81. return 0;
  82. }
  83. static int __init parse_cluster(struct device_node *cluster, int depth)
  84. {
  85. char name[10];
  86. bool leaf = true;
  87. bool has_cores = false;
  88. struct device_node *c;
  89. static int cluster_id __initdata;
  90. int core_id = 0;
  91. int i, ret;
  92. /*
  93. * First check for child clusters; we currently ignore any
  94. * information about the nesting of clusters and present the
  95. * scheduler with a flat list of them.
  96. */
  97. i = 0;
  98. do {
  99. snprintf(name, sizeof(name), "cluster%d", i);
  100. c = of_get_child_by_name(cluster, name);
  101. if (c) {
  102. leaf = false;
  103. ret = parse_cluster(c, depth + 1);
  104. of_node_put(c);
  105. if (ret != 0)
  106. return ret;
  107. }
  108. i++;
  109. } while (c);
  110. /* Now check for cores */
  111. i = 0;
  112. do {
  113. snprintf(name, sizeof(name), "core%d", i);
  114. c = of_get_child_by_name(cluster, name);
  115. if (c) {
  116. has_cores = true;
  117. if (depth == 0) {
  118. pr_err("%s: cpu-map children should be clusters\n",
  119. c->full_name);
  120. of_node_put(c);
  121. return -EINVAL;
  122. }
  123. if (leaf) {
  124. ret = parse_core(c, cluster_id, core_id++);
  125. } else {
  126. pr_err("%s: Non-leaf cluster with core %s\n",
  127. cluster->full_name, name);
  128. ret = -EINVAL;
  129. }
  130. of_node_put(c);
  131. if (ret != 0)
  132. return ret;
  133. }
  134. i++;
  135. } while (c);
  136. if (leaf && !has_cores)
  137. pr_warn("%s: empty cluster\n", cluster->full_name);
  138. if (leaf)
  139. cluster_id++;
  140. return 0;
  141. }
  142. static int __init parse_dt_topology(void)
  143. {
  144. struct device_node *cn, *map;
  145. int ret = 0;
  146. int cpu;
  147. cn = of_find_node_by_path("/cpus");
  148. if (!cn) {
  149. pr_err("No CPU information found in DT\n");
  150. return 0;
  151. }
  152. /*
  153. * When topology is provided cpu-map is essentially a root
  154. * cluster with restricted subnodes.
  155. */
  156. map = of_get_child_by_name(cn, "cpu-map");
  157. if (!map)
  158. goto out;
  159. ret = parse_cluster(map, 0);
  160. if (ret != 0)
  161. goto out_map;
  162. /*
  163. * Check that all cores are in the topology; the SMP code will
  164. * only mark cores described in the DT as possible.
  165. */
  166. for_each_possible_cpu(cpu)
  167. if (cpu_topology[cpu].cluster_id == -1)
  168. ret = -EINVAL;
  169. out_map:
  170. of_node_put(map);
  171. out:
  172. of_node_put(cn);
  173. return ret;
  174. }
  175. /*
  176. * cpu topology table
  177. */
  178. struct cpu_topology cpu_topology[NR_CPUS];
  179. EXPORT_SYMBOL_GPL(cpu_topology);
  180. const struct cpumask *cpu_coregroup_mask(int cpu)
  181. {
  182. return &cpu_topology[cpu].core_sibling;
  183. }
  184. static void update_siblings_masks(unsigned int cpuid)
  185. {
  186. struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
  187. int cpu;
  188. /* update core and thread sibling masks */
  189. for_each_possible_cpu(cpu) {
  190. cpu_topo = &cpu_topology[cpu];
  191. if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
  192. continue;
  193. cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
  194. if (cpu != cpuid)
  195. cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
  196. if (cpuid_topo->core_id != cpu_topo->core_id)
  197. continue;
  198. cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
  199. if (cpu != cpuid)
  200. cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
  201. }
  202. }
  203. void store_cpu_topology(unsigned int cpuid)
  204. {
  205. struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
  206. u64 mpidr;
  207. if (cpuid_topo->cluster_id != -1)
  208. goto topology_populated;
  209. mpidr = read_cpuid_mpidr();
  210. /* Uniprocessor systems can rely on default topology values */
  211. if (mpidr & MPIDR_UP_BITMASK)
  212. return;
  213. /* Create cpu topology mapping based on MPIDR. */
  214. if (mpidr & MPIDR_MT_BITMASK) {
  215. /* Multiprocessor system : Multi-threads per core */
  216. cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  217. cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  218. cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) |
  219. MPIDR_AFFINITY_LEVEL(mpidr, 3) << 8;
  220. } else {
  221. /* Multiprocessor system : Single-thread per core */
  222. cpuid_topo->thread_id = -1;
  223. cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  224. cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) |
  225. MPIDR_AFFINITY_LEVEL(mpidr, 2) << 8 |
  226. MPIDR_AFFINITY_LEVEL(mpidr, 3) << 16;
  227. }
  228. pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
  229. cpuid, cpuid_topo->cluster_id, cpuid_topo->core_id,
  230. cpuid_topo->thread_id, mpidr);
  231. topology_populated:
  232. update_siblings_masks(cpuid);
  233. }
  234. static void __init reset_cpu_topology(void)
  235. {
  236. unsigned int cpu;
  237. for_each_possible_cpu(cpu) {
  238. struct cpu_topology *cpu_topo = &cpu_topology[cpu];
  239. cpu_topo->thread_id = -1;
  240. cpu_topo->core_id = 0;
  241. cpu_topo->cluster_id = -1;
  242. cpumask_clear(&cpu_topo->core_sibling);
  243. cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
  244. cpumask_clear(&cpu_topo->thread_sibling);
  245. cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
  246. }
  247. }
  248. void __init init_cpu_topology(void)
  249. {
  250. reset_cpu_topology();
  251. /*
  252. * Discard anything that was parsed if we hit an error so we
  253. * don't use partial information.
  254. */
  255. if (of_have_populated_dt() && parse_dt_topology())
  256. reset_cpu_topology();
  257. }