← Documents Documentation/gpu/rfc/i915_vm_bind.rst GitHub 원문 ↗

Linux 6.18.37 · GPU·DRM·RFC

I915 VM_BIND feature design and use cases

Persistent mapping, execbuf3, lock hierarchy, dma_resv와 SVM use case를 설명합니다.

Source pathDocumentation/gpu/rfc/i915_vm_bind.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약·해설

i915_vm_bind.rst:1-245

Persistent mapping, execbuf3, lock hierarchy, dma_resv와 SVM use case를 설명합니다.

문서 위치
항목
SourceDocumentation/gpu/rfc/i915_vm_bind.rst
분량245 source lines
관련i915_vm_bind.h · HMM · GPU page faults

Source와 관련 symbol입니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ==========================================
2 I915 VM_BIND feature design and use cases
3 ==========================================
4
5 VM_BIND feature
6 ================
7 DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
8 objects (BOs) or sections of a BOs at specified GPU virtual addresses on a
9 specified address space (VM). These mappings (also referred to as persistent
10 mappings) will be persistent across multiple GPU submissions (execbuf calls)
11 issued by the UMD, without user having to provide a list of all required
12 mappings during each submission (as required by older execbuf mode).
13
14 The VM_BIND/UNBIND calls allow UMDs to request a timeline out fence for
15 signaling the completion of bind/unbind operation.
16
17 VM_BIND feature is advertised to user via I915_PARAM_VM_BIND_VERSION.
18 User has to opt-in for VM_BIND mode of binding for an address space (VM)
19 during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension.
20
21 VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently are
22 not ordered. Furthermore, parts of the VM_BIND/UNBIND operations can be done
23 asynchronously, when valid out fence is specified.
24
25 VM_BIND features include:
26
27 * Multiple Virtual Address (VA) mappings can map to the same physical pages
28 of an object (aliasing).
29 * VA mapping can map to a partial section of the BO (partial binding).
30 * Support capture of persistent mappings in the dump upon GPU error.
31 * Support for userptr gem objects (no special uapi is required for this).
32
33 TLB flush consideration
34 ------------------------
35 The i915 driver flushes the TLB for each submission and when an object's
36 pages are released. The VM_BIND/UNBIND operation will not do any additional
37 TLB flush. Any VM_BIND mapping added will be in the working set for subsequent
38 submissions on that VM and will not be in the working set for currently running
39 batches (which would require additional TLB flushes, which is not supported).
40
41 Execbuf ioctl in VM_BIND mode
42 -------------------------------
43 A VM in VM_BIND mode will not support older execbuf mode of binding.
44 The execbuf ioctl handling in VM_BIND mode differs significantly from the
45 older execbuf2 ioctl (See struct drm_i915_gem_execbuffer2).
46 Hence, a new execbuf3 ioctl has been added to support VM_BIND mode. (See
47 struct drm_i915_gem_execbuffer3). The execbuf3 ioctl will not accept any
48 execlist. Hence, no support for implicit sync. It is expected that the below
49 work will be able to support requirements of object dependency setting in all
50 use cases:
51
52 "dma-buf: Add an API for exporting sync files"
53 (https://lwn.net/Articles/859290/)
54
55 The new execbuf3 ioctl only works in VM_BIND mode and the VM_BIND mode only
56 works with execbuf3 ioctl for submission. All BOs mapped on that VM (through
57 VM_BIND call) at the time of execbuf3 call are deemed required for that
58 submission.
59
60 The execbuf3 ioctl directly specifies the batch addresses instead of as
61 object handles as in execbuf2 ioctl. The execbuf3 ioctl will also not
62 support many of the older features like in/out/submit fences, fence array,
63 default gem context and many more (See struct drm_i915_gem_execbuffer3).
64
65 In VM_BIND mode, VA allocation is completely managed by the user instead of
66 the i915 driver. Hence all VA assignment, eviction are not applicable in
67 VM_BIND mode. Also, for determining object activeness, VM_BIND mode will not
68 be using the i915_vma active reference tracking. It will instead use dma-resv
69 object for that (See `VM_BIND dma_resv usage`_).
70
71 So, a lot of existing code supporting execbuf2 ioctl, like relocations, VA
72 evictions, vma lookup table, implicit sync, vma active reference tracking etc.,
73 are not applicable for execbuf3 ioctl. Hence, all execbuf3 specific handling
74 should be in a separate file and only functionalities common to these ioctls
75 can be the shared code where possible.
76
77 VM_PRIVATE objects
78 -------------------
79 By default, BOs can be mapped on multiple VMs and can also be dma-buf
80 exported. Hence these BOs are referred to as Shared BOs.
81 During each execbuf submission, the request fence must be added to the
82 dma-resv fence list of all shared BOs mapped on the VM.
83
84 VM_BIND feature introduces an optimization where user can create BO which
85 is private to a specified VM via I915_GEM_CREATE_EXT_VM_PRIVATE flag during
86 BO creation. Unlike Shared BOs, these VM private BOs can only be mapped on
87 the VM they are private to and can't be dma-buf exported.
88 All private BOs of a VM share the dma-resv object. Hence during each execbuf
89 submission, they need only one dma-resv fence list updated. Thus, the fast
90 path (where required mappings are already bound) submission latency is O(1)
91 w.r.t the number of VM private BOs.
92
93 VM_BIND locking hierarchy
94 -------------------------
95 The locking design here supports the older (execlist based) execbuf mode, the
96 newer VM_BIND mode, the VM_BIND mode with GPU page faults and possible future
97 system allocator support (See `Shared Virtual Memory (SVM) support`_).
98 The older execbuf mode and the newer VM_BIND mode without page faults manages
99 residency of backing storage using dma_fence. The VM_BIND mode with page faults
100 and the system allocator support do not use any dma_fence at all.
101
102 VM_BIND locking order is as below.
103
104 1) Lock-A: A vm_bind mutex will protect vm_bind lists. This lock is taken in
105 vm_bind/vm_unbind ioctl calls, in the execbuf path and while releasing the
106 mapping.
107
108 In future, when GPU page faults are supported, we can potentially use a
109 rwsem instead, so that multiple page fault handlers can take the read side
110 lock to lookup the mapping and hence can run in parallel.
111 The older execbuf mode of binding do not need this lock.
112
113 2) Lock-B: The object's dma-resv lock will protect i915_vma state and needs to
114 be held while binding/unbinding a vma in the async worker and while updating
115 dma-resv fence list of an object. Note that private BOs of a VM will all
116 share a dma-resv object.
117
118 The future system allocator support will use the HMM prescribed locking
119 instead.
120
121 3) Lock-C: Spinlock/s to protect some of the VM's lists like the list of
122 invalidated vmas (due to eviction and userptr invalidation) etc.
123
124 When GPU page faults are supported, the execbuf path do not take any of these
125 locks. There we will simply smash the new batch buffer address into the ring and
126 then tell the scheduler run that. The lock taking only happens from the page
127 fault handler, where we take lock-A in read mode, whichever lock-B we need to
128 find the backing storage (dma_resv lock for gem objects, and hmm/core mm for
129 system allocator) and some additional locks (lock-D) for taking care of page
130 table races. Page fault mode should not need to ever manipulate the vm lists,
131 so won't ever need lock-C.
132
133 VM_BIND LRU handling
134 ---------------------
135 We need to ensure VM_BIND mapped objects are properly LRU tagged to avoid
136 performance degradation. We will also need support for bulk LRU movement of
137 VM_BIND objects to avoid additional latencies in execbuf path.
138
139 The page table pages are similar to VM_BIND mapped objects (See
140 `Evictable page table allocations`_) and are maintained per VM and needs to
141 be pinned in memory when VM is made active (ie., upon an execbuf call with
142 that VM). So, bulk LRU movement of page table pages is also needed.
143
144 VM_BIND dma_resv usage
145 -----------------------
146 Fences needs to be added to all VM_BIND mapped objects. During each execbuf
147 submission, they are added with DMA_RESV_USAGE_BOOKKEEP usage to prevent
148 over sync (See enum dma_resv_usage). One can override it with either
149 DMA_RESV_USAGE_READ or DMA_RESV_USAGE_WRITE usage during explicit object
150 dependency setting.
151
152 Note that DRM_I915_GEM_WAIT and DRM_I915_GEM_BUSY ioctls do not check for
153 DMA_RESV_USAGE_BOOKKEEP usage and hence should not be used for end of batch
154 check. Instead, the execbuf3 out fence should be used for end of batch check
155 (See struct drm_i915_gem_execbuffer3).
156
157 Also, in VM_BIND mode, use dma-resv apis for determining object activeness
158 (See dma_resv_test_signaled() and dma_resv_wait_timeout()) and do not use the
159 older i915_vma active reference tracking which is deprecated. This should be
160 easier to get it working with the current TTM backend.
161
162 Mesa use case
163 --------------
164 VM_BIND can potentially reduce the CPU overhead in Mesa (both Vulkan and Iris),
165 hence improving performance of CPU-bound applications. It also allows us to
166 implement Vulkan's Sparse Resources. With increasing GPU hardware performance,
167 reducing CPU overhead becomes more impactful.
168
169
170 Other VM_BIND use cases
171 ========================
172
173 Long running Compute contexts
174 ------------------------------
175 Usage of dma-fence expects that they complete in reasonable amount of time.
176 Compute on the other hand can be long running. Hence it is appropriate for
177 compute to use user/memory fence (See `User/Memory Fence`_) and dma-fence usage
178 must be limited to in-kernel consumption only.
179
180 Where GPU page faults are not available, kernel driver upon buffer invalidation
181 will initiate a suspend (preemption) of long running context, finish the
182 invalidation, revalidate the BO and then resume the compute context. This is
183 done by having a per-context preempt fence which is enabled when someone tries
184 to wait on it and triggers the context preemption.
185
186 User/Memory Fence
187 ~~~~~~~~~~~~~~~~~~
188 User/Memory fence is a <address, value> pair. To signal the user fence, the
189 specified value will be written at the specified virtual address and wakeup the
190 waiting process. User fence can be signaled either by the GPU or kernel async
191 worker (like upon bind completion). User can wait on a user fence with a new
192 user fence wait ioctl.
193
194 Here is some prior work on this:
195 https://patchwork.freedesktop.org/patch/349417/
196
197 Low Latency Submission
198 ~~~~~~~~~~~~~~~~~~~~~~~
199 Allows compute UMD to directly submit GPU jobs instead of through execbuf
200 ioctl. This is made possible by VM_BIND is not being synchronized against
201 execbuf. VM_BIND allows bind/unbind of mappings required for the directly
202 submitted jobs.
203
204 Debugger
205 ---------
206 With debug event interface user space process (debugger) is able to keep track
207 of and act upon resources created by another process (debugged) and attached
208 to GPU via vm_bind interface.
209
210 GPU page faults
211 ----------------
212 GPU page faults when supported (in future), will only be supported in the
213 VM_BIND mode. While both the older execbuf mode and the newer VM_BIND mode of
214 binding will require using dma-fence to ensure residency, the GPU page faults
215 mode when supported, will not use any dma-fence as residency is purely managed
216 by installing and removing/invalidating page table entries.
217
218 Page level hints settings
219 --------------------------
220 VM_BIND allows any hints setting per mapping instead of per BO. Possible hints
221 include placement and atomicity. Sub-BO level placement hint will be even more
222 relevant with upcoming GPU on-demand page fault support.
223
224 Page level Cache/CLOS settings
225 -------------------------------
226 VM_BIND allows cache/CLOS settings per mapping instead of per BO.
227
228 Evictable page table allocations
229 ---------------------------------
230 Make pagetable allocations evictable and manage them similar to VM_BIND
231 mapped objects. Page table pages are similar to persistent mappings of a
232 VM (difference here are that the page table pages will not have an i915_vma
233 structure and after swapping pages back in, parent page link needs to be
234 updated).
235
236 Shared Virtual Memory (SVM) support
237 ------------------------------------
238 VM_BIND interface can be used to map system memory directly (without gem BO
239 abstraction) using the HMM interface. SVM is only supported with GPU page
240 faults enabled.
241
242 VM_BIND UAPI
243 =============
244
245 .. kernel-doc:: Documentation/gpu/rfc/i915_vm_bind.h
246

3. 한국어 전문 번역

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

VM_BIND persistent mapping과 TLB

1-40

`DRM_I915_GEM_VM_BIND/UNBIND` ioctl은 UMD가 GEM BO 전체 또는 일부를 지정 VM의 GPU virtual address에 bind·unbind하게 합니다. Persistent mapping은 여러 execbuf submission 사이에 유지되므로 과거 execbuf처럼 매번 필요한 mapping list를 제출하지 않습니다.

Bind/unbind 완료를 알리는 timeline out fence를 요청할 수 있습니다. Feature version은 `I915_PARAM_VM_BIND_VERSION`으로 알리고, VM 생성 때 `I915_VM_CREATE_FLAGS_USE_VM_BIND` extension으로 opt-in해야 합니다.

서로 다른 CPU thread에서 동시에 실행한 VM_BIND/UNBIND ioctl 사이에는 ordering이 없습니다. 유효한 out fence를 지정하면 operation 일부를 asynchronous하게 수행할 수 있습니다.

Feature는 같은 physical page에 여러 VA를 mapping하는 aliasing, BO 일부만 mapping하는 partial binding, GPU error dump의 persistent mapping capture, 별도 uAPI 없는 userptr GEM object를 지원합니다.

i915는 각 submission과 object page release 때 TLB를 flush합니다. VM_BIND/UNBIND 자체는 추가 flush를 하지 않습니다. 새 mapping은 이후 submission의 working set에는 들어가지만 현재 실행 중인 batch에는 들어가지 않습니다. 후자는 추가 TLB flush가 필요하지만 지원하지 않습니다.

VM_BIND feature
기능내용
Persistent mapping여러 execbuf call 사이 VA 유지
Timeline out fenceBind/unbind 완료 signal
Aliasing여러 VA가 같은 physical page mapping
Partial bindingBO 일부 section mapping
Error capturePersistent mapping dump
Userptr별도 uAPI 없이 GEM userptr 지원

Persistent mapping이 제공하는 핵심 기능입니다.

VM_BIND opt-in
I915_PARAM_VM_BIND_VERSION queryUSE_VM_BIND flag로 VM 생성VM_BIND/UNBIND + optional timeline out fence현재 batch에는 반영하지 않음다음 submission의 working set에 반영

VM creation부터 다음 submission 적용까지의 순서입니다.

==========================================
I915 VM_BIND feature design and use cases
==========================================

VM_BIND feature
================
DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
objects (BOs) or sections of a BOs at specified GPU virtual addresses on a
specified address space (VM). These mappings (also referred to as persistent
mappings) will be persistent across multiple GPU submissions (execbuf calls)
issued by the UMD, without user having to provide a list of all required
mappings during each submission (as required by older execbuf mode).

The VM_BIND/UNBIND calls allow UMDs to request a timeline out fence for
signaling the completion of bind/unbind operation.

VM_BIND feature is advertised to user via I915_PARAM_VM_BIND_VERSION.
User has to opt-in for VM_BIND mode of binding for an address space (VM)
during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension.

VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently are
not ordered. Furthermore, parts of the VM_BIND/UNBIND operations can be done
asynchronously, when valid out fence is specified.

VM_BIND features include:

* Multiple Virtual Address (VA) mappings can map to the same physical pages
  of an object (aliasing).
* VA mapping can map to a partial section of the BO (partial binding).
* Support capture of persistent mappings in the dump upon GPU error.
* Support for userptr gem objects (no special uapi is required for this).

TLB flush consideration
------------------------
The i915 driver flushes the TLB for each submission and when an object's
pages are released. The VM_BIND/UNBIND operation will not do any additional
TLB flush. Any VM_BIND mapping added will be in the working set for subsequent
submissions on that VM and will not be in the working set for currently running
batches (which would require additional TLB flushes, which is not supported).

execbuf3와 VM_PRIVATE BO

41-92

VM_BIND mode VM은 과거 execbuf binding mode를 지원하지 않습니다. 처리 방식이 `drm_i915_gem_execbuffer2`와 크게 달라 새 `execbuf3` ioctl과 `drm_i915_gem_execbuffer3`를 사용합니다.

Execbuf3는 execlist를 받지 않아 implicit sync를 지원하지 않습니다. Object dependency는 dma-buf sync-file export API가 충족할 것으로 기대합니다. Execbuf3는 VM_BIND mode에서만 동작하고 VM_BIND mode도 submission에 execbuf3만 사용합니다.

Execbuf3 호출 시점에 VM_BIND로 해당 VM에 mapping된 모든 BO를 submission에 필요하다고 봅니다. Batch는 execbuf2의 object handle 대신 GPU address로 직접 지정합니다. In/out/submit fence, fence array, default GEM context 같은 과거 기능도 지원하지 않습니다.

VA allocation은 i915가 아니라 user가 완전히 관리하므로 driver VA assignment·eviction은 적용되지 않습니다. Object active 여부도 `i915_vma` active reference 대신 `dma-resv` object로 추적합니다.

따라서 relocation, VA eviction, VMA lookup table, implicit sync 같은 execbuf2 전용 code를 execbuf3에 사용하지 않습니다. Execbuf3 handling은 별도 file에 두고 정말 공통인 기능만 공유합니다.

기본 Shared BO는 여러 VM에 mapping하고 dma-buf export할 수 있습니다. 매 execbuf submission에서 VM에 mapping된 모든 shared BO의 dma-resv fence list에 request fence를 추가합니다.

`I915_GEM_CREATE_EXT_VM_PRIVATE` flag로 특정 VM 전용 BO를 만들 수 있습니다. Private BO는 그 VM에만 mapping할 수 있고 dma-buf export할 수 없습니다. VM의 모든 private BO가 dma-resv object 하나를 공유하므로 submission마다 fence list 하나만 갱신합니다. 이미 mapping된 fast path latency는 private BO 수에 대해 O(1)입니다.

execbuf2와 execbuf3
항목execbuf3
ModeVM_BIND 전용
Object listExeclist 없음
BatchObject handle 대신 GPU address
SyncImplicit sync 없음
VAUserspace가 allocation 관리
Activenessdma-resv 사용

VM_BIND mode에서 제거·변경되는 계약입니다.

VM_PRIVATE fast path
VM_PRIVATE flag로 BO 생성지정 VM에만 mapping·dma-buf export 금지VM의 private BO가 dma-resv 하나 공유Execbuf3마다 fence list 한 번 갱신Private BO 수와 무관한 O(1) latency

Private BO가 fence update를 하나로 합칩니다.

Execbuf ioctl in VM_BIND mode
-------------------------------
A VM in VM_BIND mode will not support older execbuf mode of binding.
The execbuf ioctl handling in VM_BIND mode differs significantly from the
older execbuf2 ioctl (See struct drm_i915_gem_execbuffer2).
Hence, a new execbuf3 ioctl has been added to support VM_BIND mode. (See
struct drm_i915_gem_execbuffer3). The execbuf3 ioctl will not accept any
execlist. Hence, no support for implicit sync. It is expected that the below
work will be able to support requirements of object dependency setting in all
use cases:

"dma-buf: Add an API for exporting sync files"
(https://lwn.net/Articles/859290/)

The new execbuf3 ioctl only works in VM_BIND mode and the VM_BIND mode only
works with execbuf3 ioctl for submission. All BOs mapped on that VM (through
VM_BIND call) at the time of execbuf3 call are deemed required for that
submission.

The execbuf3 ioctl directly specifies the batch addresses instead of as
object handles as in execbuf2 ioctl. The execbuf3 ioctl will also not
support many of the older features like in/out/submit fences, fence array,
default gem context and many more (See struct drm_i915_gem_execbuffer3).

In VM_BIND mode, VA allocation is completely managed by the user instead of
the i915 driver. Hence all VA assignment, eviction are not applicable in
VM_BIND mode. Also, for determining object activeness, VM_BIND mode will not
be using the i915_vma active reference tracking. It will instead use dma-resv
object for that (See `VM_BIND dma_resv usage`_).

So, a lot of existing code supporting execbuf2 ioctl, like relocations, VA
evictions, vma lookup table, implicit sync, vma active reference tracking etc.,
are not applicable for execbuf3 ioctl. Hence, all execbuf3 specific handling
should be in a separate file and only functionalities common to these ioctls
can be the shared code where possible.

VM_PRIVATE objects
-------------------
By default, BOs can be mapped on multiple VMs and can also be dma-buf
exported. Hence these BOs are referred to as Shared BOs.
During each execbuf submission, the request fence must be added to the
dma-resv fence list of all shared BOs mapped on the VM.

VM_BIND feature introduces an optimization where user can create BO which
is private to a specified VM via I915_GEM_CREATE_EXT_VM_PRIVATE flag during
BO creation. Unlike Shared BOs, these VM private BOs can only be mapped on
the VM they are private to and can't be dma-buf exported.
All private BOs of a VM share the dma-resv object. Hence during each execbuf
submission, they need only one dma-resv fence list updated. Thus, the fast
path (where required mappings are already bound) submission latency is O(1)
w.r.t the number of VM private BOs.

Lock A/B/C와 LRU

93-143

Locking 설계는 legacy execlist execbuf, 새 VM_BIND, GPU page fault가 있는 VM_BIND, 미래 system allocator를 함께 지원합니다. 앞의 두 mode는 backing storage residency에 dma_fence를 사용하지만 page-fault·system allocator mode는 dma_fence를 사용하지 않습니다.

Lock-A는 `vm_bind` mutex로 bind list를 보호하며 bind/unbind ioctl, execbuf path, mapping release에서 잡습니다. GPU page fault를 지원하면 여러 handler가 mapping lookup을 병렬 수행하도록 rwsem의 read side로 바꿀 수 있습니다. Legacy execbuf binding은 이 lock이 필요 없습니다.

Lock-B는 object의 dma-resv lock입니다. `i915_vma` state를 보호하고 async worker의 VMA bind/unbind와 object fence-list update 동안 유지합니다. 한 VM의 private BO는 dma-resv object를 공유합니다. 미래 system allocator는 HMM이 정한 locking을 사용합니다.

Lock-C는 eviction·userptr invalidation으로 invalidated된 VMA list 같은 VM list를 보호하는 spinlock입니다.

GPU page fault mode의 execbuf path는 이 lock을 하나도 잡지 않고 새 batch-buffer address를 ring에 기록한 뒤 scheduler를 실행합니다. Fault handler가 Lock-A read side, backing storage에 맞는 Lock-B(dma_resv 또는 HMM/core MM), page-table race용 추가 Lock-D를 잡습니다. Fault mode는 VM list를 조작하지 않아 Lock-C가 필요 없습니다.

VM_BIND object가 적절한 LRU tag를 갖도록 하고 execbuf latency를 줄이기 위해 bulk LRU movement를 지원해야 합니다. Page-table page도 VM별 persistent mapping과 비슷하며 VM이 execbuf로 active해질 때 memory에 pin하므로 page-table page의 bulk LRU movement도 필요합니다.

VM_BIND lock hierarchy
Lock보호 대상Page fault
AVM bind listRead side mapping lookup
Bi915_vma state·dma-resv fenceBO 또는 HMM backing storage
CInvalidated VMA 등 VM list사용하지 않음
DPage-table raceFault handler에서 추가

각 lock이 보호하는 범위와 page-fault 사용 여부입니다.

Page-fault path
Execbuf가 batch address를 ring에 기록Scheduler 실행 중 GPU page faultLock-A read로 mapping lookupdma-resv 또는 HMM/core MM lock 획득Lock-D로 page-table race 처리PTE 설치 후 execution 재개

Execbuf는 lockless하게 제출하고 fault에서 residency를 해결합니다.

VM_BIND locking hierarchy
-------------------------
The locking design here supports the older (execlist based) execbuf mode, the
newer VM_BIND mode, the VM_BIND mode with GPU page faults and possible future
system allocator support (See `Shared Virtual Memory (SVM) support`_).
The older execbuf mode and the newer VM_BIND mode without page faults manages
residency of backing storage using dma_fence. The VM_BIND mode with page faults
and the system allocator support do not use any dma_fence at all.

VM_BIND locking order is as below.

1) Lock-A: A vm_bind mutex will protect vm_bind lists. This lock is taken in
   vm_bind/vm_unbind ioctl calls, in the execbuf path and while releasing the
   mapping.

   In future, when GPU page faults are supported, we can potentially use a
   rwsem instead, so that multiple page fault handlers can take the read side
   lock to lookup the mapping and hence can run in parallel.
   The older execbuf mode of binding do not need this lock.

2) Lock-B: The object's dma-resv lock will protect i915_vma state and needs to
   be held while binding/unbinding a vma in the async worker and while updating
   dma-resv fence list of an object. Note that private BOs of a VM will all
   share a dma-resv object.

   The future system allocator support will use the HMM prescribed locking
   instead.

3) Lock-C: Spinlock/s to protect some of the VM's lists like the list of
   invalidated vmas (due to eviction and userptr invalidation) etc.

When GPU page faults are supported, the execbuf path do not take any of these
locks. There we will simply smash the new batch buffer address into the ring and
then tell the scheduler run that. The lock taking only happens from the page
fault handler, where we take lock-A in read mode, whichever lock-B we need to
find the backing storage (dma_resv lock for gem objects, and hmm/core mm for
system allocator) and some additional locks (lock-D) for taking care of page
table races. Page fault mode should not need to ever manipulate the vm lists,
so won't ever need lock-C.

VM_BIND LRU handling
---------------------
We need to ensure VM_BIND mapped objects are properly LRU tagged to avoid
performance degradation. We will also need support for bulk LRU movement of
VM_BIND objects to avoid additional latencies in execbuf path.

The page table pages are similar to VM_BIND mapped objects (See
`Evictable page table allocations`_) and are maintained per VM and needs to
be pinned in memory when VM is made active (ie., upon an execbuf call with
that VM). So, bulk LRU movement of page table pages is also needed.

dma_resv usage와 Mesa 효과

144-169

모든 VM_BIND mapped object에 fence를 추가해야 합니다. Execbuf submission마다 과도한 synchronization을 막기 위해 `DMA_RESV_USAGE_BOOKKEEP` usage로 추가하며 explicit dependency 설정에서는 `DMA_RESV_USAGE_READ` 또는 `DMA_RESV_USAGE_WRITE`로 override할 수 있습니다.

`DRM_I915_GEM_WAIT`와 `DRM_I915_GEM_BUSY` ioctl은 BOOKKEEP fence를 검사하지 않으므로 batch 종료 확인에 쓰면 안 됩니다. 대신 execbuf3 out fence를 사용해야 합니다.

Object active 여부는 deprecated된 `i915_vma` active reference가 아니라 `dma_resv_test_signaled()`와 `dma_resv_wait_timeout()` 같은 dma-resv API로 판단합니다. 이는 현재 TTM backend와 통합하기도 쉽습니다.

VM_BIND는 Vulkan과 Iris의 Mesa CPU overhead를 줄여 CPU-bound application 성능을 개선할 수 있고 Vulkan Sparse Resources 구현도 가능하게 합니다. GPU 성능이 높아질수록 CPU overhead 절감 효과가 커집니다.

dma_resv usage
Usage/API목적
DMA_RESV_USAGE_BOOKKEEP기본 VM_BIND mapped-object fence
DMA_RESV_USAGE_READExplicit read dependency
DMA_RESV_USAGE_WRITEExplicit write dependency
execbuf3 out fenceEnd-of-batch 확인
dma_resv_test_signaled/wait_timeoutObject activeness 확인

Fence 목적에 따른 usage와 batch 완료 확인입니다.

Mesa submission 이점
BO mapping을 VM_BIND로 한 번 유지Execbuf3에서 batch GPU address만 제출Per-submit relocation·VA eviction·mapping list 제거Vulkan/Iris CPU overhead 감소Sparse Resources 구현 가능

Persistent mapping으로 CPU-side 반복 작업을 줄입니다.

VM_BIND dma_resv usage
-----------------------
Fences needs to be added to all VM_BIND mapped objects. During each execbuf
submission, they are added with DMA_RESV_USAGE_BOOKKEEP usage to prevent
over sync (See enum dma_resv_usage). One can override it with either
DMA_RESV_USAGE_READ or DMA_RESV_USAGE_WRITE usage during explicit object
dependency setting.

Note that DRM_I915_GEM_WAIT and DRM_I915_GEM_BUSY ioctls do not check for
DMA_RESV_USAGE_BOOKKEEP usage and hence should not be used for end of batch
check. Instead, the execbuf3 out fence should be used for end of batch check
(See struct drm_i915_gem_execbuffer3).

Also, in VM_BIND mode, use dma-resv apis for determining object activeness
(See dma_resv_test_signaled() and dma_resv_wait_timeout()) and do not use the
older i915_vma active reference tracking which is deprecated. This should be
easier to get it working with the current TTM backend.

Mesa use case
--------------
VM_BIND can potentially reduce the CPU overhead in Mesa (both Vulkan and Iris),
hence improving performance of CPU-bound applications. It also allows us to
implement Vulkan's Sparse Resources. With increasing GPU hardware performance,
reducing CPU overhead becomes more impactful.

Compute·fault·debug·SVM use case

170-241

Long-running compute는 합리적 시간 안에 끝나야 하는 dma-fence와 맞지 않으므로 user/memory fence를 사용하고 dma-fence는 kernel 내부 소비로 제한합니다.

GPU page fault가 없으면 buffer invalidation 때 kernel이 long-running context를 suspend(preempt)하고 invalidation·BO revalidation을 끝낸 뒤 resume합니다. Context별 preempt fence는 누군가 wait할 때 활성화되어 context preemption을 trigger합니다.

User/Memory Fence는 `<address, value>` pair입니다. Signal할 때 지정 virtual address에 value를 쓰고 waiting process를 깨웁니다. GPU 또는 bind-completion async worker가 signal할 수 있고 새 user-fence-wait ioctl로 기다립니다.

Low Latency Submission은 compute UMD가 execbuf를 거치지 않고 GPU job을 직접 제출하게 합니다. VM_BIND가 execbuf와 동기화되지 않기 때문에 가능하며, 직접 제출할 job의 mapping도 VM_BIND/UNBIND로 관리합니다.

Debug event interface를 사용하면 debugger process가 다른 debugged process가 생성하고 VM_BIND로 GPU에 attach한 resource를 추적하고 조작할 수 있습니다.

미래 GPU page fault는 VM_BIND mode에서만 지원합니다. Legacy와 non-fault VM_BIND는 residency에 dma-fence를 쓰지만 fault mode는 PTE 설치·제거·invalidation으로 residency를 관리하므로 dma-fence를 사용하지 않습니다.

VM_BIND는 placement·atomicity hint를 BO가 아니라 mapping별로 설정합니다. On-demand page fault에서는 sub-BO placement hint가 더 중요합니다. Cache/CLOS도 mapping별로 설정할 수 있습니다.

Page-table allocation을 evictable하게 만들고 VM_BIND object처럼 관리합니다. 차이는 page-table page에는 `i915_vma`가 없고 swap-in 뒤 parent-page link를 갱신해야 한다는 점입니다.

SVM은 HMM interface로 GEM BO abstraction 없이 system memory를 직접 VM_BIND mapping합니다. GPU page fault가 활성화된 경우에만 지원합니다.

VM_BIND 확장 use case
기능핵심
Long computeUser/memory fence·preempt fence
Low latencyUMD direct GPU submission
Debugger다른 process의 attached resource 추적
GPU faultsPTE 기반 residency, dma-fence 없음
HintsMapping별 placement·atomicity·Cache/CLOS
Evictable PTSwap-in 뒤 parent link update
SVMHMM으로 system memory 직접 mapping

Persistent mapping이 가능하게 하는 기능입니다.

Fault-enabled SVM
Userspace system-memory rangeHMM을 통한 VM_BIND mappingGPU access가 page fault 발생Fault handler가 backing page resolveGPU page table에 PTE 설치Fence 없이 residency를 PTE validity로 관리

GEM BO 없이 system memory를 GPU VA에 연결합니다.

Other VM_BIND use cases
========================

Long running Compute contexts
------------------------------
Usage of dma-fence expects that they complete in reasonable amount of time.
Compute on the other hand can be long running. Hence it is appropriate for
compute to use user/memory fence (See `User/Memory Fence`_) and dma-fence usage
must be limited to in-kernel consumption only.

Where GPU page faults are not available, kernel driver upon buffer invalidation
will initiate a suspend (preemption) of long running context, finish the
invalidation, revalidate the BO and then resume the compute context. This is
done by having a per-context preempt fence which is enabled when someone tries
to wait on it and triggers the context preemption.

User/Memory Fence
~~~~~~~~~~~~~~~~~~
User/Memory fence is a <address, value> pair. To signal the user fence, the
specified value will be written at the specified virtual address and wakeup the
waiting process. User fence can be signaled either by the GPU or kernel async
worker (like upon bind completion). User can wait on a user fence with a new
user fence wait ioctl.

Here is some prior work on this:
https://patchwork.freedesktop.org/patch/349417/

Low Latency Submission
~~~~~~~~~~~~~~~~~~~~~~~
Allows compute UMD to directly submit GPU jobs instead of through execbuf
ioctl. This is made possible by VM_BIND is not being synchronized against
execbuf. VM_BIND allows bind/unbind of mappings required for the directly
submitted jobs.

Debugger
---------
With debug event interface user space process (debugger) is able to keep track
of and act upon resources created by another process (debugged) and attached
to GPU via vm_bind interface.

GPU page faults
----------------
GPU page faults when supported (in future), will only be supported in the
VM_BIND mode. While both the older execbuf mode and the newer VM_BIND mode of
binding will require using dma-fence to ensure residency, the GPU page faults
mode when supported, will not use any dma-fence as residency is purely managed
by installing and removing/invalidating page table entries.

Page level hints settings
--------------------------
VM_BIND allows any hints setting per mapping instead of per BO. Possible hints
include placement and atomicity. Sub-BO level placement hint will be even more
relevant with upcoming GPU on-demand page fault support.

Page level Cache/CLOS settings
-------------------------------
VM_BIND allows cache/CLOS settings per mapping instead of per BO.

Evictable page table allocations
---------------------------------
Make pagetable allocations evictable and manage them similar to VM_BIND
mapped objects. Page table pages are similar to persistent mappings of a
VM (difference here are that the page table pages will not have an i915_vma
structure and after swapping pages back in, parent page link needs to be
updated).

Shared Virtual Memory (SVM) support
------------------------------------
VM_BIND interface can be used to map system memory directly (without gem BO
abstraction) using the HMM interface. SVM is only supported with GPU page
faults enabled.

VM_BIND UAPI kernel-doc

242-245

VM_BIND UAPI의 structure와 ioctl 계약은 `Documentation/gpu/rfc/i915_vm_bind.h`의 `kernel-doc`에서 포함합니다.

VM_BIND UAPI source
항목
SourceDocumentation/gpu/rfc/i915_vm_bind.h
Directivekernel-doc

RFC header에서 실제 interface 문서를 가져옵니다.

RFC에서 UAPI로
VM_BIND feature designLocking·sync·use-case 검토i915_vm_bind.h uAPI structureKernel-doc rendering

Design 원칙을 header의 구체 계약에 연결합니다.

VM_BIND UAPI
=============

.. kernel-doc:: Documentation/gpu/rfc/i915_vm_bind.h