topology.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * arch/parisc/kernel/topology.c
  3. *
  4. * Copyright (C) 2017 Helge Deller <deller@gmx.de>
  5. *
  6. * based on arch/arm/kernel/topology.c
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file "COPYING" in the main directory of this archive
  10. * for more details.
  11. */
  12. #include <linux/percpu.h>
  13. #include <linux/sched.h>
  14. #include <linux/sched/topology.h>
  15. #include <asm/topology.h>
  16. /*
  17. * cpu topology table
  18. */
  19. struct cputopo_parisc cpu_topology[NR_CPUS] __read_mostly;
  20. EXPORT_SYMBOL_GPL(cpu_topology);
  21. const struct cpumask *cpu_coregroup_mask(int cpu)
  22. {
  23. return &cpu_topology[cpu].core_sibling;
  24. }
  25. static void update_siblings_masks(unsigned int cpuid)
  26. {
  27. struct cputopo_parisc *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
  28. int cpu;
  29. /* update core and thread sibling masks */
  30. for_each_possible_cpu(cpu) {
  31. cpu_topo = &cpu_topology[cpu];
  32. if (cpuid_topo->socket_id != cpu_topo->socket_id)
  33. continue;
  34. cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
  35. if (cpu != cpuid)
  36. cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
  37. if (cpuid_topo->core_id != cpu_topo->core_id)
  38. continue;
  39. cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
  40. if (cpu != cpuid)
  41. cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
  42. }
  43. smp_wmb();
  44. }
  45. static int dualcores_found __initdata;
  46. /*
  47. * store_cpu_topology is called at boot when only one cpu is running
  48. * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
  49. * which prevents simultaneous write access to cpu_topology array
  50. */
  51. void __init store_cpu_topology(unsigned int cpuid)
  52. {
  53. struct cputopo_parisc *cpuid_topo = &cpu_topology[cpuid];
  54. struct cpuinfo_parisc *p;
  55. int max_socket = -1;
  56. unsigned long cpu;
  57. /* If the cpu topology has been already set, just return */
  58. if (cpuid_topo->core_id != -1)
  59. return;
  60. /* create cpu topology mapping */
  61. cpuid_topo->thread_id = -1;
  62. cpuid_topo->core_id = 0;
  63. p = &per_cpu(cpu_data, cpuid);
  64. for_each_online_cpu(cpu) {
  65. const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
  66. if (cpu == cpuid) /* ignore current cpu */
  67. continue;
  68. if (cpuinfo->cpu_loc == p->cpu_loc) {
  69. cpuid_topo->core_id = cpu_topology[cpu].core_id;
  70. if (p->cpu_loc) {
  71. cpuid_topo->core_id++;
  72. cpuid_topo->socket_id = cpu_topology[cpu].socket_id;
  73. dualcores_found = 1;
  74. continue;
  75. }
  76. }
  77. if (cpuid_topo->socket_id == -1)
  78. max_socket = max(max_socket, cpu_topology[cpu].socket_id);
  79. }
  80. if (cpuid_topo->socket_id == -1)
  81. cpuid_topo->socket_id = max_socket + 1;
  82. update_siblings_masks(cpuid);
  83. pr_info("CPU%u: thread %d, cpu %d, socket %d\n",
  84. cpuid, cpu_topology[cpuid].thread_id,
  85. cpu_topology[cpuid].core_id,
  86. cpu_topology[cpuid].socket_id);
  87. }
  88. static struct sched_domain_topology_level parisc_mc_topology[] = {
  89. #ifdef CONFIG_SCHED_MC
  90. { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
  91. #endif
  92. { cpu_cpu_mask, SD_INIT_NAME(DIE) },
  93. { NULL, },
  94. };
  95. /*
  96. * init_cpu_topology is called at boot when only one cpu is running
  97. * which prevent simultaneous write access to cpu_topology array
  98. */
  99. void __init init_cpu_topology(void)
  100. {
  101. unsigned int cpu;
  102. /* init core mask and capacity */
  103. for_each_possible_cpu(cpu) {
  104. struct cputopo_parisc *cpu_topo = &(cpu_topology[cpu]);
  105. cpu_topo->thread_id = -1;
  106. cpu_topo->core_id = -1;
  107. cpu_topo->socket_id = -1;
  108. cpumask_clear(&cpu_topo->core_sibling);
  109. cpumask_clear(&cpu_topo->thread_sibling);
  110. }
  111. smp_wmb();
  112. /* Set scheduler topology descriptor */
  113. if (dualcores_found)
  114. set_sched_topology(parisc_mc_topology);
  115. }