Documentation/driver-api/cxl/theory-of-operation.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API / CXL

Compute Express Link Driver Theory of Operation

CXL.mem device를 PCIe·ACPI object에서 decode topology로 조립하는 원리, cxl_port lifecycle, decoder 질의와 CXL driver infrastructure를 설명합니다.

Source pathDocumentation/driver-api/cxl/theory-of-operation.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약과 해설

theory-of-operation.rst:1-415

CXL subsystem은 firmware와 PCIe가 제공하는 object를 `root → port → endpoint → DPA` decode topology로 조립합니다. topology는 hardware만으로 고정되지 않고 성능·fault tolerance 정책에 따라 runtime에 구성될 수 있습니다. `cxl list`는 memory device에서 가능한 decoder를 찾는 정방향 질의와 decoder에서 candidate device를 찾는 역방향 질의를 모두 제공하며, kernel의 `cxl_port` object와 HDM decoder가 이 관계를 표현합니다. 문서 후반은 PCI, memdev, port, HDM, CDAT, region, mailbox, feature, UAPI source의 kernel-doc entry point를 연결합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2 .. include:: <isonum.txt>
3
4 ===============================================
5 Compute Express Link Driver Theory of Operation
6 ===============================================
7
8 A Compute Express Link Memory Device is a CXL component that implements the
9 CXL.mem protocol. It contains some amount of volatile memory, persistent memory,
10 or both. It is enumerated as a PCI device for configuration and passing
11 messages over an MMIO mailbox. Its contribution to the System Physical
12 Address space is handled via HDM (Host Managed Device Memory) decoders
13 that optionally define a device's contribution to an interleaved address
14 range across multiple devices underneath a host-bridge or interleaved
15 across host-bridges.
16
17 The CXL Bus
18 ===========
19 Similar to how a RAID driver takes disk objects and assembles them into a new
20 logical device, the CXL subsystem is tasked to take PCIe and ACPI objects and
21 assemble them into a CXL.mem decode topology. The need for runtime configuration
22 of the CXL.mem topology is also similar to RAID in that different environments
23 with the same hardware configuration may decide to assemble the topology in
24 contrasting ways. One may choose performance (RAID0) striping memory across
25 multiple Host Bridges and endpoints while another may opt for fault tolerance
26 and disable any striping in the CXL.mem topology.
27
28 Platform firmware enumerates a menu of interleave options at the "CXL root port"
29 (Linux term for the top of the CXL decode topology). From there, PCIe topology
30 dictates which endpoints can participate in which Host Bridge decode regimes.
31 Each PCIe Switch in the path between the root and an endpoint introduces a point
32 at which the interleave can be split. For example, platform firmware may say a
33 given range only decodes to one Host Bridge, but that Host Bridge may in turn
34 interleave cycles across multiple Root Ports. An intervening Switch between a
35 port and an endpoint may interleave cycles across multiple Downstream Switch
36 Ports, etc.
37
38 Here is a sample listing of a CXL topology defined by 'cxl_test'. The 'cxl_test'
39 module generates an emulated CXL topology of 2 Host Bridges each with 2 Root
40 Ports. Each of those Root Ports are connected to 2-way switches with endpoints
41 connected to those downstream ports for a total of 8 endpoints::
42
43 # cxl list -BEMPu -b cxl_test
44 {
45 "bus":"root3",
46 "provider":"cxl_test",
47 "ports:root3":[
48 {
49 "port":"port5",
50 "host":"cxl_host_bridge.1",
51 "ports:port5":[
52 {
53 "port":"port8",
54 "host":"cxl_switch_uport.1",
55 "endpoints:port8":[
56 {
57 "endpoint":"endpoint9",
58 "host":"mem2",
59 "memdev":{
60 "memdev":"mem2",
61 "pmem_size":"256.00 MiB (268.44 MB)",
62 "ram_size":"256.00 MiB (268.44 MB)",
63 "serial":"0x1",
64 "numa_node":1,
65 "host":"cxl_mem.1"
66 }
67 },
68 {
69 "endpoint":"endpoint15",
70 "host":"mem6",
71 "memdev":{
72 "memdev":"mem6",
73 "pmem_size":"256.00 MiB (268.44 MB)",
74 "ram_size":"256.00 MiB (268.44 MB)",
75 "serial":"0x5",
76 "numa_node":1,
77 "host":"cxl_mem.5"
78 }
79 }
80 ]
81 },
82 {
83 "port":"port12",
84 "host":"cxl_switch_uport.3",
85 "endpoints:port12":[
86 {
87 "endpoint":"endpoint17",
88 "host":"mem8",
89 "memdev":{
90 "memdev":"mem8",
91 "pmem_size":"256.00 MiB (268.44 MB)",
92 "ram_size":"256.00 MiB (268.44 MB)",
93 "serial":"0x7",
94 "numa_node":1,
95 "host":"cxl_mem.7"
96 }
97 },
98 {
99 "endpoint":"endpoint13",
100 "host":"mem4",
101 "memdev":{
102 "memdev":"mem4",
103 "pmem_size":"256.00 MiB (268.44 MB)",
104 "ram_size":"256.00 MiB (268.44 MB)",
105 "serial":"0x3",
106 "numa_node":1,
107 "host":"cxl_mem.3"
108 }
109 }
110 ]
111 }
112 ]
113 },
114 {
115 "port":"port4",
116 "host":"cxl_host_bridge.0",
117 "ports:port4":[
118 {
119 "port":"port6",
120 "host":"cxl_switch_uport.0",
121 "endpoints:port6":[
122 {
123 "endpoint":"endpoint7",
124 "host":"mem1",
125 "memdev":{
126 "memdev":"mem1",
127 "pmem_size":"256.00 MiB (268.44 MB)",
128 "ram_size":"256.00 MiB (268.44 MB)",
129 "serial":"0",
130 "numa_node":0,
131 "host":"cxl_mem.0"
132 }
133 },
134 {
135 "endpoint":"endpoint14",
136 "host":"mem5",
137 "memdev":{
138 "memdev":"mem5",
139 "pmem_size":"256.00 MiB (268.44 MB)",
140 "ram_size":"256.00 MiB (268.44 MB)",
141 "serial":"0x4",
142 "numa_node":0,
143 "host":"cxl_mem.4"
144 }
145 }
146 ]
147 },
148 {
149 "port":"port10",
150 "host":"cxl_switch_uport.2",
151 "endpoints:port10":[
152 {
153 "endpoint":"endpoint16",
154 "host":"mem7",
155 "memdev":{
156 "memdev":"mem7",
157 "pmem_size":"256.00 MiB (268.44 MB)",
158 "ram_size":"256.00 MiB (268.44 MB)",
159 "serial":"0x6",
160 "numa_node":0,
161 "host":"cxl_mem.6"
162 }
163 },
164 {
165 "endpoint":"endpoint11",
166 "host":"mem3",
167 "memdev":{
168 "memdev":"mem3",
169 "pmem_size":"256.00 MiB (268.44 MB)",
170 "ram_size":"256.00 MiB (268.44 MB)",
171 "serial":"0x2",
172 "numa_node":0,
173 "host":"cxl_mem.2"
174 }
175 }
176 ]
177 }
178 ]
179 }
180 ]
181 }
182
183 In that listing each "root", "port", and "endpoint" object correspond a kernel
184 'struct cxl_port' object. A 'cxl_port' is a device that can decode CXL.mem to
185 its descendants. So "root" claims non-PCIe enumerable platform decode ranges and
186 decodes them to "ports", "ports" decode to "endpoints", and "endpoints"
187 represent the decode from SPA (System Physical Address) to DPA (Device Physical
188 Address).
189
190 Continuing the RAID analogy, disks have both topology metadata and on-device
191 metadata that determine RAID set assembly. CXL Port topology and CXL Port link
192 status is metadata for CXL.mem set assembly. The CXL Port topology is enumerated
193 by the arrival of a CXL.mem device. I.e. unless and until the PCIe core attaches
194 the cxl_pci driver to a CXL Memory Expander there is no role for CXL Port
195 objects. Conversely for hot-unplug / removal scenarios, there is no need for
196 the Linux PCI core to tear down switch-level CXL resources because the endpoint
197 ->remove() event cleans up the port data that was established to support that
198 Memory Expander.
199
200 The port metadata and potential decode schemes that a given memory device may
201 participate can be determined via a command like::
202
203 # cxl list -BDMu -d root -m mem3
204 {
205 "bus":"root3",
206 "provider":"cxl_test",
207 "decoders:root3":[
208 {
209 "decoder":"decoder3.1",
210 "resource":"0x8030000000",
211 "size":"512.00 MiB (536.87 MB)",
212 "volatile_capable":true,
213 "nr_targets":2
214 },
215 {
216 "decoder":"decoder3.3",
217 "resource":"0x8060000000",
218 "size":"512.00 MiB (536.87 MB)",
219 "pmem_capable":true,
220 "nr_targets":2
221 },
222 {
223 "decoder":"decoder3.0",
224 "resource":"0x8020000000",
225 "size":"256.00 MiB (268.44 MB)",
226 "volatile_capable":true,
227 "nr_targets":1
228 },
229 {
230 "decoder":"decoder3.2",
231 "resource":"0x8050000000",
232 "size":"256.00 MiB (268.44 MB)",
233 "pmem_capable":true,
234 "nr_targets":1
235 }
236 ],
237 "memdevs:root3":[
238 {
239 "memdev":"mem3",
240 "pmem_size":"256.00 MiB (268.44 MB)",
241 "ram_size":"256.00 MiB (268.44 MB)",
242 "serial":"0x2",
243 "numa_node":0,
244 "host":"cxl_mem.2"
245 }
246 ]
247 }
248
249 ...which queries the CXL topology to ask "given CXL Memory Expander with a kernel
250 device name of 'mem3' which platform level decode ranges may this device
251 participate". A given expander can participate in multiple CXL.mem interleave
252 sets simultaneously depending on how many decoder resources it has. In this
253 example mem3 can participate in one or more of a PMEM interleave that spans two
254 Host Bridges, a PMEM interleave that targets a single Host Bridge, a Volatile
255 memory interleave that spans 2 Host Bridges, and a Volatile memory interleave
256 that only targets a single Host Bridge.
257
258 Conversely the memory devices that can participate in a given platform level
259 decode scheme can be determined via a command like the following::
260
261 # cxl list -MDu -d 3.2
262 [
263 {
264 "memdevs":[
265 {
266 "memdev":"mem1",
267 "pmem_size":"256.00 MiB (268.44 MB)",
268 "ram_size":"256.00 MiB (268.44 MB)",
269 "serial":"0",
270 "numa_node":0,
271 "host":"cxl_mem.0"
272 },
273 {
274 "memdev":"mem5",
275 "pmem_size":"256.00 MiB (268.44 MB)",
276 "ram_size":"256.00 MiB (268.44 MB)",
277 "serial":"0x4",
278 "numa_node":0,
279 "host":"cxl_mem.4"
280 },
281 {
282 "memdev":"mem7",
283 "pmem_size":"256.00 MiB (268.44 MB)",
284 "ram_size":"256.00 MiB (268.44 MB)",
285 "serial":"0x6",
286 "numa_node":0,
287 "host":"cxl_mem.6"
288 },
289 {
290 "memdev":"mem3",
291 "pmem_size":"256.00 MiB (268.44 MB)",
292 "ram_size":"256.00 MiB (268.44 MB)",
293 "serial":"0x2",
294 "numa_node":0,
295 "host":"cxl_mem.2"
296 }
297 ]
298 },
299 {
300 "root decoders":[
301 {
302 "decoder":"decoder3.2",
303 "resource":"0x8050000000",
304 "size":"256.00 MiB (268.44 MB)",
305 "pmem_capable":true,
306 "nr_targets":1
307 }
308 ]
309 }
310 ]
311
312 ...where the naming scheme for decoders is "decoder<port_id>.<instance_id>".
313
314 Driver Infrastructure
315 =====================
316
317 This section covers the driver infrastructure for a CXL memory device.
318
319 CXL Memory Device
320 -----------------
321
322 .. kernel-doc:: drivers/cxl/pci.c
323 :doc: cxl pci
324
325 .. kernel-doc:: drivers/cxl/pci.c
326 :internal:
327
328 .. kernel-doc:: drivers/cxl/mem.c
329 :doc: cxl mem
330
331 .. kernel-doc:: drivers/cxl/cxlmem.h
332 :internal:
333
334 .. kernel-doc:: drivers/cxl/core/memdev.c
335 :identifiers:
336
337 CXL Port
338 --------
339 .. kernel-doc:: drivers/cxl/port.c
340 :doc: cxl port
341
342 CXL Core
343 --------
344 .. kernel-doc:: drivers/cxl/cxl.h
345 :doc: cxl objects
346
347 .. kernel-doc:: drivers/cxl/cxl.h
348 :internal:
349
350 .. kernel-doc:: drivers/cxl/acpi.c
351 :identifiers: add_cxl_resources
352
353 .. kernel-doc:: drivers/cxl/core/hdm.c
354 :doc: cxl core hdm
355
356 .. kernel-doc:: drivers/cxl/core/hdm.c
357 :identifiers:
358
359 .. kernel-doc:: drivers/cxl/core/cdat.c
360 :identifiers:
361
362 .. kernel-doc:: drivers/cxl/core/port.c
363 :doc: cxl core
364
365 .. kernel-doc:: drivers/cxl/core/port.c
366 :identifiers:
367
368 .. kernel-doc:: drivers/cxl/core/pci.c
369 :doc: cxl core pci
370
371 .. kernel-doc:: drivers/cxl/core/pci.c
372 :identifiers:
373
374 .. kernel-doc:: drivers/cxl/core/pmem.c
375 :doc: cxl pmem
376
377 .. kernel-doc:: drivers/cxl/core/pmem.c
378 :identifiers:
379
380 .. kernel-doc:: drivers/cxl/core/regs.c
381 :doc: cxl registers
382
383 .. kernel-doc:: drivers/cxl/core/regs.c
384 :identifiers:
385
386 .. kernel-doc:: drivers/cxl/core/mbox.c
387 :doc: cxl mbox
388
389 .. kernel-doc:: drivers/cxl/core/mbox.c
390 :identifiers:
391
392 .. kernel-doc:: drivers/cxl/core/features.c
393 :doc: cxl features
394
395 See :c:func:`devm_cxl_setup_features` for API details.
396
397 CXL Regions
398 -----------
399 .. kernel-doc:: drivers/cxl/core/region.c
400 :doc: cxl core region
401
402 .. kernel-doc:: drivers/cxl/core/region.c
403 :identifiers:
404
405 External Interfaces
406 ===================
407
408 CXL IOCTL Interface
409 -------------------
410
411 .. kernel-doc:: include/uapi/linux/cxl_mem.h
412 :doc: UAPI
413
414 .. kernel-doc:: include/uapi/linux/cxl_mem.h
415 :internal:
416

3. 한국어 전문 번역

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

Compute Express Link driver 동작 원리

1-16
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

Compute Express Link Memory Device는 `CXL.mem` protocol을 구현하는 CXL component입니다. 이 device에는 volatile memory, persistent memory 또는 두 종류 모두가 들어 있습니다.

configuration과 MMIO mailbox를 통한 message 전달을 위해 PCI device로 enumerate됩니다. System Physical Address space에 기여하는 범위는 HDM(Host Managed Device Memory) decoder가 처리합니다. HDM decoder는 선택적으로 하나의 host bridge 아래 여러 device 사이 또는 여러 host bridge 사이에서 interleaved address range에 각 device가 기여하는 부분을 정의합니다.

CXL bus와 decode topology 조립

17-37

RAID driver가 disk object를 가져와 새로운 logical device로 조립하는 것과 비슷하게, CXL subsystem은 PCIe와 ACPI object를 가져와 `CXL.mem` decode topology로 조립해야 합니다.

같은 hardware configuration에서도 환경에 따라 topology를 서로 다르게 조립할 수 있으므로 runtime configuration이 필요합니다. 한 환경은 여러 Host Bridge와 endpoint에 memory를 stripe하는 성능 중심 RAID0 방식과 비슷한 구성을 고를 수 있고, 다른 환경은 fault tolerance를 위해 `CXL.mem` topology의 striping을 모두 비활성화할 수 있습니다.

platform firmware는 CXL decode topology의 최상단을 뜻하는 Linux 용어인 `CXL root port`에서 interleave option 메뉴를 enumerate합니다. 그 아래에서는 PCIe topology가 어떤 endpoint가 어떤 Host Bridge decode regime에 참여할 수 있는지를 결정합니다.

root와 endpoint 사이의 각 PCIe Switch는 interleave를 나눌 수 있는 지점을 추가합니다. 예를 들어 firmware가 어떤 range를 Host Bridge 하나로만 decode한다고 선언해도, 그 Host Bridge는 여러 Root Port에 cycle을 interleave할 수 있습니다. port와 endpoint 사이의 Switch도 여러 Downstream Switch Port에 cycle을 interleave할 수 있습니다.

cxl_test가 만드는 sample topology

38-182

다음은 `cxl_test`가 정의한 CXL topology의 sample listing입니다. `cxl_test` module은 Host Bridge 두 개를 emulate하고 각 Host Bridge에 Root Port 두 개를 둡니다. 각 Root Port는 2-way switch에 연결되고 그 downstream port마다 endpoint가 있어 총 endpoint는 여덟 개입니다.

# cxl list -BEMPu -b cxl_test
{
  "bus":"root3",
  "provider":"cxl_test",
  "ports:root3":[
    {
      "port":"port5",
      "host":"cxl_host_bridge.1",
      "ports:port5":[
        {
          "port":"port8",
          "host":"cxl_switch_uport.1",
          "endpoints:port8":[
            {
              "endpoint":"endpoint9",
              "host":"mem2",
              "memdev":{
                "memdev":"mem2",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x1",
                "numa_node":1,
                "host":"cxl_mem.1"
              }
            },
            {
              "endpoint":"endpoint15",
              "host":"mem6",
              "memdev":{
                "memdev":"mem6",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x5",
                "numa_node":1,
                "host":"cxl_mem.5"
              }
            }
          ]
        },
        {
          "port":"port12",
          "host":"cxl_switch_uport.3",
          "endpoints:port12":[
            {
              "endpoint":"endpoint17",
              "host":"mem8",
              "memdev":{
                "memdev":"mem8",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x7",
                "numa_node":1,
                "host":"cxl_mem.7"
              }
            },
            {
              "endpoint":"endpoint13",
              "host":"mem4",
              "memdev":{
                "memdev":"mem4",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x3",
                "numa_node":1,
                "host":"cxl_mem.3"
              }
            }
          ]
        }
      ]
    },
    {
      "port":"port4",
      "host":"cxl_host_bridge.0",
      "ports:port4":[
        {
          "port":"port6",
          "host":"cxl_switch_uport.0",
          "endpoints:port6":[
            {
              "endpoint":"endpoint7",
              "host":"mem1",
              "memdev":{
                "memdev":"mem1",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0",
                "numa_node":0,
                "host":"cxl_mem.0"
              }
            },
            {
              "endpoint":"endpoint14",
              "host":"mem5",
              "memdev":{
                "memdev":"mem5",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x4",
                "numa_node":0,
                "host":"cxl_mem.4"
              }
            }
          ]
        },
        {
          "port":"port10",
          "host":"cxl_switch_uport.2",
          "endpoints:port10":[
            {
              "endpoint":"endpoint16",
              "host":"mem7",
              "memdev":{
                "memdev":"mem7",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x6",
                "numa_node":0,
                "host":"cxl_mem.6"
              }
            },
            {
              "endpoint":"endpoint11",
              "host":"mem3",
              "memdev":{
                "memdev":"mem3",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x2",
                "numa_node":0,
                "host":"cxl_mem.2"
              }
            }
          ]
        }
      ]
    }
  ]
}
cxl_test topology 경로
Host Bridge PortSwitch PortEndpoints / MemdevsNUMA Node
port5 / cxl_host_bridge.1port8 / cxl_switch_uport.1endpoint9 mem2, endpoint15 mem61
port5 / cxl_host_bridge.1port12 / cxl_switch_uport.3endpoint17 mem8, endpoint13 mem41
port4 / cxl_host_bridge.0port6 / cxl_switch_uport.0endpoint7 mem1, endpoint14 mem50
port4 / cxl_host_bridge.0port10 / cxl_switch_uport.2endpoint16 mem7, endpoint11 mem30

root3 아래의 두 Host Bridge, 네 switch upstream port, 여덟 endpoint를 listing 순서에 맞춰 정리했습니다.

cxl_port decode model과 lifecycle

183-199

listing의 각 `root`, `port`, `endpoint` object는 kernel의 `struct cxl_port` object에 대응합니다. `cxl_port`는 descendant 쪽으로 `CXL.mem`을 decode할 수 있는 device입니다.

따라서 `root`는 PCIe로 enumerate할 수 없는 platform decode range를 소유하고 `port`로 decode합니다. `port`는 `endpoint`로 decode하며, `endpoint`는 SPA(System Physical Address)에서 DPA(Device Physical Address)로 가는 decode를 나타냅니다.

RAID analogy를 계속 적용하면 disk에는 RAID set 조립을 결정하는 topology metadata와 on-device metadata가 모두 있습니다. CXL Port topology와 CXL Port link status는 `CXL.mem` set을 조립하는 metadata입니다.

CXL Port topology는 `CXL.mem` device가 도착할 때 enumerate됩니다. PCIe core가 CXL Memory Expander에 `cxl_pci` driver를 attach하기 전에는 CXL Port object가 할 역할이 없습니다.

반대로 hot-unplug 또는 removal 때는 Linux PCI core가 switch-level CXL resource를 직접 철거할 필요가 없습니다. endpoint의 `->remove()` event가 해당 Memory Expander를 지원하려고 구성했던 port data를 정리하기 때문입니다.

memory device에서 가능한 decoder 찾기

200-248

특정 memory device가 참여할 수 있는 port metadata와 잠재적 decode scheme은 다음 command로 확인할 수 있습니다.

# cxl list -BDMu -d root -m mem3
{
  "bus":"root3",
  "provider":"cxl_test",
  "decoders:root3":[
    {
      "decoder":"decoder3.1",
      "resource":"0x8030000000",
      "size":"512.00 MiB (536.87 MB)",
      "volatile_capable":true,
      "nr_targets":2
    },
    {
      "decoder":"decoder3.3",
      "resource":"0x8060000000",
      "size":"512.00 MiB (536.87 MB)",
      "pmem_capable":true,
      "nr_targets":2
    },
    {
      "decoder":"decoder3.0",
      "resource":"0x8020000000",
      "size":"256.00 MiB (268.44 MB)",
      "volatile_capable":true,
      "nr_targets":1
    },
    {
      "decoder":"decoder3.2",
      "resource":"0x8050000000",
      "size":"256.00 MiB (268.44 MB)",
      "pmem_capable":true,
      "nr_targets":1
    }
  ],
  "memdevs:root3":[
    {
      "memdev":"mem3",
      "pmem_size":"256.00 MiB (268.44 MB)",
      "ram_size":"256.00 MiB (268.44 MB)",
      "serial":"0x2",
      "numa_node":0,
      "host":"cxl_mem.2"
    }
  ]
}
mem3가 참여할 수 있는 root decoder
DecoderResourceSizeCapability / Targets
decoder3.10x8030000000512 MiBvolatile / 2
decoder3.30x8060000000512 MiBpmem / 2
decoder3.00x8020000000256 MiBvolatile / 1
decoder3.20x8050000000256 MiBpmem / 1

`cxl list -BDMu -d root -m mem3` 결과의 decoder capability와 target 수를 정리했습니다.

device 중심 질의의 의미

249-257

이 command는 CXL topology에 `mem3`라는 kernel device name을 가진 CXL Memory Expander가 어떤 platform-level decode range에 참여할 수 있는지를 묻습니다.

expander가 가진 decoder resource 수에 따라 하나의 expander가 여러 `CXL.mem` interleave set에 동시에 참여할 수 있습니다. 이 example에서 mem3는 Host Bridge 두 개를 가로지르는 PMEM interleave, Host Bridge 하나만 대상으로 하는 PMEM interleave, Host Bridge 두 개를 가로지르는 Volatile memory interleave, Host Bridge 하나만 대상으로 하는 Volatile memory interleave 가운데 하나 이상에 참여할 수 있습니다.

decoder에서 참여 가능한 device 찾기

258-313

반대 방향으로, 특정 platform-level decode scheme에 참여할 수 있는 memory device는 다음 command로 확인할 수 있습니다.

# cxl list -MDu -d 3.2
[
  {
    "memdevs":[
      {
        "memdev":"mem1",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0",
        "numa_node":0,
        "host":"cxl_mem.0"
      },
      {
        "memdev":"mem5",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0x4",
        "numa_node":0,
        "host":"cxl_mem.4"
      },
      {
        "memdev":"mem7",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0x6",
        "numa_node":0,
        "host":"cxl_mem.6"
      },
      {
        "memdev":"mem3",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0x2",
        "numa_node":0,
        "host":"cxl_mem.2"
      }
    ]
  },
  {
    "root decoders":[
      {
        "decoder":"decoder3.2",
        "resource":"0x8050000000",
        "size":"256.00 MiB (268.44 MB)",
        "pmem_capable":true,
        "nr_targets":1
      }
    ]
  }
]
decoder3.2 역방향 질의
Root DecoderCandidate MemdevsCapabilityRange
decoder3.2mem1, mem5, mem7, mem3pmem, 1 target0x8050000000 / 256 MiB

`cxl list -MDu -d 3.2`가 반환한 candidate memdev와 root decoder 관계입니다.

decoder naming scheme은 `decoder<port_id>.<instance_id>`입니다. 따라서 `decoder3.2`는 port id 3에 속한 instance id 2 decoder를 뜻합니다.

Driver Infrastructure와 CXL Memory Device

314-336

이 section은 CXL memory device를 위한 driver infrastructure를 다룹니다. `CXL Memory Device` subsection은 PCI transport, memory device layer, internal memory structure, memdev core identifier 문서를 kernel-doc에서 가져옵니다.

.. kernel-doc:: drivers/cxl/pci.c
   :doc: cxl pci

.. kernel-doc:: drivers/cxl/pci.c
   :internal:

.. kernel-doc:: drivers/cxl/mem.c
   :doc: cxl mem

.. kernel-doc:: drivers/cxl/cxlmem.h
   :internal:

.. kernel-doc:: drivers/cxl/core/memdev.c
   :identifiers:
  • `drivers/cxl/pci.c`: `cxl pci` 문서와 internal symbol
  • `drivers/cxl/mem.c`: `cxl mem` 문서
  • `drivers/cxl/cxlmem.h`: internal definition
  • `drivers/cxl/core/memdev.c`: exported identifier

CXL Port infrastructure

337-341

`CXL Port` subsection은 `drivers/cxl/port.c`의 `cxl port` kernel-doc를 포함해 port driver의 동작을 설명합니다.

.. kernel-doc:: drivers/cxl/port.c
   :doc: cxl port

CXL Core infrastructure

342-396

`CXL Core` subsection은 object model, ACPI resource 추가, HDM/CDAT, port와 PCI core, persistent memory, register, mailbox, feature setup을 담당하는 source의 문서와 identifier를 모읍니다.

.. kernel-doc:: drivers/cxl/cxl.h
   :doc: cxl objects

.. kernel-doc:: drivers/cxl/cxl.h
   :internal:

.. kernel-doc:: drivers/cxl/acpi.c
   :identifiers: add_cxl_resources

.. kernel-doc:: drivers/cxl/core/hdm.c
   :doc: cxl core hdm

.. kernel-doc:: drivers/cxl/core/hdm.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/cdat.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/port.c
   :doc: cxl core

.. kernel-doc:: drivers/cxl/core/port.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/pci.c
   :doc: cxl core pci

.. kernel-doc:: drivers/cxl/core/pci.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/pmem.c
   :doc: cxl pmem

.. kernel-doc:: drivers/cxl/core/pmem.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/regs.c
   :doc: cxl registers

.. kernel-doc:: drivers/cxl/core/regs.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/mbox.c
   :doc: cxl mbox

.. kernel-doc:: drivers/cxl/core/mbox.c
   :identifiers:

.. kernel-doc:: drivers/cxl/core/features.c
   :doc: cxl features
CXL Core source map
SourceDocumented AreaDirective Mode
drivers/cxl/cxl.hcxl objectsdoc + internal
drivers/cxl/acpi.cadd_cxl_resourcesidentifiers
drivers/cxl/core/hdm.ccxl core hdmdoc + identifiers
drivers/cxl/core/cdat.cCDAT supportidentifiers
drivers/cxl/core/port.ccxl coredoc + identifiers
drivers/cxl/core/pci.ccxl core pcidoc + identifiers
drivers/cxl/core/pmem.ccxl pmemdoc + identifiers
drivers/cxl/core/regs.ccxl registersdoc + identifiers
drivers/cxl/core/mbox.ccxl mboxdoc + identifiers
drivers/cxl/core/features.ccxl featuresdoc

kernel-doc directive가 참조하는 core source와 주제를 기능별로 묶었습니다.

feature API의 자세한 내용은 :c:func:`devm_cxl_setup_features`를 참조합니다.

CXL Regions

397-404

`CXL Regions` subsection은 `drivers/cxl/core/region.c`의 `cxl core region` 문서와 exported identifier를 kernel-doc로 포함합니다.

.. kernel-doc:: drivers/cxl/core/region.c
   :doc: cxl core region

.. kernel-doc:: drivers/cxl/core/region.c
   :identifiers:

External Interfaces와 CXL IOCTL

405-415

`External Interfaces`의 `CXL IOCTL Interface` subsection은 `include/uapi/linux/cxl_mem.h`에서 UAPI 문서와 internal definition을 가져옵니다.

.. kernel-doc:: include/uapi/linux/cxl_mem.h
   :doc: UAPI

.. kernel-doc:: include/uapi/linux/cxl_mem.h
   :internal: