1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun============ 4*4882a593Smuzhiyunx86 Topology 5*4882a593Smuzhiyun============ 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunThis documents and clarifies the main aspects of x86 topology modelling and 8*4882a593Smuzhiyunrepresentation in the kernel. Update/change when doing changes to the 9*4882a593Smuzhiyunrespective code. 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunThe architecture-agnostic topology definitions are in 12*4882a593SmuzhiyunDocumentation/admin-guide/cputopology.rst. This file holds x86-specific 13*4882a593Smuzhiyundifferences/specialities which must not necessarily apply to the generic 14*4882a593Smuzhiyundefinitions. Thus, the way to read up on Linux topology on x86 is to start 15*4882a593Smuzhiyunwith the generic one and look at this one in parallel for the x86 specifics. 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunNeedless to say, code should use the generic functions - this file is *only* 18*4882a593Smuzhiyunhere to *document* the inner workings of x86 topology. 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunStarted by Thomas Gleixner <tglx@linutronix.de> and Borislav Petkov <bp@alien8.de>. 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunThe main aim of the topology facilities is to present adequate interfaces to 23*4882a593Smuzhiyuncode which needs to know/query/use the structure of the running system wrt 24*4882a593Smuzhiyunthreads, cores, packages, etc. 25*4882a593Smuzhiyun 26*4882a593SmuzhiyunThe kernel does not care about the concept of physical sockets because a 27*4882a593Smuzhiyunsocket has no relevance to software. It's an electromechanical component. In 28*4882a593Smuzhiyunthe past a socket always contained a single package (see below), but with the 29*4882a593Smuzhiyunadvent of Multi Chip Modules (MCM) a socket can hold more than one package. So 30*4882a593Smuzhiyunthere might be still references to sockets in the code, but they are of 31*4882a593Smuzhiyunhistorical nature and should be cleaned up. 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunThe topology of a system is described in the units of: 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun - packages 36*4882a593Smuzhiyun - cores 37*4882a593Smuzhiyun - threads 38*4882a593Smuzhiyun 39*4882a593SmuzhiyunPackage 40*4882a593Smuzhiyun======= 41*4882a593SmuzhiyunPackages contain a number of cores plus shared resources, e.g. DRAM 42*4882a593Smuzhiyuncontroller, shared caches etc. 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunModern systems may also use the term 'Die' for package. 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunAMD nomenclature for package is 'Node'. 47*4882a593Smuzhiyun 48*4882a593SmuzhiyunPackage-related topology information in the kernel: 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun - cpuinfo_x86.x86_max_cores: 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun The number of cores in a package. This information is retrieved via CPUID. 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun - cpuinfo_x86.x86_max_dies: 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun The number of dies in a package. This information is retrieved via CPUID. 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun - cpuinfo_x86.cpu_die_id: 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun The physical ID of the die. This information is retrieved via CPUID. 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun - cpuinfo_x86.phys_proc_id: 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun The physical ID of the package. This information is retrieved via CPUID 65*4882a593Smuzhiyun and deduced from the APIC IDs of the cores in the package. 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun Modern systems use this value for the socket. There may be multiple 68*4882a593Smuzhiyun packages within a socket. This value may differ from cpu_die_id. 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun - cpuinfo_x86.logical_proc_id: 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun The logical ID of the package. As we do not trust BIOSes to enumerate the 73*4882a593Smuzhiyun packages in a consistent way, we introduced the concept of logical package 74*4882a593Smuzhiyun ID so we can sanely calculate the number of maximum possible packages in 75*4882a593Smuzhiyun the system and have the packages enumerated linearly. 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun - topology_max_packages(): 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun The maximum possible number of packages in the system. Helpful for per 80*4882a593Smuzhiyun package facilities to preallocate per package information. 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun - cpu_llc_id: 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun A per-CPU variable containing: 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun - On Intel, the first APIC ID of the list of CPUs sharing the Last Level 87*4882a593Smuzhiyun Cache 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun - On AMD, the Node ID or Core Complex ID containing the Last Level 90*4882a593Smuzhiyun Cache. In general, it is a number identifying an LLC uniquely on the 91*4882a593Smuzhiyun system. 92*4882a593Smuzhiyun 93*4882a593SmuzhiyunCores 94*4882a593Smuzhiyun===== 95*4882a593SmuzhiyunA core consists of 1 or more threads. It does not matter whether the threads 96*4882a593Smuzhiyunare SMT- or CMT-type threads. 97*4882a593Smuzhiyun 98*4882a593SmuzhiyunAMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses 99*4882a593Smuzhiyun"core". 100*4882a593Smuzhiyun 101*4882a593SmuzhiyunCore-related topology information in the kernel: 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun - smp_num_siblings: 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun The number of threads in a core. The number of threads in a package can be 106*4882a593Smuzhiyun calculated by:: 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun threads_per_package = cpuinfo_x86.x86_max_cores * smp_num_siblings 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun 111*4882a593SmuzhiyunThreads 112*4882a593Smuzhiyun======= 113*4882a593SmuzhiyunA thread is a single scheduling unit. It's the equivalent to a logical Linux 114*4882a593SmuzhiyunCPU. 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunAMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always 117*4882a593Smuzhiyunuses "thread". 118*4882a593Smuzhiyun 119*4882a593SmuzhiyunThread-related topology information in the kernel: 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun - topology_core_cpumask(): 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun The cpumask contains all online threads in the package to which a thread 124*4882a593Smuzhiyun belongs. 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun The number of online threads is also printed in /proc/cpuinfo "siblings." 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun - topology_sibling_cpumask(): 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun The cpumask contains all online threads in the core to which a thread 131*4882a593Smuzhiyun belongs. 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun - topology_logical_package_id(): 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun The logical package ID to which a thread belongs. 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun - topology_physical_package_id(): 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun The physical package ID to which a thread belongs. 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun - topology_core_id(); 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo 144*4882a593Smuzhiyun "core_id." 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun 148*4882a593SmuzhiyunSystem topology examples 149*4882a593Smuzhiyun======================== 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun.. note:: 152*4882a593Smuzhiyun The alternative Linux CPU enumeration depends on how the BIOS enumerates the 153*4882a593Smuzhiyun threads. Many BIOSes enumerate all threads 0 first and then all threads 1. 154*4882a593Smuzhiyun That has the "advantage" that the logical Linux CPU numbers of threads 0 stay 155*4882a593Smuzhiyun the same whether threads are enabled or not. That's merely an implementation 156*4882a593Smuzhiyun detail and has no practical impact. 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun1) Single Package, Single Core:: 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun2) Single Package, Dual Core 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun a) One thread per core:: 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 167*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 1 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun b) Two threads per core:: 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 172*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 1 173*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 2 174*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 3 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun Alternative enumeration:: 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 179*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 2 180*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 1 181*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 3 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun AMD nomenclature for CMT systems:: 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 186*4882a593Smuzhiyun -> [Compute Unit Core 1] -> Linux CPU 1 187*4882a593Smuzhiyun -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 188*4882a593Smuzhiyun -> [Compute Unit Core 1] -> Linux CPU 3 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun4) Dual Package, Dual Core 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun a) One thread per core:: 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 195*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 1 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 198*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 3 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun b) Two threads per core:: 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 203*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 1 204*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 2 205*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 3 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4 208*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 5 209*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 6 210*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 7 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun Alternative enumeration:: 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 215*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 4 216*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 1 217*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 5 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 220*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 6 221*4882a593Smuzhiyun -> [core 1] -> [thread 0] -> Linux CPU 3 222*4882a593Smuzhiyun -> [thread 1] -> Linux CPU 7 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun AMD nomenclature for CMT systems:: 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 227*4882a593Smuzhiyun -> [Compute Unit Core 1] -> Linux CPU 1 228*4882a593Smuzhiyun -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 229*4882a593Smuzhiyun -> [Compute Unit Core 1] -> Linux CPU 3 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4 232*4882a593Smuzhiyun -> [Compute Unit Core 1] -> Linux CPU 5 233*4882a593Smuzhiyun -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6 234*4882a593Smuzhiyun -> [Compute Unit Core 1] -> Linux CPU 7 235