€•Š2Œ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/xe/xe_cs”Œ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/xe/xe_cs”Œ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/xe/xe_cs”Œ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/xe/xe_cs”Œ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/xe/xe_cs”Œ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/xe/xe_cs”Œ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ŸŒ:/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs.rst”h KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒCommand submission”h]”hŒCommand submission”…””}”(hh»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hh¶hžhhŸh³h KubhŒ paragraph”“”)”}”(hŒkExecs have historically been rather complicated in DRM drivers (at least in the i915) because a few things:”h]”hŒkExecs have historically been rather complicated in DRM drivers (at least in the i915) because a few things:”…””}”(hhĖhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h Khh¶hžhubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒHPassing in a list BO which are read / written to creating implicit syncs”h]”hŹ)”}”(hhćh]”hŒHPassing in a list BO which are read / written to creating implicit syncs”…””}”(hhåhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h Khhįubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜubhą)”}”(hŒBinding at exec time”h]”hŹ)”}”(hhūh]”hŒBinding at exec time”…””}”(hhżhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h Khhłubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜubhą)”}”(hŒ'Flow controlling the ring at exec time ”h]”hŹ)”}”(hŒ&Flow controlling the ring at exec time”h]”hŒ&Flow controlling the ring at exec time”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1hßhhÜubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1hŚhŸhņh Khh¶hžhubhŹ)”}”(hŒżIn XE we avoid all of this complication by not allowing a BO list to be passed into an exec, using the dma-buf implicit sync uAPI, have binds as separate operations, and using the DRM scheduler to flow control the ring. Let's deep dive on each of these.”h]”hŒ’In XE we avoid all of this complication by not allowing a BO list to be passed into an exec, using the dma-buf implicit sync uAPI, have binds as separate operations, and using the DRM scheduler to flow control the ring. Let’s deep dive on each of these.”…””}”(hj2hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h K hh¶hžhubhŹ)”}”(hX0We can get away from a BO list by forcing the user to use in / out fences on every exec rather than the kernel tracking dependencies of BO (e.g. if the user knows an exec writes to a BO and reads from the BO in the next exec, it is the user's responsibility to pass in / out fence between the two execs).”h]”hX2We can get away from a BO list by forcing the user to use in / out fences on every exec rather than the kernel tracking dependencies of BO (e.g. if the user knows an exec writes to a BO and reads from the BO in the next exec, it is the user’s responsibility to pass in / out fence between the two execs).”…””}”(hjAhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h K%hh¶hžhubhŹ)”}”(hX}We do not allow a user to trigger a bind at exec time rather we have a VM bind IOCTL which uses the same in / out fence interface as exec. In that sense, a VM bind is basically the same operation as an exec from the user perspective. e.g. If an exec depends on a VM bind use the in / out fence interface (struct drm_xe_sync) to synchronize like syncing between two dependent execs.”h]”hX}We do not allow a user to trigger a bind at exec time rather we have a VM bind IOCTL which uses the same in / out fence interface as exec. In that sense, a VM bind is basically the same operation as an exec from the user perspective. e.g. If an exec depends on a VM bind use the in / out fence interface (struct drm_xe_sync) to synchronize like syncing between two dependent execs.”…””}”(hjPhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h K*hh¶hžhubhŹ)”}”(hXAlthough a user cannot trigger a bind, we still have to rebind userptrs in the VM that have been invalidated since the last exec, likewise we also have to rebind BOs that have been evicted by the kernel. We schedule these rebinds behind any pending kernel operations on any external BOs in VM or any BOs private to the VM. This is accomplished by the rebinds waiting on BOs DMA_RESV_USAGE_KERNEL slot (kernel ops) and kernel ops waiting on all BOs slots (inflight execs are in the DMA_RESV_USAGE_BOOKKEEP for private BOs and for external BOs).”h]”hXAlthough a user cannot trigger a bind, we still have to rebind userptrs in the VM that have been invalidated since the last exec, likewise we also have to rebind BOs that have been evicted by the kernel. We schedule these rebinds behind any pending kernel operations on any external BOs in VM or any BOs private to the VM. This is accomplished by the rebinds waiting on BOs DMA_RESV_USAGE_KERNEL slot (kernel ops) and kernel ops waiting on all BOs slots (inflight execs are in the DMA_RESV_USAGE_BOOKKEEP for private BOs and for external BOs).”…””}”(hj_hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h K1hh¶hžhubhŹ)”}”(hŒ‘Rebinds / dma-resv usage applies to non-compute mode VMs only as for compute mode VMs we use preempt fences and a rebind worker (TODO: add link).”h]”hŒ‘Rebinds / dma-resv usage applies to non-compute mode VMs only as for compute mode VMs we use preempt fences and a rebind worker (TODO: add link).”…””}”(hjnhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h K:hh¶hžhubhŹ)”}”(hŒņThere is no need to flow control the ring in the exec as we write the ring at submission time and set the DRM scheduler max job limit SIZE_OF_RING / MAX_JOB_SIZE. The DRM scheduler will then hold all jobs until space in the ring is available.”h]”hŒņThere is no need to flow control the ring in the exec as we write the ring at submission time and set the DRM scheduler max job limit SIZE_OF_RING / MAX_JOB_SIZE. The DRM scheduler will then hold all jobs until space in the ring is available.”…””}”(hj}hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h K=hh¶hžhubhŹ)”}”(hŒ;All of this results in a rather simple exec implementation.”h]”hŒ;All of this results in a rather simple exec implementation.”…””}”(hjŒhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h KBhh¶hžhubhµ)”}”(hhh]”(hŗ)”}”(hŒFlow”h]”hŒFlow”…””}”(hjžhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hj›hŸNh NubhŒ literal_block”“”)”}”(hX¦Parse input arguments Wait for any async VM bind passed as in-fences to start <----------------------------------------------------------------------| Lock global VM lock in read mode | Pin userptrs (also finds userptr invalidated since last exec) | Lock exec (VM dma-resv lock, external BOs dma-resv locks) | Validate BOs that have been evicted | Create job | Rebind invalidated userptrs + evicted BOs (non-compute-mode) | Add rebind fence dependency to job | Add job VM dma-resv bookkeeping slot (non-compute mode) | Add job to external BOs dma-resv write slots (non-compute mode) | Check if any userptrs invalidated since pin ------ Drop locks ---------| Install in / out fences for job Submit job Unlock all”h]”hX¦Parse input arguments Wait for any async VM bind passed as in-fences to start <----------------------------------------------------------------------| Lock global VM lock in read mode | Pin userptrs (also finds userptr invalidated since last exec) | Lock exec (VM dma-resv lock, external BOs dma-resv locks) | Validate BOs that have been evicted | Create job | Rebind invalidated userptrs + evicted BOs (non-compute-mode) | Add rebind fence dependency to job | Add job VM dma-resv bookkeeping slot (non-compute mode) | Add job to external BOs dma-resv write slots (non-compute mode) | Check if any userptrs invalidated since pin ------ Drop locks ---------| Install in / out fences for job Submit job Unlock all”…””}”hj®sbah}”(h]”h ]”h"]”h$]”h&]”h±h²Œforce”‰Œlanguage”Œnone”Œhighlight_args”}”uh1j¬hŸŒX/var/lib/git/docbuild/linux/Documentation/gpu/xe/xe_cs:7: ./drivers/gpu/drm/xe/xe_exec.c”h KGhj›ubeh}”(h]”Œflow”ah ]”h"]”Œflow”ah$]”h&]”uh1h“hh¶hžhhŸNh Nubeh}”(h]”Œcommand-submission”ah ]”h"]”Œcommand submission”ah$]”h&]”uh1h“hhhžhhŸh³h 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”}”(jĻjĢjĒjÄuŒ nametypes”}”(jωjljuh}”(jĢh¶jÄj›uŒ 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”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.