Fsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget%/translations/zh_CN/arch/x86/topologymodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/zh_TW/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/it_IT/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ja_JP/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ko_KR/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/sp_SP/arch/x86/topologymodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh?/var/lib/git/docbuild/linux/Documentation/arch/x86/topology.rsthKubhsection)}(hhh](htitle)}(h x86 Topologyh]h x86 Topology}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hThis documents and clarifies the main aspects of x86 topology modelling and representation in the kernel. Update/change when doing changes to the respective code.h]hThis documents and clarifies the main aspects of x86 topology modelling and representation in the kernel. Update/change when doing changes to the respective code.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hX^The architecture-agnostic topology definitions are in Documentation/admin-guide/cputopology.rst. This file holds x86-specific differences/specialities which must not necessarily apply to the generic definitions. Thus, the way to read up on Linux topology on x86 is to start with the generic one and look at this one in parallel for the x86 specifics.h]hX^The architecture-agnostic topology definitions are in Documentation/admin-guide/cputopology.rst. This file holds x86-specific differences/specialities which must not necessarily apply to the generic definitions. Thus, the way to read up on Linux topology on x86 is to start with the generic one and look at this one in parallel for the x86 specifics.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hNeedless to say, code should use the generic functions - this file is *only* here to *document* the inner workings of x86 topology.h](hFNeedless to say, code should use the generic functions - this file is }(hhhhhNhNubhemphasis)}(h*only*h]honly}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh here to }(hhhhhNhNubh)}(h *document*h]hdocument}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh$ the inner workings of x86 topology.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hSStarted by Thomas Gleixner and Borislav Petkov .h](hStarted by Thomas Gleixner <}(hjhhhNhNubh reference)}(htglx@linutronix.deh]htglx@linutronix.de}(hj%hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:tglx@linutronix.deuh1j#hjubh> and Borislav Petkov <}(hjhhhNhNubj$)}(h bp@alien8.deh]h bp@alien8.de}(hj9hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:bp@alien8.deuh1j#hjubh>.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hThe main aim of the topology facilities is to present adequate interfaces to code which needs to know/query/use the structure of the running system wrt threads, cores, packages, etc.h]hThe main aim of the topology facilities is to present adequate interfaces to code which needs to know/query/use the structure of the running system wrt threads, cores, packages, etc.}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXThe kernel does not care about the concept of physical sockets because a socket has no relevance to software. It's an electromechanical component. In the past a socket always contained a single package (see below), but with the advent of Multi Chip Modules (MCM) a socket can hold more than one package. So there might be still references to sockets in the code, but they are of historical nature and should be cleaned up.h]hXThe kernel does not care about the concept of physical sockets because a socket has no relevance to software. It’s an electromechanical component. In the past a socket always contained a single package (see below), but with the advent of Multi Chip Modules (MCM) a socket can hold more than one package. So there might be still references to sockets in the code, but they are of historical nature and should be cleaned up.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(h6The topology of a system is described in the units of:h]h6The topology of a system is described in the units of:}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hhhhubh block_quote)}(h- packages - cores - threads h]h bullet_list)}(hhh](h list_item)}(hpackagesh]h)}(hjh]hpackages}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hcoresh]h)}(hjh]hcores}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hthreads h]h)}(hthreadsh]hthreads}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK%hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhK#hjubah}(h]h ]h"]h$]h&]uh1j}hhhK#hhhhubh)}(hhh](h)}(hPackageh]hPackage}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK(ubh)}(hbPackages contain a number of cores plus shared resources, e.g. DRAM controller, shared caches etc.h]hbPackages contain a number of cores plus shared resources, e.g. DRAM controller, shared caches etc.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK)hjhhubh)}(h7Modern systems may also use the term 'Die' for package.h]h;Modern systems may also use the term ‘Die’ for package.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hjhhubh)}(h'AMD nomenclature for package is 'Node'.h]h+AMD nomenclature for package is ‘Node’.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjhhubh)}(h3Package-related topology information in the kernel:h]h3Package-related topology information in the kernel:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjhhubj~)}(hXI- topology_num_threads_per_package() The number of threads in a package. - topology_num_cores_per_package() The number of cores in a package. - topology_max_dies_per_package() The maximum number of dies in a package. - cpuinfo_x86.topo.die_id: The physical ID of the die. - cpuinfo_x86.topo.pkg_id: The physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package. Modern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id. - cpuinfo_x86.topo.logical_pkg_id: The logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly. - topology_max_packages(): The maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information. - cpuinfo_x86.topo.llc_id: - On Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache - On AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h]j)}(hhh](j)}(hHtopology_num_threads_per_package() The number of threads in a package. h](h)}(h"topology_num_threads_per_package()h]h"topology_num_threads_per_package()}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK2hj.ubh)}(h#The number of threads in a package.h]h#The number of threads in a package.}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK4hj.ubeh}(h]h ]h"]h$]h&]uh1jhj+ubj)}(hDtopology_num_cores_per_package() The number of cores in a package. h](h)}(h topology_num_cores_per_package()h]h topology_num_cores_per_package()}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hjTubh)}(h!The number of cores in a package.h]h!The number of cores in a package.}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjTubeh}(h]h ]h"]h$]h&]uh1jhj+ubj)}(hJtopology_max_dies_per_package() The maximum number of dies in a package. h](h)}(htopology_max_dies_per_package()h]htopology_max_dies_per_package()}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hjzubh)}(h(The maximum number of dies in a package.h]h(The maximum number of dies in a package.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe physical ID of the die.h]hThe physical ID of the die.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK@hjubeh}(h]h ]h"]h$]h&]uh1jhj+ubj)}(hX$cpuinfo_x86.topo.pkg_id: The physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package. Modern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id. h](h)}(hcpuinfo_x86.topo.pkg_id:h]hcpuinfo_x86.topo.pkg_id:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhjubh)}(hThe physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package.h]hThe physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjubh)}(hModern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id.h]hModern systems use this value for the socket. There may be multiple packages within a socket. This value may differ from topo.die_id.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhjubeh}(h]h ]h"]h$]h&]uh1jhj+ubj)}(hX6cpuinfo_x86.topo.logical_pkg_id: The logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly. h](h)}(h cpuinfo_x86.topo.logical_pkg_id:h]h cpuinfo_x86.topo.logical_pkg_id:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjubh)}(hXThe logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly.h]hXThe logical ID of the package. As we do not trust BIOSes to enumerate the packages in a consistent way, we introduced the concept of logical package ID so we can sanely calculate the number of maximum possible packages in the system and have the packages enumerated linearly.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKLhjubeh}(h]h ]h"]h$]h&]uh1jhj+ubj)}(htopology_max_packages(): The maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information. h](h)}(htopology_max_packages():h]htopology_max_packages():}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKQhj ubh)}(hThe maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information.h]hThe maximum possible number of packages in the system. Helpful for per package facilities to preallocate per package information.}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKShj ubeh}(h]h ]h"]h$]h&]uh1jhj+ubj)}(hX cpuinfo_x86.topo.llc_id: - On Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache - On AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h](h)}(hcpuinfo_x86.topo.llc_id:h]hcpuinfo_x86.topo.llc_id:}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKVhjFubj~)}(h- On Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache - On AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h]j)}(hhh](j)}(hMOn Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache h]h)}(hLOn Intel, the first APIC ID of the list of CPUs sharing the Last Level Cacheh]hLOn Intel, the first APIC ID of the list of CPUs sharing the Last Level Cache}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKXhj_ubah}(h]h ]h"]h$]h&]uh1jhj\ubj)}(hOn AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system. h]h)}(hOn AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system.h]hOn AMD, the Node ID or Core Complex ID containing the Last Level Cache. In general, it is a number identifying an LLC uniquely on the system.}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK[hjwubah}(h]h ]h"]h$]h&]uh1jhj\ubeh}(h]h ]h"]h$]h&]jjuh1jhhhKXhjXubah}(h]h ]h"]h$]h&]uh1j}hhhKXhjFubeh}(h]h ]h"]h$]h&]uh1jhj+ubeh}(h]h ]h"]h$]h&]jjuh1jhhhK2hj'ubah}(h]h ]h"]h$]h&]uh1j}hhhK2hjhhubeh}(h]packageah ]h"]packageah$]h&]uh1hhhhhhhhK(ubh)}(hhh](h)}(hCoresh]hCores}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK`ubh)}(hjA core consists of 1 or more threads. It does not matter whether the threads are SMT- or CMT-type threads.h]hjA core consists of 1 or more threads. It does not matter whether the threads are SMT- or CMT-type threads.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKahjhhubh)}(hRAMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses "core".h]hZAMDs nomenclature for a CMT core is “Compute Unit”. The kernel always uses “core”.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKdhjhhubeh}(h]coresah ]h"]coresah$]h&]uh1hhhhhhhhK`ubh)}(hhh](h)}(hThreadsh]hThreads}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKhubh)}(hQA thread is a single scheduling unit. It's the equivalent to a logical Linux CPU.h]hSA thread is a single scheduling unit. It’s the equivalent to a logical Linux CPU.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKihjhhubh)}(hZAMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always uses "thread".h]hbAMDs nomenclature for CMT threads is “Compute Unit Core”. The kernel always uses “thread”.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKlhjhhubh)}(h2Thread-related topology information in the kernel:h]h2Thread-related topology information in the kernel:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKohjhhubj~)}(hX- topology_core_cpumask(): The cpumask contains all online threads in the package to which a thread belongs. The number of online threads is also printed in /proc/cpuinfo "siblings." - topology_sibling_cpumask(): The cpumask contains all online threads in the core to which a thread belongs. - topology_logical_package_id(): The logical package ID to which a thread belongs. - topology_physical_package_id(): The physical package ID to which a thread belongs. - topology_core_id(); The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo "core_id." - topology_logical_core_id(); The logical core ID to which a thread belongs. h]j)}(hhh](j)}(htopology_core_cpumask(): The cpumask contains all online threads in the package to which a thread belongs. The number of online threads is also printed in /proc/cpuinfo "siblings." h](h)}(htopology_core_cpumask():h]htopology_core_cpumask():}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKqhj,ubh)}(hQThe cpumask contains all online threads in the package to which a thread belongs.h]hQThe cpumask contains all online threads in the package to which a thread belongs.}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKshj,ubh)}(hIThe number of online threads is also printed in /proc/cpuinfo "siblings."h]hMThe number of online threads is also printed in /proc/cpuinfo “siblings.”}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKvhj,ubeh}(h]h ]h"]h$]h&]uh1jhj)ubj)}(hltopology_sibling_cpumask(): The cpumask contains all online threads in the core to which a thread belongs. h](h)}(htopology_sibling_cpumask():h]htopology_sibling_cpumask():}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhj`ubh)}(hNThe cpumask contains all online threads in the core to which a thread belongs.h]hNThe cpumask contains all online threads in the core to which a thread belongs.}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhj`ubeh}(h]h ]h"]h$]h&]uh1jhj)ubj)}(hRtopology_logical_package_id(): The logical package ID to which a thread belongs. h](h)}(htopology_logical_package_id():h]htopology_logical_package_id():}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK}hjubh)}(h1The logical package ID to which a thread belongs.h]h1The logical package ID to which a thread belongs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhj)ubj)}(hTtopology_physical_package_id(): The physical package ID to which a thread belongs. h](h)}(htopology_physical_package_id():h]htopology_physical_package_id():}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h2The physical package ID to which a thread belongs.h]h2The physical package ID to which a thread belongs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhj)ubj)}(hrtopology_core_id(); The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo "core_id." h](h)}(htopology_core_id();h]htopology_core_id();}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h\The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo "core_id."h]h`The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo “core_id.”}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhj)ubj)}(hNtopology_logical_core_id(); The logical core ID to which a thread belongs. h](h)}(htopology_logical_core_id();h]htopology_logical_core_id();}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h.The logical core ID to which a thread belongs.h]h.The logical core ID to which a thread belongs.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhj)ubeh}(h]h ]h"]h$]h&]jjuh1jhhhKqhj%ubah}(h]h ]h"]h$]h&]uh1j}hhhKqhjhhubeh}(h]threadsah ]h"]threadsah$]h&]uh1hhhhhhhhKhubh)}(hhh](h)}(hSystem topology enumerationh]hSystem topology enumeration}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj2hhhhhKubh)}(hThe topology on x86 systems can be discovered using a combination of vendor specific CPUID leaves which enumerate the processor topology and the cache hierarchy.h]hThe topology on x86 systems can be discovered using a combination of vendor specific CPUID leaves which enumerate the processor topology and the cache hierarchy.}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj2hhubh)}(hWThe CPUID leaves in their preferred order of parsing for each x86 vendor is as follows:h]hWThe CPUID leaves in their preferred order of parsing for each x86 vendor is as follows:}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj2hhubhenumerated_list)}(hhh](j)}(hXAMD 1) CPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology) The extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level. Support for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel` in `EBX[15:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket. The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from `ExtendedLocalApicId` in `EDX[31:0]` in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. CPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics. If CPUID leaf 0x80000026 is supported, further parsing is not required. 2) CPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum) The extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology. The support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain that the level describes - Thread, or Processor (Socket). The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from the `ExtendedLocalApicId` in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level. If CPUID leaf 0xB is supported, further parsing is not required. 3) CPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId) If neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX. The support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008. The shifts from the APIC ID for the Socket ID is calculated from the `ApicIdSize` field in `ECX[15:12]` if it is non-zero. If `ApicIdSize` is reported to be zero, the shift is calculated as the order of the `number of threads` calculated from `NC` field in `ECX[7:0]` which describes the `number of threads - 1` on the package. Unless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]`. The topology parsing continues to detect if Extended APIC ID is supported or not. 4) CPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId}) The support for Extended APIC ID can be detected by checking for the presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx). If Topology Extensions is supported, the APIC ID from `ExtendedApicId` from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology enumeration. On processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of `number of threads per core` calculated using the `ThreadsPerCore` field in `EBX[15:8]` which describes `number of threads per core - 1`. On Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the `cu_id` (Compute Unit ID) to detect CPUs that share the compute units. All AMD processors that support the `TopologyExtensions` feature store the `NodeId` from the `ECX[7:0]` of CPUID leaf 0x8000001E (Core::X86::Cpuid::NodeId) as the per-CPU `node_id`. On older processors, the `node_id` was discovered using MSR_FAM10H_NODE_ID MSR (MSR 0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking `ECX[19]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx). h](h)}(hAMDh]hAMD}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjdubj`)}(hhh](j)}(hXhCPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology) The extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level. Support for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel` in `EBX[15:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket. The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from `ExtendedLocalApicId` in `EDX[31:0]` in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. CPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics. If CPUID leaf 0x80000026 is supported, further parsing is not required. h](h)}(hOCPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology)h]hOCPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology)}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjyubh)}(hThe extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level.h]hThe extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB and provides the topology information of Core, Complex, CCD (Die), and Socket in each level.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjyubh)}(hSupport for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel` in `EBX[15:0]` at a particular level (starting from 0) is non-zero.h](hySupport for the leaf is discovered by checking if the maximum extended CPUID level is >= 0x80000026 and then checking if }(hjhhhNhNubhtitle_reference)}(h`LogProcAtThisLevel`h]hLogProcAtThisLevel}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `EBX[15:0]`h]h EBX[15:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh5 at a particular level (starting from 0) is non-zero.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjyubh)}(hThe `LevelType` in `ECX[15:8]` at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket.h](hThe }(hjhhhNhNubj)}(h `LevelType`h]h LevelType}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `ECX[15:8]`h]h ECX[15:8]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhh at the level provides the topology domain the level describes - Core, Complex, CCD(Die), or the Socket.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjyubh)}(hXThe kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from `ExtendedLocalApicId` in `EDX[31:0]` in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.h](hThe kernel uses the }(hjhhhNhNubj)}(h`CoreMaskWidth`h]h CoreMaskWidth}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh from }(hjhhhNhNubj)}(h `EAX[4:0]`h]hEAX[4:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhC to discover the number of bits that need to be right-shifted from }(hjhhhNhNubj)}(h`ExtendedLocalApicId`h]hExtendedLocalApicId}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `EDX[31:0]`h]h EDX[31:0]}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in order to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjyubh)}(hCPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics.h]hCPUID leaf 0x80000026 also provides more information regarding the power and efficiency rankings, and about the core type on AMD processors with heterogeneous characteristics.}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjyubh)}(hGIf CPUID leaf 0x80000026 is supported, further parsing is not required.h]hGIf CPUID leaf 0x80000026 is supported, further parsing is not required.}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjyubeh}(h]h ]h"]h$]h&]uh1jhjvubj)}(hXCPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum) The extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology. The support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `LevelType` in `ECX[15:8]` at the level provides the topology domain that the level describes - Thread, or Processor (Socket). The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from the `ExtendedLocalApicId` in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level. If CPUID leaf 0xB is supported, further parsing is not required. h](h)}(hTCPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum)h]hTCPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum)}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjwubh)}(hThe extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology.h]hThe extended CPUID leaf 0x0000000B is the predecessor on the extended CPUID leaf 0x80000026 and only describes the core, and the socket domains of the processor topology.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjwubh)}(hThe support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level (starting from 0) is non-zero.h](hnThe support for the leaf is discovered by checking if the maximum supported CPUID level is >= 0xB and then if }(hjhhhNhNubj)}(h `EBX[31:0]`h]h EBX[31:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh5 at a particular level (starting from 0) is non-zero.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjwubh)}(hThe `LevelType` in `ECX[15:8]` at the level provides the topology domain that the level describes - Thread, or Processor (Socket).h](hThe }(hjhhhNhNubj)}(h `LevelType`h]h LevelType}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `ECX[15:8]`h]h ECX[15:8]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhd at the level provides the topology domain that the level describes - Thread, or Processor (Socket).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjwubh)}(hXThe kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the number of bits that need to be right-shifted from the `ExtendedLocalApicId` in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level.h](hThe kernel uses the }(hjhhhNhNubj)}(h`CoreMaskWidth`h]h CoreMaskWidth}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh from }(hjhhhNhNubj)}(h `EAX[4:0]`h]hEAX[4:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhG to discover the number of bits that need to be right-shifted from the }(hjhhhNhNubj)}(h`ExtendedLocalApicId`h]hExtendedLocalApicId}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in }(hjhhhNhNubj)}(h `EDX[31:0]`h]h EDX[31:0]}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhu to get a unique Topology ID for that topology level. CPUs sharing the Topology ID share the resources at that level.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjwubh)}(h@If CPUID leaf 0xB is supported, further parsing is not required.h]h@If CPUID leaf 0xB is supported, further parsing is not required.}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjwubeh}(h]h ]h"]h$]h&]uh1jhjvubj)}(hXCPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId) If neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX. The support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008. The shifts from the APIC ID for the Socket ID is calculated from the `ApicIdSize` field in `ECX[15:12]` if it is non-zero. If `ApicIdSize` is reported to be zero, the shift is calculated as the order of the `number of threads` calculated from `NC` field in `ECX[7:0]` which describes the `number of threads - 1` on the package. Unless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]`. The topology parsing continues to detect if Extended APIC ID is supported or not. h](h)}(hGCPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId)h]hGCPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId)}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjSubh)}(hIf neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX.h]hIf neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of CPUs on the package is detected using the Size Identifier leaf 0x80000008 ECX.}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjSubh)}(hjThe support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008.h]hjThe support for the leaf is discovered by checking if the supported extended CPUID level is >= 0x80000008.}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjSubh)}(hzThe shifts from the APIC ID for the Socket ID is calculated from the `ApicIdSize` field in `ECX[15:12]` if it is non-zero.h](hEThe shifts from the APIC ID for the Socket ID is calculated from the }(hjhhhNhNubj)}(h `ApicIdSize`h]h ApicIdSize}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field in }(hjhhhNhNubj)}(h `ECX[15:12]`h]h ECX[15:12]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh if it is non-zero.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjSubh)}(hIf `ApicIdSize` is reported to be zero, the shift is calculated as the order of the `number of threads` calculated from `NC` field in `ECX[7:0]` which describes the `number of threads - 1` on the package.h](hIf }(hjhhhNhNubj)}(h `ApicIdSize`h]h ApicIdSize}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhE is reported to be zero, the shift is calculated as the order of the }(hjhhhNhNubj)}(h`number of threads`h]hnumber of threads}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh calculated from }(hjhhhNhNubj)}(h`NC`h]hNC}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field in }(hjhhhNhNubj)}(h `ECX[7:0]`h]hECX[7:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh which describes the }(hjhhhNhNubj)}(h`number of threads - 1`h]hnumber of threads - 1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh on the package.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjSubh)}(hUnless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]`.h](hYUnless Extended APIC ID is supported, the APIC ID used to find the Socket ID is from the }(hjhhhNhNubj)}(h `LocalApicId`h]h LocalApicId}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field of CPUID leaf 0x00000001 }(hjhhhNhNubj)}(h `EBX[31:24]`h]h EBX[31:24]}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjSubh)}(hQThe topology parsing continues to detect if Extended APIC ID is supported or not.h]hQThe topology parsing continues to detect if Extended APIC ID is supported or not.}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjSubeh}(h]h ]h"]h$]h&]uh1jhjvubj)}(hXCPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId}) The support for Extended APIC ID can be detected by checking for the presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx). If Topology Extensions is supported, the APIC ID from `ExtendedApicId` from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology enumeration. On processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of `number of threads per core` calculated using the `ThreadsPerCore` field in `EBX[15:8]` which describes `number of threads per core - 1`. On Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the `cu_id` (Compute Unit ID) to detect CPUs that share the compute units. h](h)}(hzCPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId})h]hzCPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers] (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId})}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjaubh)}(hThe support for Extended APIC ID can be detected by checking for the presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).h](hQThe support for Extended APIC ID can be detected by checking for the presence of }(hjshhhNhNubj)}(h`TopologyExtensions`h]hTopologyExtensions}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjsubh in }(hjshhhNhNubj)}(h `ECX[22]`h]hECX[22]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjsubhT of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).}(hjshhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjaubh)}(hIf Topology Extensions is supported, the APIC ID from `ExtendedApicId` from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology enumeration.h](h6If Topology Extensions is supported, the APIC ID from }(hjhhhNhNubj)}(h`ExtendedApicId`h]hExtendedApicId}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh from CPUID leaf 0x8000001E }(hjhhhNhNubj)}(h `EAX[31:0]`h]h EAX[31:0]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh$ should be preferred over that from }(hjhhhNhNubj)}(h `LocalApicId`h]h LocalApicId}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field of CPUID leaf 0x00000001 }(hjhhhNhNubj)}(h `EBX[31:24]`h]h EBX[31:24]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh for topology enumeration.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjaubh)}(hX:On processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of `number of threads per core` calculated using the `ThreadsPerCore` field in `EBX[15:8]` which describes `number of threads per core - 1`.h](hOn processors of Family 0x17 and above that do not support CPUID leaf 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core ID is calculated using the order of }(hjhhhNhNubj)}(h`number of threads per core`h]hnumber of threads per core}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh calculated using the }(hjhhhNhNubj)}(h`ThreadsPerCore`h]hThreadsPerCore}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh field in }(hjhhhNhNubj)}(h `EBX[15:8]`h]h EBX[15:8]}(hj' hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh which describes }(hjhhhNhNubj)}(h `number of threads per core - 1`h]hnumber of threads per core - 1}(hj9 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjaubh)}(hOn Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the `cu_id` (Compute Unit ID) to detect CPUs that share the compute units.h](h/On Processors of Family 0x15, the Core ID from }(hjQ hhhNhNubj)}(h `EBX[7:0]`h]hEBX[7:0]}(hjY hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQ ubh is used as the }(hjQ hhhNhNubj)}(h`cu_id`h]hcu_id}(hjk hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQ ubh? (Compute Unit ID) to detect CPUs that share the compute units.}(hjQ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjaubeh}(h]h ]h"]h$]h&]uh1jhjvubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix)uh1j_hjdubh)}(hXAll AMD processors that support the `TopologyExtensions` feature store the `NodeId` from the `ECX[7:0]` of CPUID leaf 0x8000001E (Core::X86::Cpuid::NodeId) as the per-CPU `node_id`. On older processors, the `node_id` was discovered using MSR_FAM10H_NODE_ID MSR (MSR 0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking `ECX[19]` of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).h](h$All AMD processors that support the }(hj hhhNhNubj)}(h`TopologyExtensions`h]hTopologyExtensions}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh feature store the }(hj hhhNhNubj)}(h`NodeId`h]hNodeId}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh from the }(hj hhhNhNubj)}(h `ECX[7:0]`h]hECX[7:0]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhD of CPUID leaf 0x8000001E (Core::X86::Cpuid::NodeId) as the per-CPU }(hj hhhNhNubj)}(h `node_id`h]hnode_id}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh. On older processors, the }(hj hhhNhNubj)}(h `node_id`h]hnode_id}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh{ was discovered using MSR_FAM10H_NODE_ID MSR (MSR 0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking }(hj hhhNhNubj)}(h `ECX[19]`h]hECX[19]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhT of CPUID leaf 0x80000001 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjdubeh}(h]h ]h"]h$]h&]uh1jhjahhhhhNubj)}(hX Intel On Intel platforms, the CPUID leaves that enumerate the processor topology are as follows: 1) CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf) The CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level. The support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket. The kernel uses the value from `EAX[4:0]` to discover the number of bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]` to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. If CPUID leaf 0x1F is supported, further parsing is not required. 2) CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf) The extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology. The support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if `EBX[31:0]` at a particular level (starting from 0) is non-zero. CPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner. If CPUID leaf 0xB is supported, further parsing is not required. 3) CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) On Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache. Processors that feature Hyper-Threading is detected using `EDX[28]` of CPUID leaf 0x1 (Basic CPUID Information). The order of `Maximum number of addressable IDs for logical processors sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID. The APIC ID and Package information is computed using the data from CPUID leaf 0x1. 4) CPUID leaf 0x00000001 (Basic CPUID Information) The mask and shifts to derive the Physical Package (socket) ID is computed using the `Maximum number of addressable IDs for logical processors in this physical package` from `EBX[23:16]` of CPUID leaf 0x1. The APIC ID on the legacy platforms is derived from the `Initial APIC ID` field from `EBX[31:24]` of CPUID leaf 0x1. h](h)}(hIntelh]hIntel}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(hZOn Intel platforms, the CPUID leaves that enumerate the processor topology are as follows:h]hZOn Intel platforms, the CPUID leaves that enumerate the processor topology are as follows:}(hj& hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubj`)}(hhh](j)}(hX[CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf) The CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level. The support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level (starting from 0) is non-zero. The `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket. The kernel uses the value from `EAX[4:0]` to discover the number of bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]` to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level. If CPUID leaf 0x1F is supported, further parsing is not required. h](h)}(h7CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf)h]h7CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf)}(hj; hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj7 ubh)}(hThe CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level.h]hThe CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides the topology information of Core, Module, Tile, Die, DieGrp, and Socket in each level.}(hjI hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj7 ubh)}(hThe support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level (starting from 0) is non-zero.h](hdThe support for the leaf is discovered by checking if the supported CPUID level is >= 0x1F and then }(hjW hhhNhNubj)}(h `EBX[31:0]`h]h EBX[31:0]}(hj_ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjW ubh5 at a particular level (starting from 0) is non-zero.}(hjW hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj7 ubh)}(hThe `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket.h](hThe }(hjw hhhNhNubj)}(h `Domain Type`h]h Domain Type}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjw ubh in }(hjw hhhNhNubj)}(h `ECX[15:8]`h]h ECX[15:8]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjw ubhu of the sub-leaf provides the topology domain that the level describes - Core, Module, Tile, Die, DieGrp, and Socket.}(hjw hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj7 ubh)}(hXThe kernel uses the value from `EAX[4:0]` to discover the number of bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]` to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.h](hThe kernel uses the value from }(hj hhhNhNubj)}(h `EAX[4:0]`h]hEAX[4:0]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhG to discover the number of bits that need to be right shifted from the }(hj hhhNhNubj)}(h `x2APIC ID`h]h x2APIC ID}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh in }(hj hhhNhNubj)}(h `EDX[31:0]`h]h EDX[31:0]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhv to get a unique Topology ID for the topology level. CPUs with the same Topology ID share the resources at that level.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj7 ubh)}(hAIf CPUID leaf 0x1F is supported, further parsing is not required.h]hAIf CPUID leaf 0x1F is supported, further parsing is not required.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj7 ubeh}(h]h ]h"]h$]h&]uh1jhj4 ubj)}(hXUCPUID leaf 0x0000000B (Extended Topology Enumeration Leaf) The extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology. The support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if `EBX[31:0]` at a particular level (starting from 0) is non-zero. CPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner. If CPUID leaf 0xB is supported, further parsing is not required. h](h)}(h:CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf)h]h:CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(hThe extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology.h]hThe extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended Topology Enumeration Leaf 0x1F and only describes the core, and the socket domains of the processor topology.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(hThe support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if `EBX[31:0]` at a particular level (starting from 0) is non-zero.h](hnThe support for the leaf is iscovered by checking if the supported CPUID level is >= 0xB and then checking if }(hj! hhhNhNubj)}(h `EBX[31:0]`h]h EBX[31:0]}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj! ubh5 at a particular level (starting from 0) is non-zero.}(hj! hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM!hj ubh)}(hmCPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner.h]hmCPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and should be enumerated in a similar manner.}(hjA hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hj ubh)}(h@If CPUID leaf 0xB is supported, further parsing is not required.h]h@If CPUID leaf 0xB is supported, further parsing is not required.}(hjO hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM(hj ubeh}(h]h ]h"]h$]h&]uh1jhj4 ubj)}(hX{CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) On Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache. Processors that feature Hyper-Threading is detected using `EDX[28]` of CPUID leaf 0x1 (Basic CPUID Information). The order of `Maximum number of addressable IDs for logical processors sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID. The APIC ID and Package information is computed using the data from CPUID leaf 0x1. h](h)}(h;CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf)h]h;CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf)}(hjg hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM+hjc ubh)}(hOn Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache.h]hOn Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf 0xB, the shifts for the SMT domains is calculated using the number of CPUs sharing the L1 cache.}(hju hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM-hjc ubh)}(hpProcessors that feature Hyper-Threading is detected using `EDX[28]` of CPUID leaf 0x1 (Basic CPUID Information).h](h:Processors that feature Hyper-Threading is detected using }(hj hhhNhNubj)}(h `EDX[28]`h]hEDX[28]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh- of CPUID leaf 0x1 (Basic CPUID Information).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM1hjc ubh)}(hThe order of `Maximum number of addressable IDs for logical processors sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID.h](h The order of }(hj hhhNhNubj)}(hM`Maximum number of addressable IDs for logical processors sharing this cache`h]hKMaximum number of addressable IDs for logical processors sharing this cache}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh from }(hj hhhNhNubj)}(h `EAX[25:14]`h]h EAX[25:14]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh^ of level-0 of CPUID 0x4 provides the shifts from the APIC ID required to compute the Core ID.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM4hjc ubh)}(hSThe APIC ID and Package information is computed using the data from CPUID leaf 0x1.h]hSThe APIC ID and Package information is computed using the data from CPUID leaf 0x1.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM8hjc ubeh}(h]h ]h"]h$]h&]uh1jhj4 ubj)}(hCPUID leaf 0x00000001 (Basic CPUID Information) The mask and shifts to derive the Physical Package (socket) ID is computed using the `Maximum number of addressable IDs for logical processors in this physical package` from `EBX[23:16]` of CPUID leaf 0x1. h](h)}(h/CPUID leaf 0x00000001 (Basic CPUID Information)h]h/CPUID leaf 0x00000001 (Basic CPUID Information)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM<hj ubh)}(hThe mask and shifts to derive the Physical Package (socket) ID is computed using the `Maximum number of addressable IDs for logical processors in this physical package` from `EBX[23:16]` of CPUID leaf 0x1.h](hUThe mask and shifts to derive the Physical Package (socket) ID is computed using the }(hj hhhNhNubj)}(hS`Maximum number of addressable IDs for logical processors in this physical package`h]hQMaximum number of addressable IDs for logical processors in this physical package}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh from }(hj hhhNhNubj)}(h `EBX[23:16]`h]h EBX[23:16]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh of CPUID leaf 0x1.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM>hj ubeh}(h]h ]h"]h$]h&]uh1jhj4 ubeh}(h]h ]h"]h$]h&]j j j hj j uh1j_hj ubj~)}(hvThe APIC ID on the legacy platforms is derived from the `Initial APIC ID` field from `EBX[31:24]` of CPUID leaf 0x1. h]h)}(htThe APIC ID on the legacy platforms is derived from the `Initial APIC ID` field from `EBX[31:24]` of CPUID leaf 0x1.h](h8The APIC ID on the legacy platforms is derived from the }(hj= hhhNhNubj)}(h`Initial APIC ID`h]hInitial APIC ID}(hjE hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj= ubh field from }(hj= hhhNhNubj)}(h `EBX[31:24]`h]h EBX[31:24]}(hjW hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj= ubh of CPUID leaf 0x1.}(hj= hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMChj9 ubah}(h]h ]h"]h$]h&]uh1j}hhhMChj ubeh}(h]h ]h"]h$]h&]uh1jhjahhhhhNubj)}(hCentaur and Zhaoxin Similar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001 (Basic CPUID Information) to derive the topology information. h](h)}(hCentaur and Zhaoxinh]hCentaur and Zhaoxin}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMGhj{ ubh)}(hSimilar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001 (Basic CPUID Information) to derive the topology information.h]hSimilar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001 (Basic CPUID Information) to derive the topology information.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMIhj{ ubeh}(h]h ]h"]h$]h&]uh1jhjahhhhhNubeh}(h]h ]h"]h$]h&]j j j hj j uh1j_hj2hhhhhKubeh}(h]system-topology-enumerationah ]h"]system topology enumerationah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hSystem topology examplesh]hSystem topology examples}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMPubhnote)}(hXVThe alternative Linux CPU enumeration depends on how the BIOS enumerates the threads. Many BIOSes enumerate all threads 0 first and then all threads 1. That has the "advantage" that the logical Linux CPU numbers of threads 0 stay the same whether threads are enabled or not. That's merely an implementation detail and has no practical impact.Dh]h)}(hXVThe alternative Linux CPU enumeration depends on how the BIOS enumerates the threads. Many BIOSes enumerate all threads 0 first and then all threads 1. That has the "advantage" that the logical Linux CPU numbers of threads 0 stay the same whether threads are enabled or not. That's merely an implementation detail and has no practical impact.h]hX\The alternative Linux CPU enumeration depends on how the BIOS enumerates the threads. Many BIOSes enumerate all threads 0 first and then all threads 1. That has the “advantage” that the logical Linux CPU numbers of threads 0 stay the same whether threads are enabled or not. That’s merely an implementation detail and has no practical impact.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMShj ubah}(h]h ]h"]h$]h&]uh1j hj hhhhhNubj`)}(hhh](j)}(hTSingle Package, Single Core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 h](h)}(hSingle Package, Single Core::h]hSingle Package, Single Core:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMYhj ubh literal_block)}(h4[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0h]h4[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhM[hj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hXSingle Package, Dual Core a) One thread per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 b) Two threads per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3 Alternative enumeration:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 3 AMD nomenclature for CMT systems:: [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3 h](h)}(hSingle Package, Dual Coreh]hSingle Package, Dual Core}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM]hj ubj`)}(hhh](j)}(hOne thread per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 h](h)}(hOne thread per core::h]hOne thread per core:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM_hj ubj )}(hi[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1h]hi[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1}hj, sbah}(h]h ]h"]h$]h&]hhuh1j hhhMahj ubeh}(h]h ]h"]h$]h&]uh1jhj ubj)}(hX-Two threads per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3 Alternative enumeration:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 3 AMD nomenclature for CMT systems:: [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3 h](h)}(hTwo threads per core::h]hTwo threads per core:}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMdhj@ ubj )}(h[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3h]h[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3}hjR sbah}(h]h ]h"]h$]h&]hhuh1j hhhMfhj@ ubh)}(hAlternative enumeration::h]hAlternative enumeration:}(hj` hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMkhj@ ubj )}(h[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 3h]h[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 3}hjn sbah}(h]h ]h"]h$]h&]hhuh1j hhhMmhj@ ubh)}(h"AMD nomenclature for CMT systems::h]h!AMD nomenclature for CMT systems:}(hj| hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMrhj@ ubj )}(hX[node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3h]hX[node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhMthj@ ubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]j loweralphaj hj j uh1j_hj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhNhNubeh}(h]h ]h"]h$]h&]j j j hj j uh1j_hj hhhhhMYubj`)}(hhh]j)}(hXqDual Package, Dual Core a) One thread per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 3 b) Two threads per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4 -> [thread 1] -> Linux CPU 5 -> [core 1] -> [thread 0] -> Linux CPU 6 -> [thread 1] -> Linux CPU 7 Alternative enumeration:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 4 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 5 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 6 -> [core 1] -> [thread 0] -> Linux CPU 3 -> [thread 1] -> Linux CPU 7 AMD nomenclature for CMT systems:: [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3 [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4 -> [Compute Unit Core 1] -> Linux CPU 5 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6 -> [Compute Unit Core 1] -> Linux CPU 7h](h)}(hDual Package, Dual Coreh]hDual Package, Dual Core}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMyhj ubj`)}(hhh](j)}(hOne thread per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 3 h](h)}(hOne thread per core::h]hOne thread per core:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM{hj ubj )}(h[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 3h]h[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [core 1] -> [thread 0] -> Linux CPU 1 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [core 1] -> [thread 0] -> Linux CPU 3}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhM}hj ubeh}(h]h ]h"]h$]h&]uh1jhj ubj)}(hXTwo threads per core:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4 -> [thread 1] -> Linux CPU 5 -> [core 1] -> [thread 0] -> Linux CPU 6 -> [thread 1] -> Linux CPU 7 Alternative enumeration:: [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 4 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 5 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 6 -> [core 1] -> [thread 0] -> Linux CPU 3 -> [thread 1] -> Linux CPU 7 AMD nomenclature for CMT systems:: [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3 [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4 -> [Compute Unit Core 1] -> Linux CPU 5 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6 -> [Compute Unit Core 1] -> Linux CPU 7h](h)}(hTwo threads per core::h]hTwo threads per core:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubj )}(hX[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4 -> [thread 1] -> Linux CPU 5 -> [core 1] -> [thread 0] -> Linux CPU 6 -> [thread 1] -> Linux CPU 7h]hX[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 1 -> [core 1] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 3 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4 -> [thread 1] -> Linux CPU 5 -> [core 1] -> [thread 0] -> Linux CPU 6 -> [thread 1] -> Linux CPU 7}hjsbah}(h]h ]h"]h$]h&]hhuh1j hhhMhj ubh)}(hAlternative enumeration::h]hAlternative enumeration:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubj )}(hX[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 4 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 5 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 6 -> [core 1] -> [thread 0] -> Linux CPU 3 -> [thread 1] -> Linux CPU 7h]hX[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 -> [thread 1] -> Linux CPU 4 -> [core 1] -> [thread 0] -> Linux CPU 1 -> [thread 1] -> Linux CPU 5 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 -> [thread 1] -> Linux CPU 6 -> [core 1] -> [thread 0] -> Linux CPU 3 -> [thread 1] -> Linux CPU 7}hjsbah}(h]h ]h"]h$]h&]hhuh1j hhhMhj ubh)}(h"AMD nomenclature for CMT systems::h]h!AMD nomenclature for CMT systems:}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubj )}(hX([node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3 [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4 -> [Compute Unit Core 1] -> Linux CPU 5 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6 -> [Compute Unit Core 1] -> Linux CPU 7h]hX([node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 -> [Compute Unit Core 1] -> Linux CPU 1 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 -> [Compute Unit Core 1] -> Linux CPU 3 [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4 -> [Compute Unit Core 1] -> Linux CPU 5 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6 -> [Compute Unit Core 1] -> Linux CPU 7}hj9sbah}(h]h ]h"]h$]h&]hhuh1j hhhMhj ubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]j j j hj j uh1j_hj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhNhNubah}(h]h ]h"]h$]h&]j j j hj j startKuh1j_hj hhhhhMyubeh}(h]system-topology-examplesah ]h"]system topology examplesah$]h&]uh1hhhhhhhhMPubeh}(h] x86-topologyah ]h"] x86 topologyah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jmjjjjjjj/j,j j jejbu nametypes}(jmjjj/j jeuh}(jjhjjjjj,jj j2jbj u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]hsystem_message)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "4" (ordinal 4)h]h>Enumerated list start value not ordinal-1: “4” (ordinal 4)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1jhj hhhhhMyubatransform_messages] transformerN include_log] decorationNhhub.