← Documents Documentation/arch/x86/topology.rst GitHub 원문 ↗

Linux 6.18.37 · Architecture

x86 Topology

x86 package·core·thread 모델, vendor별 CPUID enumeration과 CPU 번호 예시를 설명합니다.

Source pathDocumentation/arch/x86/topology.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

topology.rst:1-421

x86 topology는 software에 의미 없는 physical socket 대신 package, core, thread 단위로 표현합니다. kernel은 generic topology API와 `cpuinfo_x86.topo` field로 physical·logical package, die, LLC와 sibling 관계를 제공합니다.

AMD와 Intel은 최신 extended topology CPUID leaf부터 legacy cache·APIC field까지 우선순위대로 parse합니다. 마지막 구조화 표는 BIOS의 thread enumeration 순서와 AMD CMT 명칭이 Linux CPU 번호에 어떻게 대응하는지 보여 줍니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ============
4 x86 Topology
5 ============
6
7 This documents and clarifies the main aspects of x86 topology modelling and
8 representation in the kernel. Update/change when doing changes to the
9 respective code.
10
11 The architecture-agnostic topology definitions are in
12 Documentation/admin-guide/cputopology.rst. This file holds x86-specific
13 differences/specialities which must not necessarily apply to the generic
14 definitions. Thus, the way to read up on Linux topology on x86 is to start
15 with the generic one and look at this one in parallel for the x86 specifics.
16
17 Needless to say, code should use the generic functions - this file is *only*
18 here to *document* the inner workings of x86 topology.
19
20 Started by Thomas Gleixner <[email protected]> and Borislav Petkov <[email protected]>.
21
22 The main aim of the topology facilities is to present adequate interfaces to
23 code which needs to know/query/use the structure of the running system wrt
24 threads, cores, packages, etc.
25
26 The kernel does not care about the concept of physical sockets because a
27 socket has no relevance to software. It's an electromechanical component. In
28 the past a socket always contained a single package (see below), but with the
29 advent of Multi Chip Modules (MCM) a socket can hold more than one package. So
30 there might be still references to sockets in the code, but they are of
31 historical nature and should be cleaned up.
32
33 The topology of a system is described in the units of:
34
35 - packages
36 - cores
37 - threads
38
39 Package
40 =======
41 Packages contain a number of cores plus shared resources, e.g. DRAM
42 controller, shared caches etc.
43
44 Modern systems may also use the term 'Die' for package.
45
46 AMD nomenclature for package is 'Node'.
47
48 Package-related topology information in the kernel:
49
50 - topology_num_threads_per_package()
51
52 The number of threads in a package.
53
54 - topology_num_cores_per_package()
55
56 The number of cores in a package.
57
58 - topology_max_dies_per_package()
59
60 The maximum number of dies in a package.
61
62 - cpuinfo_x86.topo.die_id:
63
64 The physical ID of the die.
65
66 - cpuinfo_x86.topo.pkg_id:
67
68 The physical ID of the package. This information is retrieved via CPUID
69 and deduced from the APIC IDs of the cores in the package.
70
71 Modern systems use this value for the socket. There may be multiple
72 packages within a socket. This value may differ from topo.die_id.
73
74 - cpuinfo_x86.topo.logical_pkg_id:
75
76 The logical ID of the package. As we do not trust BIOSes to enumerate the
77 packages in a consistent way, we introduced the concept of logical package
78 ID so we can sanely calculate the number of maximum possible packages in
79 the system and have the packages enumerated linearly.
80
81 - topology_max_packages():
82
83 The maximum possible number of packages in the system. Helpful for per
84 package facilities to preallocate per package information.
85
86 - cpuinfo_x86.topo.llc_id:
87
88 - On Intel, the first APIC ID of the list of CPUs sharing the Last Level
89 Cache
90
91 - On AMD, the Node ID or Core Complex ID containing the Last Level
92 Cache. In general, it is a number identifying an LLC uniquely on the
93 system.
94
95 Cores
96 =====
97 A core consists of 1 or more threads. It does not matter whether the threads
98 are SMT- or CMT-type threads.
99
100 AMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses
101 "core".
102
103 Threads
104 =======
105 A thread is a single scheduling unit. It's the equivalent to a logical Linux
106 CPU.
107
108 AMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always
109 uses "thread".
110
111 Thread-related topology information in the kernel:
112
113 - topology_core_cpumask():
114
115 The cpumask contains all online threads in the package to which a thread
116 belongs.
117
118 The number of online threads is also printed in /proc/cpuinfo "siblings."
119
120 - topology_sibling_cpumask():
121
122 The cpumask contains all online threads in the core to which a thread
123 belongs.
124
125 - topology_logical_package_id():
126
127 The logical package ID to which a thread belongs.
128
129 - topology_physical_package_id():
130
131 The physical package ID to which a thread belongs.
132
133 - topology_core_id();
134
135 The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo
136 "core_id."
137
138 - topology_logical_core_id();
139
140 The logical core ID to which a thread belongs.
141
142
143
144 System topology enumeration
145 ===========================
146
147 The topology on x86 systems can be discovered using a combination of vendor
148 specific CPUID leaves which enumerate the processor topology and the cache
149 hierarchy.
150
151 The CPUID leaves in their preferred order of parsing for each x86 vendor is as
152 follows:
153
154 1) AMD
155
156 1) CPUID leaf 0x80000026 [Extended CPU Topology] (Core::X86::Cpuid::ExCpuTopology)
157
158 The extended CPUID leaf 0x80000026 is the extension of the CPUID leaf 0xB
159 and provides the topology information of Core, Complex, CCD (Die), and
160 Socket in each level.
161
162 Support for the leaf is discovered by checking if the maximum extended
163 CPUID level is >= 0x80000026 and then checking if `LogProcAtThisLevel`
164 in `EBX[15:0]` at a particular level (starting from 0) is non-zero.
165
166 The `LevelType` in `ECX[15:8]` at the level provides the topology domain
167 the level describes - Core, Complex, CCD(Die), or the Socket.
168
169 The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the
170 number of bits that need to be right-shifted from `ExtendedLocalApicId`
171 in `EDX[31:0]` in order to get a unique Topology ID for the topology
172 level. CPUs with the same Topology ID share the resources at that level.
173
174 CPUID leaf 0x80000026 also provides more information regarding the power
175 and efficiency rankings, and about the core type on AMD processors with
176 heterogeneous characteristics.
177
178 If CPUID leaf 0x80000026 is supported, further parsing is not required.
179
180 2) CPUID leaf 0x0000000B [Extended Topology Enumeration] (Core::X86::Cpuid::ExtTopEnum)
181
182 The extended CPUID leaf 0x0000000B is the predecessor on the extended
183 CPUID leaf 0x80000026 and only describes the core, and the socket domains
184 of the processor topology.
185
186 The support for the leaf is discovered by checking if the maximum supported
187 CPUID level is >= 0xB and then if `EBX[31:0]` at a particular level
188 (starting from 0) is non-zero.
189
190 The `LevelType` in `ECX[15:8]` at the level provides the topology domain
191 that the level describes - Thread, or Processor (Socket).
192
193 The kernel uses the `CoreMaskWidth` from `EAX[4:0]` to discover the
194 number of bits that need to be right-shifted from the `ExtendedLocalApicId`
195 in `EDX[31:0]` to get a unique Topology ID for that topology level. CPUs
196 sharing the Topology ID share the resources at that level.
197
198 If CPUID leaf 0xB is supported, further parsing is not required.
199
200
201 3) CPUID leaf 0x80000008 ECX [Size Identifiers] (Core::X86::Cpuid::SizeId)
202
203 If neither the CPUID leaf 0x80000026 nor 0xB is supported, the number of
204 CPUs on the package is detected using the Size Identifier leaf
205 0x80000008 ECX.
206
207 The support for the leaf is discovered by checking if the supported
208 extended CPUID level is >= 0x80000008.
209
210 The shifts from the APIC ID for the Socket ID is calculated from the
211 `ApicIdSize` field in `ECX[15:12]` if it is non-zero.
212
213 If `ApicIdSize` is reported to be zero, the shift is calculated as the
214 order of the `number of threads` calculated from `NC` field in
215 `ECX[7:0]` which describes the `number of threads - 1` on the package.
216
217 Unless Extended APIC ID is supported, the APIC ID used to find the
218 Socket ID is from the `LocalApicId` field of CPUID leaf 0x00000001
219 `EBX[31:24]`.
220
221 The topology parsing continues to detect if Extended APIC ID is
222 supported or not.
223
224
225 4) CPUID leaf 0x8000001E [Extended APIC ID, Core Identifiers, Node Identifiers]
226 (Core::X86::Cpuid::{ExtApicId,CoreId,NodeId})
227
228 The support for Extended APIC ID can be detected by checking for the
229 presence of `TopologyExtensions` in `ECX[22]` of CPUID leaf 0x80000001
230 [Feature Identifiers] (Core::X86::Cpuid::FeatureExtIdEcx).
231
232 If Topology Extensions is supported, the APIC ID from `ExtendedApicId`
233 from CPUID leaf 0x8000001E `EAX[31:0]` should be preferred over that from
234 `LocalApicId` field of CPUID leaf 0x00000001 `EBX[31:24]` for topology
235 enumeration.
236
237 On processors of Family 0x17 and above that do not support CPUID leaf
238 0x80000026 or CPUID leaf 0xB, the shifts from the APIC ID for the Core
239 ID is calculated using the order of `number of threads per core`
240 calculated using the `ThreadsPerCore` field in `EBX[15:8]` which
241 describes `number of threads per core - 1`.
242
243 On Processors of Family 0x15, the Core ID from `EBX[7:0]` is used as the
244 `cu_id` (Compute Unit ID) to detect CPUs that share the compute units.
245
246
247 All AMD processors that support the `TopologyExtensions` feature store the
248 `NodeId` from the `ECX[7:0]` of CPUID leaf 0x8000001E
249 (Core::X86::Cpuid::NodeId) as the per-CPU `node_id`. On older processors,
250 the `node_id` was discovered using MSR_FAM10H_NODE_ID MSR (MSR
251 0x0xc001_100c). The presence of the NODE_ID MSR was detected by checking
252 `ECX[19]` of CPUID leaf 0x80000001 [Feature Identifiers]
253 (Core::X86::Cpuid::FeatureExtIdEcx).
254
255
256 2) Intel
257
258 On Intel platforms, the CPUID leaves that enumerate the processor
259 topology are as follows:
260
261 1) CPUID leaf 0x1F (V2 Extended Topology Enumeration Leaf)
262
263 The CPUID leaf 0x1F is the extension of the CPUID leaf 0xB and provides
264 the topology information of Core, Module, Tile, Die, DieGrp, and Socket
265 in each level.
266
267 The support for the leaf is discovered by checking if the supported
268 CPUID level is >= 0x1F and then `EBX[31:0]` at a particular level
269 (starting from 0) is non-zero.
270
271 The `Domain Type` in `ECX[15:8]` of the sub-leaf provides the topology
272 domain that the level describes - Core, Module, Tile, Die, DieGrp, and
273 Socket.
274
275 The kernel uses the value from `EAX[4:0]` to discover the number of
276 bits that need to be right shifted from the `x2APIC ID` in `EDX[31:0]`
277 to get a unique Topology ID for the topology level. CPUs with the same
278 Topology ID share the resources at that level.
279
280 If CPUID leaf 0x1F is supported, further parsing is not required.
281
282
283 2) CPUID leaf 0x0000000B (Extended Topology Enumeration Leaf)
284
285 The extended CPUID leaf 0x0000000B is the predecessor of the V2 Extended
286 Topology Enumeration Leaf 0x1F and only describes the core, and the
287 socket domains of the processor topology.
288
289 The support for the leaf is iscovered by checking if the supported CPUID
290 level is >= 0xB and then checking if `EBX[31:0]` at a particular level
291 (starting from 0) is non-zero.
292
293 CPUID leaf 0x0000000B shares the same layout as CPUID leaf 0x1F and
294 should be enumerated in a similar manner.
295
296 If CPUID leaf 0xB is supported, further parsing is not required.
297
298
299 3) CPUID leaf 0x00000004 (Deterministic Cache Parameters Leaf)
300
301 On Intel processors that support neither CPUID leaf 0x1F, nor CPUID leaf
302 0xB, the shifts for the SMT domains is calculated using the number of
303 CPUs sharing the L1 cache.
304
305 Processors that feature Hyper-Threading is detected using `EDX[28]` of
306 CPUID leaf 0x1 (Basic CPUID Information).
307
308 The order of `Maximum number of addressable IDs for logical processors
309 sharing this cache` from `EAX[25:14]` of level-0 of CPUID 0x4 provides
310 the shifts from the APIC ID required to compute the Core ID.
311
312 The APIC ID and Package information is computed using the data from
313 CPUID leaf 0x1.
314
315
316 4) CPUID leaf 0x00000001 (Basic CPUID Information)
317
318 The mask and shifts to derive the Physical Package (socket) ID is
319 computed using the `Maximum number of addressable IDs for logical
320 processors in this physical package` from `EBX[23:16]` of CPUID leaf
321 0x1.
322
323 The APIC ID on the legacy platforms is derived from the `Initial APIC
324 ID` field from `EBX[31:24]` of CPUID leaf 0x1.
325
326
327 3) Centaur and Zhaoxin
328
329 Similar to Intel, Centaur and Zhaoxin use a combination of CPUID leaf
330 0x00000004 (Deterministic Cache Parameters Leaf) and CPUID leaf 0x00000001
331 (Basic CPUID Information) to derive the topology information.
332
333
334
335 System topology examples
336 ========================
337
338 .. note::
339 The alternative Linux CPU enumeration depends on how the BIOS enumerates the
340 threads. Many BIOSes enumerate all threads 0 first and then all threads 1.
341 That has the "advantage" that the logical Linux CPU numbers of threads 0 stay
342 the same whether threads are enabled or not. That's merely an implementation
343 detail and has no practical impact.
344
345 1) Single Package, Single Core::
346
347 [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
348
349 2) Single Package, Dual Core
350
351 a) One thread per core::
352
353 [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
354 -> [core 1] -> [thread 0] -> Linux CPU 1
355
356 b) Two threads per core::
357
358 [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
359 -> [thread 1] -> Linux CPU 1
360 -> [core 1] -> [thread 0] -> Linux CPU 2
361 -> [thread 1] -> Linux CPU 3
362
363 Alternative enumeration::
364
365 [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
366 -> [thread 1] -> Linux CPU 2
367 -> [core 1] -> [thread 0] -> Linux CPU 1
368 -> [thread 1] -> Linux CPU 3
369
370 AMD nomenclature for CMT systems::
371
372 [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
373 -> [Compute Unit Core 1] -> Linux CPU 1
374 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
375 -> [Compute Unit Core 1] -> Linux CPU 3
376
377 4) Dual Package, Dual Core
378
379 a) One thread per core::
380
381 [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
382 -> [core 1] -> [thread 0] -> Linux CPU 1
383
384 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
385 -> [core 1] -> [thread 0] -> Linux CPU 3
386
387 b) Two threads per core::
388
389 [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
390 -> [thread 1] -> Linux CPU 1
391 -> [core 1] -> [thread 0] -> Linux CPU 2
392 -> [thread 1] -> Linux CPU 3
393
394 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4
395 -> [thread 1] -> Linux CPU 5
396 -> [core 1] -> [thread 0] -> Linux CPU 6
397 -> [thread 1] -> Linux CPU 7
398
399 Alternative enumeration::
400
401 [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
402 -> [thread 1] -> Linux CPU 4
403 -> [core 1] -> [thread 0] -> Linux CPU 1
404 -> [thread 1] -> Linux CPU 5
405
406 [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
407 -> [thread 1] -> Linux CPU 6
408 -> [core 1] -> [thread 0] -> Linux CPU 3
409 -> [thread 1] -> Linux CPU 7
410
411 AMD nomenclature for CMT systems::
412
413 [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
414 -> [Compute Unit Core 1] -> Linux CPU 1
415 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
416 -> [Compute Unit Core 1] -> Linux CPU 3
417
418 [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4
419 -> [Compute Unit Core 1] -> Linux CPU 5
420 -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6
421 -> [Compute Unit Core 1] -> Linux CPU 7
422

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

x86 topology 모델의 범위

1-38

이 문서는 `SPDX-License-Identifier: GPL-2.0`으로 배포됩니다. kernel에서 x86 topology를 model하고 표현하는 주요 측면을 문서화하고 명확히 설명합니다. 관련 code를 변경할 때 이 문서도 갱신해야 합니다.

architecture-independent topology 정의는 `Documentation/admin-guide/cputopology.rst`에 있습니다. 이 문서는 generic 정의에 반드시 적용되지는 않는 x86-specific 차이와 특성을 다룹니다. Linux x86 topology를 이해하려면 generic 문서를 먼저 읽고 x86-specific 내용은 이 문서와 나란히 확인해야 합니다.

code에서는 generic function을 사용해야 합니다. 이 문서는 x86 topology의 내부 동작을 문서화하기 위한 것일 뿐입니다.

Thomas Gleixner `<[email protected]>`와 Borislav Petkov `<[email protected]>`가 이 문서를 시작했습니다.

topology facility의 주 목적은 실행 중인 system의 thread, core, package 등의 구조를 알아야 하거나 query·사용해야 하는 code에 적절한 interface를 제공하는 것입니다.

kernel은 physical socket 개념을 중요하게 여기지 않습니다. socket은 software와 무관한 electromechanical component입니다. 과거에는 socket 하나가 항상 package 하나를 담았지만 Multi Chip Modules(MCM)가 등장하면서 socket 하나에 package가 여러 개 들어갈 수 있게 됐습니다. code에 남은 socket 참조는 역사적인 것이며 정리해야 합니다.

system topology는 다음 단위로 설명합니다.

  • package
  • core
  • thread

package와 kernel topology 정보

39-94

package는 여러 core와 DRAM controller, shared cache 같은 shared resource를 포함합니다. 현대 system에서는 package를 `Die`라고 부르기도 하며 AMD 명칭은 `Node`입니다.

kernel의 package 관련 topology 정보는 다음과 같습니다.

interface 또는 field의미
`topology_num_threads_per_package()`package에 포함된 thread 수입니다.
`topology_num_cores_per_package()`package에 포함된 core 수입니다.
`topology_max_dies_per_package()`package 하나에 들어갈 수 있는 최대 die 수입니다.
`cpuinfo_x86.topo.die_id`die의 physical ID입니다.
`cpuinfo_x86.topo.pkg_id`package의 physical ID입니다. CPUID로 얻고 package 안 core의 APIC ID에서 유도합니다. 현대 system은 이 값을 socket에 사용하지만 socket 하나에 package가 여러 개 있을 수 있어 `topo.die_id`와 다를 수 있습니다.
`cpuinfo_x86.topo.logical_pkg_id`package의 logical ID입니다. BIOS가 package를 일관되게 enumerate한다고 신뢰할 수 없으므로, 최대 possible package 수를 합리적으로 계산하고 package를 선형으로 enumerate하기 위해 도입했습니다.
`topology_max_packages()`system에 존재할 수 있는 최대 package 수입니다. package별 facility가 정보를 미리 allocate할 때 유용합니다.
`cpuinfo_x86.topo.llc_id`Intel에서는 Last Level Cache를 공유하는 CPU 목록의 첫 APIC ID입니다. AMD에서는 LLC를 포함하는 Node ID 또는 Core Complex ID이며, 일반적으로 system에서 LLC 하나를 고유하게 식별하는 값입니다.

core와 thread

95-143

core는 하나 이상의 thread로 구성됩니다. thread가 SMT type인지 CMT type인지는 중요하지 않습니다. AMD는 CMT core를 `Compute Unit`이라고 부르지만 kernel은 항상 `core`라는 용어를 사용합니다.

thread는 단일 scheduling unit이며 logical Linux CPU와 같습니다. AMD는 CMT thread를 `Compute Unit Core`라고 부르지만 kernel은 항상 `thread`라고 부릅니다.

kernel의 thread 관련 topology 정보는 다음과 같습니다.

interface의미
`topology_core_cpumask()`thread가 속한 package의 online thread를 모두 포함하는 cpumask입니다. online thread 수는 `/proc/cpuinfo`의 `siblings`에도 출력됩니다.
`topology_sibling_cpumask()`thread가 속한 core의 online thread를 모두 포함하는 cpumask입니다.
`topology_logical_package_id()`thread가 속한 logical package ID입니다.
`topology_physical_package_id()`thread가 속한 physical package ID입니다.
`topology_core_id()`thread가 속한 core ID입니다. `/proc/cpuinfo`의 `core_id`에도 출력됩니다.
`topology_logical_core_id()`thread가 속한 logical core ID입니다.

AMD CPUID 0x80000026 enumeration

144-179

x86 system topology는 processor topology와 cache hierarchy를 enumerate하는 vendor-specific CPUID leaf 조합으로 탐색합니다. 각 vendor에 대해 아래 우선순위로 CPUID leaf를 parse합니다.

AMD에서 첫 번째 선택은 CPUID leaf `0x80000026` Extended CPU Topology(`Core::X86::Cpuid::ExCpuTopology`)입니다. 이 extended leaf는 CPUID leaf `0xB`를 확장하며 level마다 Core, Complex, CCD(Die), Socket topology 정보를 제공합니다.

maximum extended CPUID level이 `>= 0x80000026`인지 확인한 뒤 0부터 시작하는 특정 level의 `EBX[15:0]`에 있는 `LogProcAtThisLevel`이 0이 아닌지 검사해 지원 여부를 판별합니다.

해당 level의 `ECX[15:8]`에 있는 `LevelType`은 그 level이 설명하는 topology domain이 Core, Complex, CCD(Die), Socket 중 무엇인지 알려 줍니다.

kernel은 `EAX[4:0]`의 `CoreMaskWidth`로 `EDX[31:0]`의 `ExtendedLocalApicId`를 몇 bit right shift해야 해당 topology level의 고유 Topology ID를 얻는지 계산합니다. 같은 Topology ID를 가진 CPU는 그 level의 resource를 공유합니다.

CPUID leaf `0x80000026`은 heterogeneous characteristic을 가진 AMD processor에서 power·efficiency ranking과 core type 정보도 제공합니다. 이 leaf를 지원하면 추가 parsing은 필요하지 않습니다.

AMD CPUID 0xB와 0x80000008 fallback

180-224

AMD의 두 번째 선택은 CPUID leaf `0x0000000B` Extended Topology Enumeration(`Core::X86::Cpuid::ExtTopEnum`)입니다. `0x80000026`의 predecessor이며 processor topology의 core와 socket domain만 설명합니다.

maximum supported CPUID level이 `>= 0xB`인지 확인하고 0부터 시작하는 특정 level의 `EBX[31:0]`이 0이 아닌지 검사해 지원 여부를 판별합니다. 그 level의 `ECX[15:8]`에 있는 `LevelType`은 Thread 또는 Processor(Socket) topology domain을 나타냅니다.

kernel은 `EAX[4:0]`의 `CoreMaskWidth`로 `EDX[31:0]`의 `ExtendedLocalApicId`를 right shift할 bit 수를 알아내고 해당 topology level의 고유 Topology ID를 얻습니다. 같은 Topology ID를 공유하는 CPU는 해당 level의 resource도 공유합니다. CPUID leaf `0xB`를 지원하면 추가 parsing은 필요하지 않습니다.

`0x80000026`과 `0xB`를 모두 지원하지 않으면 세 번째로 CPUID leaf `0x80000008 ECX` Size Identifiers(`Core::X86::Cpuid::SizeId`)를 사용해 package의 CPU 수를 감지합니다. supported extended CPUID level이 `>= 0x80000008`이면 이 leaf를 지원합니다.

`ECX[15:12]`의 `ApicIdSize`가 0이 아니면 이 field로 APIC ID에서 Socket ID를 얻기 위한 shift를 계산합니다. `ApicIdSize`가 0이면 `ECX[7:0]`의 `NC` field에서 계산한 `number of threads`의 order를 shift로 사용합니다. `NC`는 package의 `number of threads - 1`을 나타냅니다.

Extended APIC ID를 지원하지 않으면 Socket ID를 찾는 APIC ID로 CPUID leaf `0x00000001`의 `EBX[31:24]`에 있는 `LocalApicId`를 사용합니다. 이후 topology parsing은 Extended APIC ID 지원 여부를 확인하기 위해 계속됩니다.

AMD Extended APIC ID와 Node ID

225-255

네 번째 AMD source는 CPUID leaf `0x8000001E` Extended APIC ID, Core Identifiers, Node Identifiers(`Core::X86::Cpuid::{ExtApicId,CoreId,NodeId}`)입니다.

CPUID leaf `0x80000001` Feature Identifiers(`Core::X86::Cpuid::FeatureExtIdEcx`)의 `ECX[22]`에 `TopologyExtensions`가 있는지 확인해 Extended APIC ID 지원 여부를 감지합니다.

Topology Extensions를 지원하면 topology enumeration에서 CPUID leaf `0x00000001`의 `EBX[31:24]`에 있는 `LocalApicId`보다 CPUID leaf `0x8000001E`의 `EAX[31:0]`에 있는 `ExtendedApicId`를 우선해야 합니다.

CPUID leaf `0x80000026`이나 `0xB`를 지원하지 않는 Family `0x17` 이상 processor에서는 `EBX[15:8]`의 `ThreadsPerCore`로 계산한 `number of threads per core`의 order를 사용해 APIC ID에서 Core ID를 얻는 shift를 계산합니다. 이 field는 `number of threads per core - 1`을 나타냅니다.

Family `0x15` processor에서는 `EBX[7:0]`의 Core ID를 `cu_id`(Compute Unit ID)로 사용해 compute unit을 공유하는 CPU를 감지합니다.

`TopologyExtensions`를 지원하는 모든 AMD processor는 CPUID leaf `0x8000001E`(`Core::X86::Cpuid::NodeId`)의 `ECX[7:0]`에 있는 `NodeId`를 per-CPU `node_id`로 저장합니다.

구형 processor에서는 `MSR_FAM10H_NODE_ID` MSR(`0x0xc001_100c`)로 `node_id`를 탐색했습니다. NODE_ID MSR의 존재 여부는 CPUID leaf `0x80000001` Feature Identifiers의 `ECX[19]`를 확인해 감지했습니다.

Intel CPUID 0x1F와 0xB enumeration

256-298

Intel platform에서 첫 번째 선택은 CPUID leaf `0x1F` V2 Extended Topology Enumeration Leaf입니다. CPUID leaf `0xB`를 확장하며 level마다 Core, Module, Tile, Die, DieGrp, Socket topology 정보를 제공합니다.

supported CPUID level이 `>= 0x1F`인지 확인하고 0부터 시작하는 특정 level의 `EBX[31:0]`이 0이 아닌지 검사해 지원 여부를 판별합니다.

sub-leaf의 `ECX[15:8]`에 있는 `Domain Type`은 그 level이 Core, Module, Tile, Die, DieGrp, Socket 중 어떤 topology domain을 설명하는지 알려 줍니다.

kernel은 `EAX[4:0]` 값으로 `EDX[31:0]`의 `x2APIC ID`를 몇 bit right shift해야 해당 topology level의 고유 Topology ID를 얻는지 계산합니다. 같은 Topology ID를 가진 CPU는 그 level의 resource를 공유합니다. CPUID leaf `0x1F`를 지원하면 추가 parsing은 필요하지 않습니다.

두 번째 선택인 CPUID leaf `0x0000000B` Extended Topology Enumeration Leaf는 V2 leaf `0x1F`의 predecessor이며 processor topology의 core와 socket domain만 설명합니다.

supported CPUID level이 `>= 0xB`인지 확인한 뒤 특정 level의 `EBX[31:0]`이 0이 아닌지 검사해 지원 여부를 판별합니다. CPUID leaf `0x0000000B`는 `0x1F`와 layout이 같으므로 같은 방식으로 enumerate해야 합니다. `0xB`를 지원하면 추가 parsing은 필요하지 않습니다.

Intel fallback과 Centaur·Zhaoxin

299-334

Intel processor가 CPUID leaf `0x1F`와 `0xB`를 모두 지원하지 않으면 세 번째로 CPUID leaf `0x00000004` Deterministic Cache Parameters Leaf를 사용합니다. SMT domain의 shift는 L1 cache를 공유하는 CPU 수로 계산합니다.

Hyper-Threading을 제공하는 processor는 CPUID leaf `0x1` Basic CPUID Information의 `EDX[28]`로 감지합니다. CPUID `0x4` level 0의 `EAX[25:14]`에 있는 `Maximum number of addressable IDs for logical processors sharing this cache`의 order가 APIC ID에서 Core ID를 계산할 때 필요한 shift를 제공합니다.

APIC ID와 package 정보는 CPUID leaf `0x1`의 data로 계산합니다. physical package(socket) ID를 유도하는 mask와 shift는 CPUID leaf `0x1`의 `EBX[23:16]`에 있는 `Maximum number of addressable IDs for logical processors in this physical package`로 계산합니다.

legacy platform의 APIC ID는 CPUID leaf `0x1`의 `EBX[31:24]`에 있는 `Initial APIC ID` field에서 유도합니다.

Centaur와 Zhaoxin은 Intel과 비슷하게 CPUID leaf `0x00000004` Deterministic Cache Parameters Leaf와 CPUID leaf `0x00000001` Basic CPUID Information을 조합해 topology 정보를 유도합니다.

system topology 구조화 예시

335-421

대안 Linux CPU enumeration은 BIOS가 thread를 enumerate하는 방법에 따라 달라집니다. 많은 BIOS는 모든 thread 0을 먼저 enumerate한 뒤 모든 thread 1을 enumerate합니다. 그러면 thread 활성화 여부와 관계없이 thread 0의 logical Linux CPU number가 유지된다는 `장점`이 있지만, 이는 구현 세부 사항일 뿐 실제 영향은 없습니다.

Single package, single core
packagecorethreadLinux CPU
0000

package 하나, core 하나, thread 하나인 최소 topology입니다.

Single package, dual core: one thread per core
packagecorethreadLinux CPU
0000
0101

각 core에 thread가 하나씩 있는 기본 enumeration입니다.

Single package, dual core: two threads per core
packagecorethreadLinux CPU
0000
0011
0102
0113

core별로 두 thread를 연속 enumerate하는 기본 순서입니다.

Single package, dual core: alternative enumeration
packagecorethreadLinux CPU
0000
0012
0101
0113

모든 thread 0을 먼저 배정한 뒤 thread 1을 배정하는 BIOS 순서입니다.

Single node CMT terminology
nodeCompute UnitCompute Unit CoreLinux CPU
0000
0011
0102
0113

같은 2-core/2-thread 구조를 AMD CMT 명칭으로 나타냈습니다.

Dual package, dual core: one thread per core
packagecorethreadLinux CPU
0000
0101
1002
1103

package 두 개에 core가 두 개씩 있고 thread가 하나씩 있는 topology입니다.

Dual package, dual core: two threads per core
packagecorethreadLinux CPU
0000
0011
0102
0113
1004
1015
1106
1117

package, core, thread 순으로 연속 enumerate하는 기본 순서입니다.

Dual package, dual core: alternative enumeration
packagecorethreadLinux CPU
0000
0014
0101
0115
1002
1016
1103
1117

모든 package와 core의 thread 0을 먼저 배정한 뒤 thread 1을 배정합니다.

Dual node CMT terminology
nodeCompute UnitCompute Unit CoreLinux CPU
0000
0011
0102
0113
1004
1015
1106
1117

dual-package topology를 AMD CMT의 Node, Compute Unit, Compute Unit Core로 표현했습니다.