← Documents Documentation/accel/qaic/qaic.rst GitHub 원문 ↗

Linux 6.18.37 · Compute accelerators / QAIC

QAIC driver

AIC100 KMD의 IRQ storm 제어, single MSI fallback, NNC KMD/UMD 분담, BO ioctl lifecycle, client isolation과 module parameter를 설명합니다.

Source pathDocumentation/accel/qaic/qaic.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

Interrupt handling

qaic.rst:1-61

FIFO burst를 polling으로 흡수하고 MultiMSI가 어려운 platform에서는 MHI·DBC가 MSI 하나를 공유합니다.

NNC와 uAPI

qaic.rst:62-159

NNC wire envelope와 opaque command 책임을 나누고 nine driver-specific IOCTL의 BO state transition을 정의합니다.

Isolation과 tuning

qaic.rst:160-209

Per-open resource ownership을 강제하고 polling·MHI·QSM·wait·timesync timeout parameter를 제공합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0-only
2
3 =============
4 QAIC driver
5 =============
6
7 The QAIC driver is the Kernel Mode Driver (KMD) for the AIC100 family of AI
8 accelerator products.
9
10 Interrupts
11 ==========
12
13 IRQ Storm Mitigation
14 --------------------
15
16 While the AIC100 DMA Bridge hardware implements an IRQ storm mitigation
17 mechanism, it is still possible for an IRQ storm to occur. A storm can happen
18 if the workload is particularly quick, and the host is responsive. If the host
19 can drain the response FIFO as quickly as the device can insert elements into
20 it, then the device will frequently transition the response FIFO from empty to
21 non-empty and generate MSIs at a rate equivalent to the speed of the
22 workload's ability to process inputs. The lprnet (license plate reader network)
23 workload is known to trigger this condition, and can generate in excess of 100k
24 MSIs per second. It has been observed that most systems cannot tolerate this
25 for long, and will crash due to some form of watchdog due to the overhead of
26 the interrupt controller interrupting the host CPU.
27
28 To mitigate this issue, the QAIC driver implements specific IRQ handling. When
29 QAIC receives an IRQ, it disables that line. This prevents the interrupt
30 controller from interrupting the CPU. Then AIC drains the FIFO. Once the FIFO
31 is drained, QAIC implements a "last chance" polling algorithm where QAIC will
32 sleep for a time to see if the workload will generate more activity. The IRQ
33 line remains disabled during this time. If no activity is detected, QAIC exits
34 polling mode and reenables the IRQ line.
35
36 This mitigation in QAIC is very effective. The same lprnet usecase that
37 generates 100k IRQs per second (per /proc/interrupts) is reduced to roughly 64
38 IRQs over 5 minutes while keeping the host system stable, and having the same
39 workload throughput performance (within run to run noise variation).
40
41 Single MSI Mode
42 ---------------
43
44 MultiMSI is not well supported on all systems; virtualized ones even less so
45 (circa 2023). Between hypervisors masking the PCIe MSI capability structure to
46 large memory requirements for vIOMMUs (required for supporting MultiMSI), it is
47 useful to be able to fall back to a single MSI when needed.
48
49 To support this fallback, we allow the case where only one MSI is able to be
50 allocated, and share that one MSI between MHI and the DBCs. The device detects
51 when only one MSI has been configured and directs the interrupts for the DBCs
52 to the interrupt normally used for MHI. Unfortunately this means that the
53 interrupt handlers for every DBC and MHI wake up for every interrupt that
54 arrives; however, the DBC threaded irq handlers only are started when work to be
55 done is detected (MHI will always start its threaded handler).
56
57 If the DBC is configured to force MSI interrupts, this can circumvent the
58 software IRQ storm mitigation mentioned above. Since the MSI is shared it is
59 never disabled, allowing each new entry to the FIFO to trigger a new interrupt.
60
61
62 Neural Network Control (NNC) Protocol
63 =====================================
64
65 The implementation of NNC is split between the KMD (QAIC) and UMD. In general
66 QAIC understands how to encode/decode NNC wire protocol, and elements of the
67 protocol which require kernel space knowledge to process (for example, mapping
68 host memory to device IOVAs). QAIC understands the structure of a message, and
69 all of the transactions. QAIC does not understand commands (the payload of a
70 passthrough transaction).
71
72 QAIC handles and enforces the required little endianness and 64-bit alignment,
73 to the degree that it can. Since QAIC does not know the contents of a
74 passthrough transaction, it relies on the UMD to satisfy the requirements.
75
76 The terminate transaction is of particular use to QAIC. QAIC is not aware of
77 the resources that are loaded onto a device since the majority of that activity
78 occurs within NNC commands. As a result, QAIC does not have the means to
79 roll back userspace activity. To ensure that a userspace client's resources
80 are fully released in the case of a process crash, or a bug, QAIC uses the
81 terminate command to let QSM know when a user has gone away, and the resources
82 can be released.
83
84 QSM can report a version number of the NNC protocol it supports. This is in the
85 form of a Major number and a Minor number.
86
87 Major number updates indicate changes to the NNC protocol which impact the
88 message format, or transactions (impacts QAIC).
89
90 Minor number updates indicate changes to the NNC protocol which impact the
91 commands (does not impact QAIC).
92
93 uAPI
94 ====
95
96 QAIC creates an accel device per physical PCIe device. This accel device exists
97 for as long as the PCIe device is known to Linux.
98
99 The PCIe device may not be in the state to accept requests from userspace at
100 all times. QAIC will trigger KOBJ_ONLINE/OFFLINE uevents to advertise when the
101 device can accept requests (ONLINE) and when the device is no longer accepting
102 requests (OFFLINE) because of a reset or other state transition.
103
104 QAIC defines a number of driver specific IOCTLs as part of the userspace API.
105
106 DRM_IOCTL_QAIC_MANAGE
107 This IOCTL allows userspace to send a NNC request to the QSM. The call will
108 block until a response is received, or the request has timed out.
109
110 DRM_IOCTL_QAIC_CREATE_BO
111 This IOCTL allows userspace to allocate a buffer object (BO) which can send
112 or receive data from a workload. The call will return a GEM handle that
113 represents the allocated buffer. The BO is not usable until it has been
114 sliced (see DRM_IOCTL_QAIC_ATTACH_SLICE_BO).
115
116 DRM_IOCTL_QAIC_MMAP_BO
117 This IOCTL allows userspace to prepare an allocated BO to be mmap'd into the
118 userspace process.
119
120 DRM_IOCTL_QAIC_ATTACH_SLICE_BO
121 This IOCTL allows userspace to slice a BO in preparation for sending the BO
122 to the device. Slicing is the operation of describing what portions of a BO
123 get sent where to a workload. This requires a set of DMA transfers for the
124 DMA Bridge, and as such, locks the BO to a specific DBC.
125
126 DRM_IOCTL_QAIC_EXECUTE_BO
127 This IOCTL allows userspace to submit a set of sliced BOs to the device. The
128 call is non-blocking. Success only indicates that the BOs have been queued
129 to the device, but does not guarantee they have been executed.
130
131 DRM_IOCTL_QAIC_PARTIAL_EXECUTE_BO
132 This IOCTL operates like DRM_IOCTL_QAIC_EXECUTE_BO, but it allows userspace
133 to shrink the BOs sent to the device for this specific call. If a BO
134 typically has N inputs, but only a subset of those is available, this IOCTL
135 allows userspace to indicate that only the first M bytes of the BO should be
136 sent to the device to minimize data transfer overhead. This IOCTL dynamically
137 recomputes the slicing, and therefore has some processing overhead before the
138 BOs can be queued to the device.
139
140 DRM_IOCTL_QAIC_WAIT_BO
141 This IOCTL allows userspace to determine when a particular BO has been
142 processed by the device. The call will block until either the BO has been
143 processed and can be re-queued to the device, or a timeout occurs.
144
145 DRM_IOCTL_QAIC_PERF_STATS_BO
146 This IOCTL allows userspace to collect performance statistics on the most
147 recent execution of a BO. This allows userspace to construct an end to end
148 timeline of the BO processing for a performance analysis.
149
150 DRM_IOCTL_QAIC_DETACH_SLICE_BO
151 This IOCTL allows userspace to remove the slicing information from a BO that
152 was originally provided by a call to DRM_IOCTL_QAIC_ATTACH_SLICE_BO. This
153 is the inverse of DRM_IOCTL_QAIC_ATTACH_SLICE_BO. The BO must be idle for
154 DRM_IOCTL_QAIC_DETACH_SLICE_BO to be called. After a successful detach slice
155 operation the BO may have new slicing information attached with a new call
156 to DRM_IOCTL_QAIC_ATTACH_SLICE_BO. After detach slice, the BO cannot be
157 executed until after a new attach slice operation. Combining attach slice
158 and detach slice calls allows userspace to use a BO with multiple workloads.
159
160 Userspace Client Isolation
161 ==========================
162
163 AIC100 supports multiple clients. Multiple DBCs can be consumed by a single
164 client, and multiple clients can each consume one or more DBCs. Workloads
165 may contain sensitive information therefore only the client that owns the
166 workload should be allowed to interface with the DBC.
167
168 Clients are identified by the instance associated with their open(). A client
169 may only use memory they allocate, and DBCs that are assigned to their
170 workloads. Attempts to access resources assigned to other clients will be
171 rejected.
172
173 Module parameters
174 =================
175
176 QAIC supports the following module parameters:
177
178 **datapath_polling (bool)**
179
180 Configures QAIC to use a polling thread for datapath events instead of relying
181 on the device interrupts. Useful for platforms with broken multiMSI. Must be
182 set at QAIC driver initialization. Default is 0 (off).
183
184 **mhi_timeout_ms (unsigned int)**
185
186 Sets the timeout value for MHI operations in milliseconds (ms). Must be set
187 at the time the driver detects a device. Default is 2000 (2 seconds).
188
189 **control_resp_timeout_s (unsigned int)**
190
191 Sets the timeout value for QSM responses to NNC messages in seconds (s). Must
192 be set at the time the driver is sending a request to QSM. Default is 60 (one
193 minute).
194
195 **wait_exec_default_timeout_ms (unsigned int)**
196
197 Sets the default timeout for the wait_exec ioctl in milliseconds (ms). Must be
198 set prior to the waic_exec ioctl call. A value specified in the ioctl call
199 overrides this for that call. Default is 5000 (5 seconds).
200
201 **datapath_poll_interval_us (unsigned int)**
202
203 Sets the polling interval in microseconds (us) when datapath polling is active.
204 Takes effect at the next polling interval. Default is 100 (100 us).
205
206 **timesync_delay_ms (unsigned int)**
207
208 Sets the time interval in milliseconds (ms) between two consecutive timesync
209 operations. Default is 1000 (1000 ms).
210

3. 한국어 전문 번역

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

QAIC Kernel Mode Driver

1-6

`GPL-2.0-only` 문서입니다. QAIC driver는 AIC100 AI accelerator 제품군의 KMD(Kernel Mode Driver)입니다.

IRQ storm mitigation

7-39

AIC100 DMA Bridge hardware에 IRQ storm mitigation이 있어도 workload가 매우 빠르고 host가 민첩하면 storm이 발생할 수 있습니다. Host가 device의 response FIFO insert 속도만큼 빨리 FIFO를 drain하면 FIFO가 empty에서 non-empty로 자주 전환되고 workload input 처리 속도와 같은 rate로 MSI가 발생합니다.

License plate reader network인 `lprnet` workload는 초당 MSI 100k개를 넘길 수 있습니다. 많은 system은 interrupt controller가 host CPU를 계속 interrupt하는 overhead를 오래 견디지 못하고 watchdog 형태의 문제로 crash하는 것이 관찰됐습니다.

QAIC는 IRQ를 받으면 해당 line을 disable해 interrupt controller가 CPU를 깨우지 못하게 한 뒤 FIFO를 drain합니다. FIFO가 비면 `last chance` polling으로 일정 시간 sleep하며 추가 activity를 확인하고, 그동안 IRQ line은 disable 상태를 유지합니다. Activity가 없으면 polling mode를 끝내고 IRQ line을 다시 enable합니다.

이 방식은 `/proc/interrupts`에서 초당 IRQ 100k개를 만들던 같은 `lprnet` use case를 5분 동안 약 64 IRQ로 줄였습니다. Host는 안정적이었고 workload throughput은 실행 간 noise 범위에서 동일했습니다.

QAIC IRQ storm mitigation
Receive IRQDisable IRQ lineDrain response FIFOKeep line disabled and enter last-chance pollingSleep and check for more activity
Activity foundDrain and poll again
No activityExit pollingRe-enable IRQ line

IRQ line을 잠시 막고 FIFO를 비운 뒤 짧은 polling window로 burst를 흡수합니다.

Observed lprnet interrupt reduction
ModeObserved interruptsHost result
Without QAIC software mitigation>100k MSI/sWatchdog/crash risk
With QAIC mitigation~64 IRQs / 5 minutesStable; same throughput

Workload throughput을 유지하면서 host-visible IRQ rate를 낮춥니다.

Single MSI fallback

40-61

2023년 무렵 MultiMSI는 모든 system, 특히 virtualized system에서 충분히 지원되지 않았습니다. Hypervisor가 PCIe MSI capability structure를 mask하거나 MultiMSI에 필요한 vIOMMU memory 요구량이 커서 MSI 하나로 fallback하는 기능이 유용합니다.

QAIC는 MSI 하나만 allocate할 수 있는 경우 MHI와 모든 DBC가 이를 공유하도록 허용합니다. Device가 MSI 하나만 설정됐음을 감지하면 DBC interrupt를 보통 MHI가 쓰는 interrupt로 보냅니다. 모든 interrupt에서 모든 DBC와 MHI handler가 wake하지만, DBC threaded IRQ handler는 할 일이 감지될 때만 시작하고 MHI는 항상 threaded handler를 시작합니다.

DBC가 force MSI interrupt로 구성되면 앞의 software IRQ storm mitigation을 우회할 수 있습니다. Shared MSI는 disable되지 않으므로 FIFO의 새 entry마다 새 interrupt를 trigger할 수 있습니다.

Single MSI sharing
Only one MSI allocatedDevice redirects DBC interrupts to MHI MSIWake MHI and every DBC handlerStart DBC threaded handler only when work exists
DBC force MSI enabledShared line stays enabledSoftware storm mitigation can be bypassed

MHI와 16 DBC interrupt source가 하나의 MSI로 합쳐집니다.

KMD와 UMD의 NNC protocol 분담

62-92

NNC implementation은 KMD(QAIC)와 UMD로 나뉩니다. QAIC는 NNC wire protocol encode/decode, host memory를 device IOVA에 map하는 것처럼 kernel knowledge가 필요한 element를 처리합니다. Message structure와 모든 transaction을 이해하지만 passthrough transaction payload인 command 자체는 이해하지 않습니다.

QAIC는 가능한 범위에서 required little endianness와 64-bit alignment를 적용합니다. Passthrough 내용은 알 수 없으므로 그 payload의 requirement는 UMD가 충족해야 합니다.

`terminate` transaction은 QAIC에 특히 유용합니다. Resource load 대부분이 NNC command 안에서 일어나 QAIC는 device에 load된 resource를 알지 못하고 userspace activity를 rollback할 수 없습니다. Process crash나 bug로 client가 사라지면 QAIC가 `terminate`로 QSM에 알려 모든 resource를 release하게 합니다.

QSM은 지원하는 NNC protocol version을 Major와 Minor number로 보고합니다. Major update는 message format이나 transaction에 영향을 주므로 QAIC에 영향을 줍니다. Minor update는 command에 영향을 주며 QAIC에는 영향을 주지 않습니다.

NNC responsibility boundary
LayerUnderstands/enforcesDoes not understand
QAIC KMDMessage, transactions, little endian, 64-bit alignment, IOVA mappingPassthrough commands
UMDPassthrough command payload requirementsKernel-only memory mapping

KMD가 검증할 수 있는 wire envelope와 UMD가 책임지는 opaque command를 구분합니다.

NNC version semantics
VersionChanged surfaceImpacts QAIC
MajorMessage format or transactionsYes
MinorCommandsNo

Version component가 바뀌는 protocol surface입니다.

QAIC userspace API

93-159

QAIC는 physical PCIe device마다 accel device 하나를 만들며 Linux가 PCIe device를 아는 동안 유지합니다. Device가 항상 userspace request를 받을 수 있는 것은 아닙니다. QAIC는 request 수락 가능 상태에 `KOBJ_ONLINE`, reset이나 다른 state transition으로 더 이상 수락하지 않을 때 `KOBJ_OFFLINE` uevent를 발생시킵니다.

QAIC driver-specific IOCTLs
IOCTLOperationCompletion semantics
DRM_IOCTL_QAIC_MANAGESend NNC request to QSMBlocks for response or timeout
DRM_IOCTL_QAIC_CREATE_BOAllocate BO and return GEM handleBO unusable until sliced
DRM_IOCTL_QAIC_MMAP_BOPrepare BO for userspace mmapPreparation only
DRM_IOCTL_QAIC_ATTACH_SLICE_BODescribe BO regions and DMA destinations; bind DBCLocks BO to one DBC
DRM_IOCTL_QAIC_EXECUTE_BOSubmit sliced BO setNon-blocking; success means queued, not executed
DRM_IOCTL_QAIC_PARTIAL_EXECUTE_BOSend first M bytes when subset of N inputs existsRecomputes slicing before queue
DRM_IOCTL_QAIC_WAIT_BOWait for BO processing/requeue readinessBlocks until processed or timeout
DRM_IOCTL_QAIC_PERF_STATS_BORead latest BO execution statisticsBuild end-to-end timeline
DRM_IOCTL_QAIC_DETACH_SLICE_BORemove slice information from idle BOMust reattach before execute

Buffer lifecycle과 NNC control의 blocking·queue semantics를 보존합니다.

`DRM_IOCTL_QAIC_MANAGE`는 NNC request를 QSM에 보내고 response 수신 또는 timeout까지 block합니다. `DRM_IOCTL_QAIC_CREATE_BO`는 workload와 data를 주고받을 buffer object(BO)를 allocate하고 GEM handle을 반환합니다. BO는 `DRM_IOCTL_QAIC_ATTACH_SLICE_BO`로 slice하기 전에는 사용할 수 없습니다. `DRM_IOCTL_QAIC_MMAP_BO`는 allocated BO를 userspace process에 mmap할 준비를 합니다.

`DRM_IOCTL_QAIC_ATTACH_SLICE_BO`는 BO의 어느 부분을 workload의 어디로 보낼지 기술하는 slicing을 적용합니다. DMA Bridge용 DMA transfer set이 필요하므로 BO를 특정 DBC에 lock합니다. `DRM_IOCTL_QAIC_EXECUTE_BO`는 sliced BO set을 non-blocking으로 submit합니다. Success는 device queue에 들어갔다는 뜻일 뿐 실행 완료를 보장하지 않습니다.

`DRM_IOCTL_QAIC_PARTIAL_EXECUTE_BO`는 execute와 비슷하지만 이번 call에 보낼 BO를 줄일 수 있습니다. BO가 보통 input N개를 갖지만 일부만 준비됐다면 첫 M byte만 보내 transfer overhead를 줄입니다. Slicing을 동적으로 다시 계산하므로 queue 전에 processing overhead가 있습니다.

`DRM_IOCTL_QAIC_WAIT_BO`는 특정 BO가 처리돼 다시 queue할 수 있을 때까지 또는 timeout까지 block합니다. `DRM_IOCTL_QAIC_PERF_STATS_BO`는 가장 최근 BO 실행의 performance statistic을 수집해 end-to-end processing timeline을 구성하게 합니다.

`DRM_IOCTL_QAIC_DETACH_SLICE_BO`는 attach call로 넣은 slicing information을 제거하는 역연산이며 BO가 idle이어야 합니다. 성공 후 새 attach call로 다른 slicing을 붙일 수 있지만 다시 attach하기 전에는 실행할 수 없습니다. Attach와 detach를 조합하면 BO 하나를 여러 workload에서 사용할 수 있습니다.

QAIC buffer object lifecycle
CREATE_BO -> GEM handleMMAP_BO if userspace mapping is neededATTACH_SLICE_BO -> bind specific DBCEXECUTE_BO or PARTIAL_EXECUTE_BOWAIT_BO / PERF_STATS_BO
BO idleDETACH_SLICE_BOAttach new slicing for another workload

Allocation부터 workload 재사용까지 필요한 state transition입니다.

Userspace client isolation

160-172

AIC100은 multiple client를 지원합니다. Client 하나가 DBC 여러 개를 사용할 수 있고 여러 client가 각자 하나 이상의 DBC를 사용할 수도 있습니다. Workload에는 sensitive information이 있을 수 있으므로 해당 workload를 소유한 client만 DBC와 interface해야 합니다.

Client는 자신의 `open()`에 연관된 instance로 식별됩니다. 자신이 allocate한 memory와 자신의 workload에 배정된 DBC만 사용할 수 있으며 다른 client resource에 접근하려는 시도는 reject됩니다.

Per-open client ownership
ResourceAllowedRejected
MemoryAllocated by this clientAllocated by another client
DBCAssigned to this client's workloadAssigned to another client

Memory와 DBC access를 open instance의 resource ownership으로 제한합니다.

Module parameters

173-209

`datapath_polling`(bool)은 device interrupt 대신 polling thread로 datapath event를 처리합니다. MultiMSI가 고장 난 platform에 유용하고 QAIC driver initialization 때 설정해야 하며 default는 `0`(off)입니다.

`mhi_timeout_ms`(unsigned int)는 MHI operation timeout을 millisecond로 지정합니다. Driver가 device를 detect할 때 설정해야 하며 default는 `2000`(2 seconds)입니다. `control_resp_timeout_s`는 NNC message에 대한 QSM response timeout을 seconds로 지정하고 QSM request를 보낼 때 설정해야 하며 default는 `60`(1 minute)입니다.

`wait_exec_default_timeout_ms`는 `wait_exec` ioctl의 default timeout을 millisecond로 지정합니다. Source에 명시된 `waic_exec` ioctl call 전에 설정해야 하고 call에 지정한 값이 이번 call에서 override하며 default는 `5000`(5 seconds)입니다.

`datapath_poll_interval_us`는 datapath polling active 상태의 interval을 microseconds로 지정하며 다음 polling interval부터 적용됩니다. Default는 `100`(100 us)입니다. `timesync_delay_ms`는 연속된 timesync operation 사이의 interval을 milliseconds로 지정하며 default는 `1000`(1000 ms)입니다.

QAIC module parameter defaults
ParameterTypeWhen appliedDefault
datapath_pollingboolDriver initialization0 (off)
mhi_timeout_msunsigned intDevice detection2000 ms
control_resp_timeout_sunsigned intSending QSM request60 s
wait_exec_default_timeout_msunsigned intBefore waic_exec; ioctl overrides5000 ms
datapath_poll_interval_usunsigned intNext polling interval100 us
timesync_delay_msunsigned intConsecutive timesync operations1000 ms

Type, application point와 default 값을 함께 정리합니다.