Branch data Line data Source code
1 : : /* 2 : : * include/linux/topology.h 3 : : * 4 : : * Written by: Matthew Dobson, IBM Corporation 5 : : * 6 : : * Copyright (C) 2002, IBM Corp. 7 : : * 8 : : * All rights reserved. 9 : : * 10 : : * This program is free software; you can redistribute it and/or modify 11 : : * it under the terms of the GNU General Public License as published by 12 : : * the Free Software Foundation; either version 2 of the License, or 13 : : * (at your option) any later version. 14 : : * 15 : : * This program is distributed in the hope that it will be useful, but 16 : : * WITHOUT ANY WARRANTY; without even the implied warranty of 17 : : * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 18 : : * NON INFRINGEMENT. See the GNU General Public License for more 19 : : * details. 20 : : * 21 : : * You should have received a copy of the GNU General Public License 22 : : * along with this program; if not, write to the Free Software 23 : : * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 : : * 25 : : * Send feedback to <colpatch@us.ibm.com> 26 : : */ 27 : : #ifndef _LINUX_TOPOLOGY_H 28 : : #define _LINUX_TOPOLOGY_H 29 : : 30 : : #include <linux/arch_topology.h> 31 : : #include <linux/cpumask.h> 32 : : #include <linux/bitops.h> 33 : : #include <linux/mmzone.h> 34 : : #include <linux/smp.h> 35 : : #include <linux/percpu.h> 36 : : #include <asm/topology.h> 37 : : 38 : : #ifndef nr_cpus_node 39 : : #define nr_cpus_node(node) cpumask_weight(cpumask_of_node(node)) 40 : : #endif 41 : : 42 : : #define for_each_node_with_cpus(node) \ 43 : : for_each_online_node(node) \ 44 : : if (nr_cpus_node(node)) 45 : : 46 : : int arch_update_cpu_topology(void); 47 : : 48 : : /* Conform to ACPI 2.0 SLIT distance definitions */ 49 : : #define LOCAL_DISTANCE 10 50 : : #define REMOTE_DISTANCE 20 51 : : #ifndef node_distance 52 : : #define node_distance(from,to) ((from) == (to) ? LOCAL_DISTANCE : REMOTE_DISTANCE) 53 : : #endif 54 : : #ifndef RECLAIM_DISTANCE 55 : : /* 56 : : * If the distance between nodes in a system is larger than RECLAIM_DISTANCE 57 : : * (in whatever arch specific measurement units returned by node_distance()) 58 : : * and node_reclaim_mode is enabled then the VM will only call node_reclaim() 59 : : * on nodes within this distance. 60 : : */ 61 : : #define RECLAIM_DISTANCE 30 62 : : #endif 63 : : 64 : : /* 65 : : * The following tunable allows platforms to override the default node 66 : : * reclaim distance (RECLAIM_DISTANCE) if remote memory accesses are 67 : : * sufficiently fast that the default value actually hurts 68 : : * performance. 69 : : * 70 : : * AMD EPYC machines use this because even though the 2-hop distance 71 : : * is 32 (3.2x slower than a local memory access) performance actually 72 : : * *improves* if allowed to reclaim memory and load balance tasks 73 : : * between NUMA nodes 2-hops apart. 74 : : */ 75 : : extern int __read_mostly node_reclaim_distance; 76 : : 77 : : #ifndef PENALTY_FOR_NODE_WITH_CPUS 78 : : #define PENALTY_FOR_NODE_WITH_CPUS (1) 79 : : #endif 80 : : 81 : : #ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID 82 : : DECLARE_PER_CPU(int, numa_node); 83 : : 84 : : #ifndef numa_node_id 85 : : /* Returns the number of the current Node. */ 86 : : static inline int numa_node_id(void) 87 : : { 88 : : return raw_cpu_read(numa_node); 89 : : } 90 : : #endif 91 : : 92 : : #ifndef cpu_to_node 93 : : static inline int cpu_to_node(int cpu) 94 : : { 95 : : return per_cpu(numa_node, cpu); 96 : : } 97 : : #endif 98 : : 99 : : #ifndef set_numa_node 100 : : static inline void set_numa_node(int node) 101 : : { 102 : : this_cpu_write(numa_node, node); 103 : : } 104 : : #endif 105 : : 106 : : #ifndef set_cpu_numa_node 107 : : static inline void set_cpu_numa_node(int cpu, int node) 108 : : { 109 : : per_cpu(numa_node, cpu) = node; 110 : : } 111 : : #endif 112 : : 113 : : #else /* !CONFIG_USE_PERCPU_NUMA_NODE_ID */ 114 : : 115 : : /* Returns the number of the current Node. */ 116 : : #ifndef numa_node_id 117 : 0 : static inline int numa_node_id(void) 118 : : { 119 : 0 : return cpu_to_node(raw_smp_processor_id()); 120 : : } 121 : : #endif 122 : : 123 : : #endif /* [!]CONFIG_USE_PERCPU_NUMA_NODE_ID */ 124 : : 125 : : #ifdef CONFIG_HAVE_MEMORYLESS_NODES 126 : : 127 : : /* 128 : : * N.B., Do NOT reference the '_numa_mem_' per cpu variable directly. 129 : : * It will not be defined when CONFIG_HAVE_MEMORYLESS_NODES is not defined. 130 : : * Use the accessor functions set_numa_mem(), numa_mem_id() and cpu_to_mem(). 131 : : */ 132 : : DECLARE_PER_CPU(int, _numa_mem_); 133 : : extern int _node_numa_mem_[MAX_NUMNODES]; 134 : : 135 : : #ifndef set_numa_mem 136 : : static inline void set_numa_mem(int node) 137 : : { 138 : : this_cpu_write(_numa_mem_, node); 139 : : _node_numa_mem_[numa_node_id()] = node; 140 : : } 141 : : #endif 142 : : 143 : : #ifndef node_to_mem_node 144 : : static inline int node_to_mem_node(int node) 145 : : { 146 : : return _node_numa_mem_[node]; 147 : : } 148 : : #endif 149 : : 150 : : #ifndef numa_mem_id 151 : : /* Returns the number of the nearest Node with memory */ 152 : : static inline int numa_mem_id(void) 153 : : { 154 : : return raw_cpu_read(_numa_mem_); 155 : : } 156 : : #endif 157 : : 158 : : #ifndef cpu_to_mem 159 : : static inline int cpu_to_mem(int cpu) 160 : : { 161 : : return per_cpu(_numa_mem_, cpu); 162 : : } 163 : : #endif 164 : : 165 : : #ifndef set_cpu_numa_mem 166 : : static inline void set_cpu_numa_mem(int cpu, int node) 167 : : { 168 : : per_cpu(_numa_mem_, cpu) = node; 169 : : _node_numa_mem_[cpu_to_node(cpu)] = node; 170 : : } 171 : : #endif 172 : : 173 : : #else /* !CONFIG_HAVE_MEMORYLESS_NODES */ 174 : : 175 : : #ifndef numa_mem_id 176 : : /* Returns the number of the nearest Node with memory */ 177 : : static inline int numa_mem_id(void) 178 : : { 179 : : return numa_node_id(); 180 : : } 181 : : #endif 182 : : 183 : : #ifndef node_to_mem_node 184 : : static inline int node_to_mem_node(int node) 185 : : { 186 : : return node; 187 : : } 188 : : #endif 189 : : 190 : : #ifndef cpu_to_mem 191 : : static inline int cpu_to_mem(int cpu) 192 : : { 193 : : return cpu_to_node(cpu); 194 : : } 195 : : #endif 196 : : 197 : : #endif /* [!]CONFIG_HAVE_MEMORYLESS_NODES */ 198 : : 199 : : #ifndef topology_physical_package_id 200 : : #define topology_physical_package_id(cpu) ((void)(cpu), -1) 201 : : #endif 202 : : #ifndef topology_die_id 203 : : #define topology_die_id(cpu) ((void)(cpu), -1) 204 : : #endif 205 : : #ifndef topology_core_id 206 : : #define topology_core_id(cpu) ((void)(cpu), 0) 207 : : #endif 208 : : #ifndef topology_sibling_cpumask 209 : : #define topology_sibling_cpumask(cpu) cpumask_of(cpu) 210 : : #endif 211 : : #ifndef topology_core_cpumask 212 : : #define topology_core_cpumask(cpu) cpumask_of(cpu) 213 : : #endif 214 : : #ifndef topology_die_cpumask 215 : : #define topology_die_cpumask(cpu) cpumask_of(cpu) 216 : : #endif 217 : : 218 : : #ifdef CONFIG_SCHED_SMT 219 : : static inline const struct cpumask *cpu_smt_mask(int cpu) 220 : : { 221 : : return topology_sibling_cpumask(cpu); 222 : : } 223 : : #endif 224 : : 225 : 3 : static inline const struct cpumask *cpu_cpu_mask(int cpu) 226 : : { 227 : 3 : return cpumask_of_node(cpu_to_node(cpu)); 228 : : } 229 : : 230 : : 231 : : #endif /* _LINUX_TOPOLOGY_H */