topology.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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/sched.h>
  20. #include <asm/topology.h>
  21. /*
  22. * cpu topology table
  23. */
  24. struct cpu_topology cpu_topology[NR_CPUS];
  25. EXPORT_SYMBOL_GPL(cpu_topology);
  26. const struct cpumask *cpu_coregroup_mask(int cpu)
  27. {
  28. return &cpu_topology[cpu].core_sibling;
  29. }
  30. static void update_siblings_masks(unsigned int cpuid)
  31. {
  32. struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
  33. int cpu;
  34. if (cpuid_topo->cluster_id == -1) {
  35. /*
  36. * DT does not contain topology information for this cpu
  37. * reset it to default behaviour
  38. */
  39. pr_debug("CPU%u: No topology information configured\n", cpuid);
  40. cpuid_topo->core_id = 0;
  41. cpumask_set_cpu(cpuid, &cpuid_topo->core_sibling);
  42. cpumask_set_cpu(cpuid, &cpuid_topo->thread_sibling);
  43. return;
  44. }
  45. /* update core and thread sibling masks */
  46. for_each_possible_cpu(cpu) {
  47. cpu_topo = &cpu_topology[cpu];
  48. if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
  49. continue;
  50. cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
  51. if (cpu != cpuid)
  52. cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
  53. if (cpuid_topo->core_id != cpu_topo->core_id)
  54. continue;
  55. cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
  56. if (cpu != cpuid)
  57. cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
  58. }
  59. }
  60. void store_cpu_topology(unsigned int cpuid)
  61. {
  62. update_siblings_masks(cpuid);
  63. }
  64. /*
  65. * init_cpu_topology is called at boot when only one cpu is running
  66. * which prevent simultaneous write access to cpu_topology array
  67. */
  68. void __init init_cpu_topology(void)
  69. {
  70. unsigned int cpu;
  71. /* init core mask and power*/
  72. for_each_possible_cpu(cpu) {
  73. struct cpu_topology *cpu_topo = &cpu_topology[cpu];
  74. cpu_topo->thread_id = -1;
  75. cpu_topo->core_id = -1;
  76. cpu_topo->cluster_id = -1;
  77. cpumask_clear(&cpu_topo->core_sibling);
  78. cpumask_clear(&cpu_topo->thread_sibling);
  79. }
  80. }