€•M–Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ)/translations/zh_CN/gpu/drm-vm-bind-async”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/zh_TW/gpu/drm-vm-bind-async”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/it_IT/gpu/drm-vm-bind-async”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/ja_JP/gpu/drm-vm-bind-async”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/ko_KR/gpu/drm-vm-bind-async”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ)/translations/sp_SP/gpu/drm-vm-bind-async”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ*SPDX-License-Identifier: (GPL-2.0+ OR MIT)”h]”hŒ*SPDX-License-Identifier: (GPL-2.0+ OR MIT)”…””}”hh£sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1h¡hhhžhhŸŒC/var/lib/git/docbuild/linux/Documentation/gpu/drm-vm-bind-async.rst”h KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒAsynchronous VM_BIND”h]”hŒAsynchronous VM_BIND”…””}”(hh»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hh¶hžhhŸh³h Kubhµ)”}”(hhh]”(hº)”}”(hŒ Nomenclature:”h]”hŒ Nomenclature:”…””}”(hhÌhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hhÉhžhhŸh³h KubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒJ``VRAM``: On-device memory. Sometimes referred to as device local memory. ”h]”hŒ paragraph”“”)”}”(hŒI``VRAM``: On-device memory. Sometimes referred to as device local memory.”h]”(hŒliteral”“”)”}”(hŒ``VRAM``”h]”hŒVRAM”…””}”(hhíhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhhçubhŒA: On-device memory. Sometimes referred to as device local memory.”…””}”(hhçhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K hháubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒi``gpu_vm``: A virtual GPU address space. Typically per process, but can be shared by multiple processes. ”h]”hæ)”}”(hŒh``gpu_vm``: A virtual GPU address space. Typically per process, but can be shared by multiple processes.”h]”(hì)”}”(hŒ ``gpu_vm``”h]”hŒgpu_vm”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjubhŒ^: A virtual GPU address space. Typically per process, but can be shared by multiple processes.”…””}”(hjhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒš``VM_BIND``: An operation or a list of operations to modify a gpu_vm using an IOCTL. The operations include mapping and unmapping system- or VRAM memory. ”h]”hæ)”}”(hŒ™``VM_BIND``: An operation or a list of operations to modify a gpu_vm using an IOCTL. The operations include mapping and unmapping system- or VRAM memory.”h]”(hì)”}”(hŒ ``VM_BIND``”h]”hŒVM_BIND”…””}”(hj9hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhj5ubhŒŽ: An operation or a list of operations to modify a gpu_vm using an IOCTL. The operations include mapping and unmapping system- or VRAM memory.”…””}”(hj5hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h Khj1ubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒé``syncobj``: A container that abstracts synchronization objects. The synchronization objects can be either generic, like dma-fences or driver specific. A syncobj typically indicates the type of the underlying synchronization object. ”h]”hæ)”}”(hŒè``syncobj``: A container that abstracts synchronization objects. The synchronization objects can be either generic, like dma-fences or driver specific. A syncobj typically indicates the type of the underlying synchronization object.”h]”(hì)”}”(hŒ ``syncobj``”h]”hŒsyncobj”…””}”(hj_hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhj[ubhŒÝ: A container that abstracts synchronization objects. The synchronization objects can be either generic, like dma-fences or driver specific. A syncobj typically indicates the type of the underlying synchronization object.”…””}”(hj[hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KhjWubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒd``in-syncobj``: Argument to a VM_BIND IOCTL, the VM_BIND operation waits for these before starting. ”h]”hæ)”}”(hŒc``in-syncobj``: Argument to a VM_BIND IOCTL, the VM_BIND operation waits for these before starting.”h]”(hì)”}”(hŒ``in-syncobj``”h]”hŒ in-syncobj”…””}”(hj…hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjubhŒU: Argument to a VM_BIND IOCTL, the VM_BIND operation waits for these before starting.”…””}”(hjhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h Khj}ubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒw``out-syncobj``: Argument to a VM_BIND_IOCTL, the VM_BIND operation signals these when the bind operation is complete. ”h]”hæ)”}”(hŒv``out-syncobj``: Argument to a VM_BIND_IOCTL, the VM_BIND operation signals these when the bind operation is complete.”h]”(hì)”}”(hŒ``out-syncobj``”h]”hŒ out-syncobj”…””}”(hj«hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhj§ubhŒg: Argument to a VM_BIND_IOCTL, the VM_BIND operation signals these when the bind operation is complete.”…””}”(hj§hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h Khj£ubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒÛ``dma-fence``: A cross-driver synchronization object. A basic understanding of dma-fences is required to digest this document. Please refer to the ``DMA Fences`` section of the :doc:`dma-buf doc `. ”h]”hæ)”}”(hŒÚ``dma-fence``: A cross-driver synchronization object. A basic understanding of dma-fences is required to digest this document. Please refer to the ``DMA Fences`` section of the :doc:`dma-buf doc `.”h]”(hì)”}”(hŒ ``dma-fence``”h]”hŒ dma-fence”…””}”(hjÑhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjÍubhŒ†: A cross-driver synchronization object. A basic understanding of dma-fences is required to digest this document. Please refer to the ”…””}”(hjÍhžhhŸNh Nubhì)”}”(hŒ``DMA Fences``”h]”hŒ DMA Fences”…””}”(hjãhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjÍubhŒ section of the ”…””}”(hjÍhžhhŸNh Nubh)”}”(hŒ(:doc:`dma-buf doc `”h]”hŒinline”“”)”}”(hj÷h]”hŒ dma-buf doc”…””}”(hjûhžhhŸNh Nubah}”(h]”h ]”(Œxref”Œstd”Œstd-doc”eh"]”h$]”h&]”uh1jùhjõubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œgpu/drm-vm-bind-async”Œ refdomain”jŒreftype”Œdoc”Œ refexplicit”ˆŒrefwarn”ˆŒ reftarget”Œ/driver-api/dma-buf”uh1hhŸh³h KhjÍubhŒ.”…””}”(hjÍhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KhjÉubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hXé``memory fence``: A synchronization object, different from a dma-fence. A memory fence uses the value of a specified memory location to determine signaled status. A memory fence can be awaited and signaled by both the GPU and CPU. Memory fences are sometimes referred to as user-fences, userspace-fences or gpu futexes and do not necessarily obey the dma-fence rule of signaling within a "reasonable amount of time". The kernel should thus avoid waiting for memory fences with locks held. ”h]”hæ)”}”(hXè``memory fence``: A synchronization object, different from a dma-fence. A memory fence uses the value of a specified memory location to determine signaled status. A memory fence can be awaited and signaled by both the GPU and CPU. Memory fences are sometimes referred to as user-fences, userspace-fences or gpu futexes and do not necessarily obey the dma-fence rule of signaling within a "reasonable amount of time". The kernel should thus avoid waiting for memory fences with locks held.”h]”(hì)”}”(hŒ``memory fence``”h]”hŒ memory fence”…””}”(hj2hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhj.ubhXÜ: A synchronization object, different from a dma-fence. A memory fence uses the value of a specified memory location to determine signaled status. A memory fence can be awaited and signaled by both the GPU and CPU. Memory fences are sometimes referred to as user-fences, userspace-fences or gpu futexes and do not necessarily obey the dma-fence rule of signaling within a “reasonable amount of timeâ€. The kernel should thus avoid waiting for memory fences with locks held.”…””}”(hj.hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K#hj*ubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hX``long-running workload``: A workload that may take more than the current stipulated dma-fence maximum signal delay to complete and which therefore needs to set the gpu_vm or the GPU execution context in a certain mode that disallows completion dma-fences. ”h]”hæ)”}”(hX``long-running workload``: A workload that may take more than the current stipulated dma-fence maximum signal delay to complete and which therefore needs to set the gpu_vm or the GPU execution context in a certain mode that disallows completion dma-fences.”h]”(hì)”}”(hŒ``long-running workload``”h]”hŒlong-running workload”…””}”(hjXhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjTubhŒç: A workload that may take more than the current stipulated dma-fence maximum signal delay to complete and which therefore needs to set the gpu_vm or the GPU execution context in a certain mode that disallows completion dma-fences.”…””}”(hjThžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K+hjPubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hX``exec function``: An exec function is a function that revalidates all affected gpu_vmas, submits a GPU command batch and registers the dma_fence representing the GPU command's activity with all affected dma_resvs. For completeness, although not covered by this document, it's worth mentioning that an exec function may also be the revalidation worker that is used by some drivers in compute / long-running mode. ”h]”hæ)”}”(hXœ``exec function``: An exec function is a function that revalidates all affected gpu_vmas, submits a GPU command batch and registers the dma_fence representing the GPU command's activity with all affected dma_resvs. For completeness, although not covered by this document, it's worth mentioning that an exec function may also be the revalidation worker that is used by some drivers in compute / long-running mode.”h]”(hì)”}”(hŒ``exec function``”h]”hŒ exec function”…””}”(hj~hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjzubhX: An exec function is a function that revalidates all affected gpu_vmas, submits a GPU command batch and registers the dma_fence representing the GPU command’s activity with all affected dma_resvs. For completeness, although not covered by this document, it’s worth mentioning that an exec function may also be the revalidation worker that is used by some drivers in compute / long-running mode.”…””}”(hjzhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K0hjvubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hX``bind context``: A context identifier used for the VM_BIND operation. VM_BIND operations that use the same bind context can be assumed, where it matters, to complete in order of submission. No such assumptions can be made for VM_BIND operations using separate bind contexts. ”h]”hæ)”}”(hX``bind context``: A context identifier used for the VM_BIND operation. VM_BIND operations that use the same bind context can be assumed, where it matters, to complete in order of submission. No such assumptions can be made for VM_BIND operations using separate bind contexts.”h]”(hì)”}”(hŒ``bind context``”h]”hŒ bind context”…””}”(hj¤hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhj ubhX: A context identifier used for the VM_BIND operation. VM_BIND operations that use the same bind context can be assumed, where it matters, to complete in order of submission. No such assumptions can be made for VM_BIND operations using separate bind contexts.”…””}”(hj hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K8hjœubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒ``UMD``: User-mode driver. ”h]”hæ)”}”(hŒ``UMD``: User-mode driver.”h]”(hì)”}”(hŒ``UMD``”h]”hŒUMD”…””}”(hjÊhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjÆubhŒ: User-mode driver.”…””}”(hjÆhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K=hjÂubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubhà)”}”(hŒ``KMD``: Kernel-mode driver. ”h]”hæ)”}”(hŒ``KMD``: Kernel-mode driver.”h]”(hì)”}”(hŒ``KMD``”h]”hŒKMD”…””}”(hjðhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhjìubhŒ: Kernel-mode driver.”…””}”(hjìhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K?hjèubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜhžhhŸh³h Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1hÚhŸh³h K hhÉhžhubeh}”(h]”Œ nomenclature”ah ]”h"]”Œ nomenclature:”ah$]”h&]”uh1h´hh¶hžhhŸh³h Kubhµ)”}”(hhh]”(hº)”}”(hŒ,Synchronous / Asynchronous VM_BIND operation”h]”hŒ,Synchronous / Asynchronous VM_BIND operation”…””}”(hj!hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hjhžhhŸh³h KCubhµ)”}”(hhh]”(hº)”}”(hŒSynchronous VM_BIND”h]”hŒSynchronous VM_BIND”…””}”(hj2hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hj/hžhhŸh³h KFubhæ)”}”(hX With Synchronous VM_BIND, the VM_BIND operations all complete before the IOCTL returns. A synchronous VM_BIND takes neither in-fences nor out-fences. Synchronous VM_BIND may block and wait for GPU operations; for example swap-in or clearing, or even previous binds.”h]”hX With Synchronous VM_BIND, the VM_BIND operations all complete before the IOCTL returns. A synchronous VM_BIND takes neither in-fences nor out-fences. Synchronous VM_BIND may block and wait for GPU operations; for example swap-in or clearing, or even previous binds.”…””}”(hj@hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KGhj/hžhubeh}”(h]”Œsynchronous-vm-bind”ah ]”h"]”Œsynchronous vm_bind”ah$]”h&]”uh1h´hjhžhhŸh³h KFubhµ)”}”(hhh]”(hº)”}”(hŒAsynchronous VM_BIND”h]”hŒAsynchronous VM_BIND”…””}”(hjYhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hjVhžhhŸh³h KMubhæ)”}”(hX?Asynchronous VM_BIND accepts both in-syncobjs and out-syncobjs. While the IOCTL may return immediately, the VM_BIND operations wait for the in-syncobjs before modifying the GPU page-tables, and signal the out-syncobjs when the modification is done in the sense that the next exec function that awaits for the out-syncobjs will see the change. Errors are reported synchronously. In low-memory situations the implementation may block, performing the VM_BIND synchronously, because there might not be enough memory immediately available for preparing the asynchronous operation.”h]”hX?Asynchronous VM_BIND accepts both in-syncobjs and out-syncobjs. While the IOCTL may return immediately, the VM_BIND operations wait for the in-syncobjs before modifying the GPU page-tables, and signal the out-syncobjs when the modification is done in the sense that the next exec function that awaits for the out-syncobjs will see the change. Errors are reported synchronously. In low-memory situations the implementation may block, performing the VM_BIND synchronously, because there might not be enough memory immediately available for preparing the asynchronous operation.”…””}”(hjghžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KNhjVhžhubhæ)”}”(hX2If the VM_BIND IOCTL takes a list or an array of operations as an argument, the in-syncobjs needs to signal before the first operation starts to execute, and the out-syncobjs signal after the last operation completes. Operations in the operation list can be assumed, where it matters, to complete in order.”h]”hX2If the VM_BIND IOCTL takes a list or an array of operations as an argument, the in-syncobjs needs to signal before the first operation starts to execute, and the out-syncobjs signal after the last operation completes. Operations in the operation list can be assumed, where it matters, to complete in order.”…””}”(hjuhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KXhjVhžhubhæ)”}”(hX‰Since asynchronous VM_BIND operations may use dma-fences embedded in out-syncobjs and internally in KMD to signal bind completion, any memory fences given as VM_BIND in-fences need to be awaited synchronously before the VM_BIND ioctl returns, since dma-fences, required to signal in a reasonable amount of time, can never be made to depend on memory fences that don't have such a restriction.”h]”hX‹Since asynchronous VM_BIND operations may use dma-fences embedded in out-syncobjs and internally in KMD to signal bind completion, any memory fences given as VM_BIND in-fences need to be awaited synchronously before the VM_BIND ioctl returns, since dma-fences, required to signal in a reasonable amount of time, can never be made to depend on memory fences that don’t have such a restriction.”…””}”(hjƒhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K^hjVhžhubhæ)”}”(hXPThe purpose of an Asynchronous VM_BIND operation is for user-mode drivers to be able to pipeline interleaved gpu_vm modifications and exec functions. For long-running workloads, such pipelining of a bind operation is not allowed and any in-fences need to be awaited synchronously. The reason for this is twofold. First, any memory fences gated by a long-running workload and used as in-syncobjs for the VM_BIND operation will need to be awaited synchronously anyway (see above). Second, any dma-fences used as in-syncobjs for VM_BIND operations for long-running workloads will not allow for pipelining anyway since long-running workloads don't allow for dma-fences as out-syncobjs, so while theoretically possible the use of them is questionable and should be rejected until there is a valuable use-case. Note that this is not a limitation imposed by dma-fence rules, but rather a limitation imposed to keep KMD implementation simple. It does not affect using dma-fences as dependencies for the long-running workload itself, which is allowed by dma-fence rules, but rather for the VM_BIND operation only.”h]”hXRThe purpose of an Asynchronous VM_BIND operation is for user-mode drivers to be able to pipeline interleaved gpu_vm modifications and exec functions. For long-running workloads, such pipelining of a bind operation is not allowed and any in-fences need to be awaited synchronously. The reason for this is twofold. First, any memory fences gated by a long-running workload and used as in-syncobjs for the VM_BIND operation will need to be awaited synchronously anyway (see above). Second, any dma-fences used as in-syncobjs for VM_BIND operations for long-running workloads will not allow for pipelining anyway since long-running workloads don’t allow for dma-fences as out-syncobjs, so while theoretically possible the use of them is questionable and should be rejected until there is a valuable use-case. Note that this is not a limitation imposed by dma-fence rules, but rather a limitation imposed to keep KMD implementation simple. It does not affect using dma-fences as dependencies for the long-running workload itself, which is allowed by dma-fence rules, but rather for the VM_BIND operation only.”…””}”(hj‘hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KehjVhžhubhæ)”}”(hXAn asynchronous VM_BIND operation may take substantial time to complete and signal the out_fence. In particular if the operation is deeply pipelined behind other VM_BIND operations and workloads submitted using exec functions. In that case, UMD might want to avoid a subsequent VM_BIND operation to be queued behind the first one if there are no explicit dependencies. In order to circumvent such a queue-up, a VM_BIND implementation may allow for VM_BIND contexts to be created. For each context, VM_BIND operations will be guaranteed to complete in the order they were submitted, but that is not the case for VM_BIND operations executing on separate VM_BIND contexts. Instead KMD will attempt to execute such VM_BIND operations in parallel but leaving no guarantee that they will actually be executed in parallel. There may be internal implicit dependencies that only KMD knows about, for example page-table structure changes. A way to attempt to avoid such internal dependencies is to have different VM_BIND contexts use separate regions of a VM.”h]”hXAn asynchronous VM_BIND operation may take substantial time to complete and signal the out_fence. In particular if the operation is deeply pipelined behind other VM_BIND operations and workloads submitted using exec functions. In that case, UMD might want to avoid a subsequent VM_BIND operation to be queued behind the first one if there are no explicit dependencies. In order to circumvent such a queue-up, a VM_BIND implementation may allow for VM_BIND contexts to be created. For each context, VM_BIND operations will be guaranteed to complete in the order they were submitted, but that is not the case for VM_BIND operations executing on separate VM_BIND contexts. Instead KMD will attempt to execute such VM_BIND operations in parallel but leaving no guarantee that they will actually be executed in parallel. There may be internal implicit dependencies that only KMD knows about, for example page-table structure changes. A way to attempt to avoid such internal dependencies is to have different VM_BIND contexts use separate regions of a VM.”…””}”(hjŸhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KwhjVhžhubhæ)”}”(hXãAlso for VM_BINDS for long-running gpu_vms the user-mode driver should typically select memory fences as out-fences since that gives greater flexibility for the kernel mode driver to inject other operations into the bind / unbind operations. Like for example inserting breakpoints into batch buffers. The workload execution can then easily be pipelined behind the bind completion using the memory out-fence as the signal condition for a GPU semaphore embedded by UMD in the workload.”h]”hXãAlso for VM_BINDS for long-running gpu_vms the user-mode driver should typically select memory fences as out-fences since that gives greater flexibility for the kernel mode driver to inject other operations into the bind / unbind operations. Like for example inserting breakpoints into batch buffers. The workload execution can then easily be pipelined behind the bind completion using the memory out-fence as the signal condition for a GPU semaphore embedded by UMD in the workload.”…””}”(hj­hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KˆhjVhžhubhæ)”}”(hŒ†There is no difference in the operations supported or in multi-operation support between asynchronous VM_BIND and synchronous VM_BIND.”h]”hŒ†There is no difference in the operations supported or in multi-operation support between asynchronous VM_BIND and synchronous VM_BIND.”…””}”(hj»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h KhjVhžhubeh}”(h]”Œid1”ah ]”h"]”h$]”Œasynchronous vm_bind”ah&]”uh1h´hjhžhhŸh³h KMŒ referenced”Kubeh}”(h]”Œ*synchronous-asynchronous-vm-bind-operation”ah ]”h"]”Œ,synchronous / asynchronous vm_bind operation”ah$]”h&]”uh1h´hh¶hžhhŸh³h KCubhµ)”}”(hhh]”(hº)”}”(hŒ;Multi-operation VM_BIND IOCTL error handling and interrupts”h]”hŒ;Multi-operation VM_BIND IOCTL error handling and interrupts”…””}”(hjÝhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hjÚhžhhŸh³h K”ubhæ)”}”(hXBThe VM_BIND operations of the IOCTL may error for various reasons, for example due to lack of resources to complete and due to interrupted waits. In these situations UMD should preferably restart the IOCTL after taking suitable action. If UMD has over-committed a memory resource, an -ENOSPC error will be returned, and UMD may then unbind resources that are not used at the moment and rerun the IOCTL. On -EINTR, UMD should simply rerun the IOCTL and on -ENOMEM user-space may either attempt to free known system memory resources or fail. In case of UMD deciding to fail a bind operation, due to an error return, no additional action is needed to clean up the failed operation, and the VM is left in the same state as it was before the failing IOCTL. Unbind operations are guaranteed not to return any errors due to resource constraints, but may return errors due to, for example, invalid arguments or the gpu_vm being banned. In the case an unexpected error happens during the asynchronous bind process, the gpu_vm will be banned, and attempts to use it after banning will return -ENOENT.”h]”hXBThe VM_BIND operations of the IOCTL may error for various reasons, for example due to lack of resources to complete and due to interrupted waits. In these situations UMD should preferably restart the IOCTL after taking suitable action. If UMD has over-committed a memory resource, an -ENOSPC error will be returned, and UMD may then unbind resources that are not used at the moment and rerun the IOCTL. On -EINTR, UMD should simply rerun the IOCTL and on -ENOMEM user-space may either attempt to free known system memory resources or fail. In case of UMD deciding to fail a bind operation, due to an error return, no additional action is needed to clean up the failed operation, and the VM is left in the same state as it was before the failing IOCTL. Unbind operations are guaranteed not to return any errors due to resource constraints, but may return errors due to, for example, invalid arguments or the gpu_vm being banned. In the case an unexpected error happens during the asynchronous bind process, the gpu_vm will be banned, and attempts to use it after banning will return -ENOENT.”…””}”(hjëhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K–hjÚhžhubeh}”(h]”Œ;multi-operation-vm-bind-ioctl-error-handling-and-interrupts”ah ]”h"]”Œ;multi-operation vm_bind ioctl error handling and interrupts”ah$]”h&]”uh1h´hh¶hžhhŸh³h K”ubhµ)”}”(hhh]”(hº)”}”(hŒExample: The Xe VM_BIND uAPI”h]”hŒExample: The Xe VM_BIND uAPI”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hjhžhhŸh³h K«ubhæ)”}”(hX2Starting with the VM_BIND operation struct, the IOCTL call can take zero, one or many such operations. A zero number means only the synchronization part of the IOCTL is carried out: an asynchronous VM_BIND updates the syncobjects, whereas a sync VM_BIND waits for the implicit dependencies to be fulfilled.”h]”hX2Starting with the VM_BIND operation struct, the IOCTL call can take zero, one or many such operations. A zero number means only the synchronization part of the IOCTL is carried out: an asynchronous VM_BIND updates the syncobjects, whereas a sync VM_BIND waits for the implicit dependencies to be fulfilled.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h K­hjhžhubhŒ literal_block”“”)”}”(hX( struct drm_xe_vm_bind_op { /** * @obj: GEM object to operate on, MBZ for MAP_USERPTR, MBZ for UNMAP */ __u32 obj; /** @pad: MBZ */ __u32 pad; union { /** * @obj_offset: Offset into the object for MAP. */ __u64 obj_offset; /** @userptr: user virtual address for MAP_USERPTR */ __u64 userptr; }; /** * @range: Number of bytes from the object to bind to addr, MBZ for UNMAP_ALL */ __u64 range; /** @addr: Address to operate on, MBZ for UNMAP_ALL */ __u64 addr; /** * @tile_mask: Mask for which tiles to create binds for, 0 == All tiles, * only applies to creating new VMAs */ __u64 tile_mask; /* Map (parts of) an object into the GPU virtual address range. #define XE_VM_BIND_OP_MAP 0x0 /* Unmap a GPU virtual address range */ #define XE_VM_BIND_OP_UNMAP 0x1 /* * Map a CPU virtual address range into a GPU virtual * address range. */ #define XE_VM_BIND_OP_MAP_USERPTR 0x2 /* Unmap a gem object from the VM. */ #define XE_VM_BIND_OP_UNMAP_ALL 0x3 /* * Make the backing memory of an address range resident if * possible. Note that this doesn't pin backing memory. */ #define XE_VM_BIND_OP_PREFETCH 0x4 /* Make the GPU map readonly. */ #define XE_VM_BIND_FLAG_READONLY (0x1 << 16) /* * Valid on a faulting VM only, do the MAP operation immediately rather * than deferring the MAP to the page fault handler. */ #define XE_VM_BIND_FLAG_IMMEDIATE (0x1 << 17) /* * When the NULL flag is set, the page tables are setup with a special * bit which indicates writes are dropped and all reads return zero. In * the future, the NULL flags will only be valid for XE_VM_BIND_OP_MAP * operations, the BO handle MBZ, and the BO offset MBZ. This flag is * intended to implement VK sparse bindings. */ #define XE_VM_BIND_FLAG_NULL (0x1 << 18) /** @op: Operation to perform (lower 16 bits) and flags (upper 16 bits) */ __u32 op; /** @mem_region: Memory region to prefetch VMA to, instance not a mask */ __u32 region; /** @reserved: Reserved */ __u64 reserved[2]; };”h]”hX( struct drm_xe_vm_bind_op { /** * @obj: GEM object to operate on, MBZ for MAP_USERPTR, MBZ for UNMAP */ __u32 obj; /** @pad: MBZ */ __u32 pad; union { /** * @obj_offset: Offset into the object for MAP. */ __u64 obj_offset; /** @userptr: user virtual address for MAP_USERPTR */ __u64 userptr; }; /** * @range: Number of bytes from the object to bind to addr, MBZ for UNMAP_ALL */ __u64 range; /** @addr: Address to operate on, MBZ for UNMAP_ALL */ __u64 addr; /** * @tile_mask: Mask for which tiles to create binds for, 0 == All tiles, * only applies to creating new VMAs */ __u64 tile_mask; /* Map (parts of) an object into the GPU virtual address range. #define XE_VM_BIND_OP_MAP 0x0 /* Unmap a GPU virtual address range */ #define XE_VM_BIND_OP_UNMAP 0x1 /* * Map a CPU virtual address range into a GPU virtual * address range. */ #define XE_VM_BIND_OP_MAP_USERPTR 0x2 /* Unmap a gem object from the VM. */ #define XE_VM_BIND_OP_UNMAP_ALL 0x3 /* * Make the backing memory of an address range resident if * possible. Note that this doesn't pin backing memory. */ #define XE_VM_BIND_OP_PREFETCH 0x4 /* Make the GPU map readonly. */ #define XE_VM_BIND_FLAG_READONLY (0x1 << 16) /* * Valid on a faulting VM only, do the MAP operation immediately rather * than deferring the MAP to the page fault handler. */ #define XE_VM_BIND_FLAG_IMMEDIATE (0x1 << 17) /* * When the NULL flag is set, the page tables are setup with a special * bit which indicates writes are dropped and all reads return zero. In * the future, the NULL flags will only be valid for XE_VM_BIND_OP_MAP * operations, the BO handle MBZ, and the BO offset MBZ. This flag is * intended to implement VK sparse bindings. */ #define XE_VM_BIND_FLAG_NULL (0x1 << 18) /** @op: Operation to perform (lower 16 bits) and flags (upper 16 bits) */ __u32 op; /** @mem_region: Memory region to prefetch VMA to, instance not a mask */ __u32 region; /** @reserved: Reserved */ __u64 reserved[2]; };”…””}”hj"sbah}”(h]”h ]”h"]”h$]”h&]”h±h²Œforce”‰Œlanguage”Œc”Œhighlight_args”}”uh1j hŸh³h K³hjhžhubhæ)”}”(hXThe VM_BIND IOCTL argument itself, looks like follows. Note that for synchronous VM_BIND, the num_syncs and syncs fields must be zero. Here the ``exec_queue_id`` field is the VM_BIND context discussed previously that is used to facilitate out-of-order VM_BINDs.”h]”(hŒThe VM_BIND IOCTL argument itself, looks like follows. Note that for synchronous VM_BIND, the num_syncs and syncs fields must be zero. Here the ”…””}”(hj5hžhhŸNh Nubhì)”}”(hŒ``exec_queue_id``”h]”hŒ exec_queue_id”…””}”(hj=hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëhj5ubhŒd field is the VM_BIND context discussed previously that is used to facilitate out-of-order VM_BINDs.”…””}”(hj5hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1håhŸh³h Mhjhžhubj!)”}”(hXÕstruct drm_xe_vm_bind { /** @extensions: Pointer to the first extension struct, if any */ __u64 extensions; /** @vm_id: The ID of the VM to bind to */ __u32 vm_id; /** * @exec_queue_id: exec_queue_id, must be of class DRM_XE_ENGINE_CLASS_VM_BIND * and exec queue must have same vm_id. If zero, the default VM bind engine * is used. */ __u32 exec_queue_id; /** @num_binds: number of binds in this IOCTL */ __u32 num_binds; /* If set, perform an async VM_BIND, if clear a sync VM_BIND */ #define XE_VM_BIND_IOCTL_FLAG_ASYNC (0x1 << 0) /** @flag: Flags controlling all operations in this ioctl. */ __u32 flags; union { /** @bind: used if num_binds == 1 */ struct drm_xe_vm_bind_op bind; /** * @vector_of_binds: userptr to array of struct * drm_xe_vm_bind_op if num_binds > 1 */ __u64 vector_of_binds; }; /** @num_syncs: amount of syncs to wait for or to signal on completion. */ __u32 num_syncs; /** @pad2: MBZ */ __u32 pad2; /** @syncs: pointer to struct drm_xe_sync array */ __u64 syncs; /** @reserved: Reserved */ __u64 reserved[2]; };”h]”hXÕstruct drm_xe_vm_bind { /** @extensions: Pointer to the first extension struct, if any */ __u64 extensions; /** @vm_id: The ID of the VM to bind to */ __u32 vm_id; /** * @exec_queue_id: exec_queue_id, must be of class DRM_XE_ENGINE_CLASS_VM_BIND * and exec queue must have same vm_id. If zero, the default VM bind engine * is used. */ __u32 exec_queue_id; /** @num_binds: number of binds in this IOCTL */ __u32 num_binds; /* If set, perform an async VM_BIND, if clear a sync VM_BIND */ #define XE_VM_BIND_IOCTL_FLAG_ASYNC (0x1 << 0) /** @flag: Flags controlling all operations in this ioctl. */ __u32 flags; union { /** @bind: used if num_binds == 1 */ struct drm_xe_vm_bind_op bind; /** * @vector_of_binds: userptr to array of struct * drm_xe_vm_bind_op if num_binds > 1 */ __u64 vector_of_binds; }; /** @num_syncs: amount of syncs to wait for or to signal on completion. */ __u32 num_syncs; /** @pad2: MBZ */ __u32 pad2; /** @syncs: pointer to struct drm_xe_sync array */ __u64 syncs; /** @reserved: Reserved */ __u64 reserved[2]; };”…””}”hjUsbah}”(h]”h ]”h"]”h$]”h&]”h±h²j0‰j1j2j3}”uh1j hŸh³h Mhjhžhubeh}”(h]”Œexample-the-xe-vm-bind-uapi”ah ]”h"]”Œexample: the xe vm_bind uapi”ah$]”h&]”uh1h´hh¶hžhhŸh³h K«ubeh}”(h]”Œasynchronous-vm-bind”ah ]”h"]”h$]”jÏah&]”uh1h´hhhžhhŸh³h KjÑKubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h³uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(h¹NŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j–Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”h³Œ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(Œasynchronous vm_bind”Njjj×jÔjSjPjþjûjijfuŒ nametypes”}”(jÚ‰j‰j׉jS‰jþ‰ji‰uh}”(jnh¶jhÉjÔjjPj/jËjVjûjÚjfjuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”j¤Ks…”R”Œparse_messages”]”hŒsystem_message”“”)”}”(hhh]”hæ)”}”(hŒ7Duplicate implicit target name: "asynchronous vm_bind".”h]”hŒ;Duplicate implicit target name: “asynchronous vm_bindâ€.”…””}”(hjþhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1håhjûubah}”(h]”h ]”h"]”h$]”h&]”jËaŒlevel”KŒtype”ŒINFO”Œsource”h³Œline”KMuh1jùhjVhžhhŸh³h KMubaŒtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.