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