€•]QŒ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/arch/arm/kernel_mode_neon”Œ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/arch/arm/kernel_mode_neon”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/it_IT/arch/arm/kernel_mode_neon”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ja_JP/arch/arm/kernel_mode_neon”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ko_KR/arch/arm/kernel_mode_neon”Œ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/arch/arm/kernel_mode_neon”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒKernel mode NEON”h]”hŒKernel mode NEON”…””}”(hh¨hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hh£hžhhŸŒG/var/lib/git/docbuild/linux/Documentation/arch/arm/kernel_mode_neon.rst”h Kubh¢)”}”(hhh]”(h§)”}”(hŒ TL;DR summary”h]”hŒ TL;DR summary”…””}”(hhºhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hh·hžhhŸh¶h KubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒOUse only NEON instructions, or VFP instructions that don't rely on support code”h]”hŒ paragraph”“”)”}”(hŒOUse only NEON instructions, or VFP instructions that don't rely on support code”h]”hŒQUse only NEON instructions, or VFP instructions that don’t rely on support code”…””}”(hhÕhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h KhhÏubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊhžhhŸh¶h NubhÎ)”}”(hŒyIsolate your NEON code in a separate compilation unit, and compile it with '-march=armv7-a -mfpu=neon -mfloat-abi=softfp'”h]”hÔ)”}”(hŒyIsolate your NEON code in a separate compilation unit, and compile it with '-march=armv7-a -mfpu=neon -mfloat-abi=softfp'”h]”hŒ}Isolate your NEON code in a separate compilation unit, and compile it with ‘-march=armv7-a -mfpu=neon -mfloat-abi=softfp’”…””}”(hhíhžhhŸNh Nubah}”(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ŒXPut kernel_neon_begin() and kernel_neon_end() calls around the calls into your NEON code”h]”hÔ)”}”(hŒXPut kernel_neon_begin() and kernel_neon_end() calls around the calls into your NEON code”h]”hŒXPut kernel_neon_begin() and kernel_neon_end() calls around the calls into your NEON code”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h K hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊhžhhŸh¶h NubhÎ)”}”(hŒ_Don't sleep in your NEON code, and be aware that it will be executed with preemption disabled ”h]”hÔ)”}”(hŒ]Don't sleep in your NEON code, and be aware that it will be executed with preemption disabled”h]”hŒ_Don’t sleep in your NEON code, and be aware that it will be executed with preemption disabled”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h K hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊhžhhŸh¶h Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1hÈhŸh¶h Khh·hžhubeh}”(h]”Œ tl-dr-summary”ah ]”h"]”Œ tl;dr summary”ah$]”h&]”uh1h¡hh£hžhhŸh¶h Kubh¢)”}”(hhh]”(h§)”}”(hŒ Introduction”h]”hŒ Introduction”…””}”(hjDhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjAhžhhŸh¶h KubhÔ)”}”(hXIt is possible to use NEON instructions (and in some cases, VFP instructions) in code that runs in kernel mode. However, for performance reasons, the NEON/VFP register file is not preserved and restored at every context switch or taken exception like the normal register file is, so some manual intervention is required. Furthermore, special care is required for code that may sleep [i.e., may call schedule()], as NEON or VFP instructions will be executed in a non-preemptible section for reasons outlined below.”h]”hXIt is possible to use NEON instructions (and in some cases, VFP instructions) in code that runs in kernel mode. However, for performance reasons, the NEON/VFP register file is not preserved and restored at every context switch or taken exception like the normal register file is, so some manual intervention is required. Furthermore, special care is required for code that may sleep [i.e., may call schedule()], as NEON or VFP instructions will be executed in a non-preemptible section for reasons outlined below.”…””}”(hjRhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h KhjAhžhubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1h¡hh£hžhhŸh¶h Kubh¢)”}”(hhh]”(h§)”}”(hŒLazy preserve and restore”h]”hŒLazy preserve and restore”…””}”(hjkhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhhžhhŸh¶h KubhÔ)”}”(hX'The NEON/VFP register file is managed using lazy preserve (on UP systems) and lazy restore (on both SMP and UP systems). This means that the register file is kept 'live', and is only preserved and restored when multiple tasks are contending for the NEON/VFP unit (or, in the SMP case, when a task migrates to another core). Lazy restore is implemented by disabling the NEON/VFP unit after every context switch, resulting in a trap when subsequently a NEON/VFP instruction is issued, allowing the kernel to step in and perform the restore if necessary.”h]”hX+The NEON/VFP register file is managed using lazy preserve (on UP systems) and lazy restore (on both SMP and UP systems). This means that the register file is kept ‘live’, and is only preserved and restored when multiple tasks are contending for the NEON/VFP unit (or, in the SMP case, when a task migrates to another core). Lazy restore is implemented by disabling the NEON/VFP unit after every context switch, resulting in a trap when subsequently a NEON/VFP instruction is issued, allowing the kernel to step in and perform the restore if necessary.”…””}”(hjyhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h KhjhhžhubhÔ)”}”(hX5Any use of the NEON/VFP unit in kernel mode should not interfere with this, so it is required to do an 'eager' preserve of the NEON/VFP register file, and enable the NEON/VFP unit explicitly so no exceptions are generated on first subsequent use. This is handled by the function kernel_neon_begin(), which should be called before any kernel mode NEON or VFP instructions are issued. Likewise, the NEON/VFP unit should be disabled again after use to make sure user mode will hit the lazy restore trap upon next use. This is handled by the function kernel_neon_end().”h]”hX9Any use of the NEON/VFP unit in kernel mode should not interfere with this, so it is required to do an ‘eager’ preserve of the NEON/VFP register file, and enable the NEON/VFP unit explicitly so no exceptions are generated on first subsequent use. This is handled by the function kernel_neon_begin(), which should be called before any kernel mode NEON or VFP instructions are issued. Likewise, the NEON/VFP unit should be disabled again after use to make sure user mode will hit the lazy restore trap upon next use. This is handled by the function kernel_neon_end().”…””}”(hj‡hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h K'hjhhžhubeh}”(h]”Œlazy-preserve-and-restore”ah ]”h"]”Œlazy preserve and restore”ah$]”h&]”uh1h¡hh£hžhhŸh¶h Kubh¢)”}”(hhh]”(h§)”}”(hŒInterruptions in kernel mode”h]”hŒInterruptions in kernel mode”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h K2ubhÔ)”}”(hXFor reasons of performance and simplicity, it was decided that there shall be no preserve/restore mechanism for the kernel mode NEON/VFP register contents. This implies that interruptions of a kernel mode NEON section can only be allowed if they are guaranteed not to touch the NEON/VFP registers. For this reason, the following rules and restrictions apply in the kernel: * NEON/VFP code is not allowed in interrupt context; * NEON/VFP code is not allowed to sleep; * NEON/VFP code is executed with preemption disabled.”h]”hXFor reasons of performance and simplicity, it was decided that there shall be no preserve/restore mechanism for the kernel mode NEON/VFP register contents. This implies that interruptions of a kernel mode NEON section can only be allowed if they are guaranteed not to touch the NEON/VFP registers. For this reason, the following rules and restrictions apply in the kernel: * NEON/VFP code is not allowed in interrupt context; * NEON/VFP code is not allowed to sleep; * NEON/VFP code is executed with preemption disabled.”…””}”(hj®hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h K3hjhžhubhÔ)”}”(hX#If latency is a concern, it is possible to put back to back calls to kernel_neon_end() and kernel_neon_begin() in places in your code where none of the NEON registers are live. (Additional calls to kernel_neon_begin() should be reasonably cheap if no context switch occurred in the meantime)”h]”hX#If latency is a concern, it is possible to put back to back calls to kernel_neon_end() and kernel_neon_begin() in places in your code where none of the NEON registers are live. (Additional calls to kernel_neon_begin() should be reasonably cheap if no context switch occurred in the meantime)”…””}”(hj¼hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h K, (which #includes ), you should observe the following in addition to the rules above:”h]”hŒÐNEON intrinsics are also supported. However, as code using NEON intrinsics relies on the GCC header , (which #includes ), you should observe the following in addition to the rules above:”…””}”(hjöhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h KuhjåhžhubhÉ)”}”(hhh]”(hÎ)”}”(hŒ¬Compile the unit containing the NEON intrinsics with '-ffreestanding' so GCC uses its builtin version of (this is a C99 header which the kernel does not supply);”h]”hÔ)”}”(hŒ¬Compile the unit containing the NEON intrinsics with '-ffreestanding' so GCC uses its builtin version of (this is a C99 header which the kernel does not supply);”h]”hŒ°Compile the unit containing the NEON intrinsics with ‘-ffreestanding’ so GCC uses its builtin version of (this is a C99 header which the kernel does not supply);”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h Kyhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjhžhhŸh¶h NubhÎ)”}”(hŒ last, or at least after ”h]”hÔ)”}”(hj!h]”hŒ last, or at least after ”…””}”(hj#hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhŸh¶h K|hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjhžhhŸh¶h Nubeh}”(h]”h ]”h"]”h$]”h&]”j7j8uh1hÈhŸh¶h Kyhjåhžhubeh}”(h]”Œneon-intrinsics”ah ]”h"]”Œneon intrinsics”ah$]”h&]”uh1h¡hh£hžhhŸh¶h Ktubeh}”(h]”Œkernel-mode-neon”ah ]”h"]”Œkernel mode neon”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”joŒ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”}”(jIjFj>j;jejbjšj—jÏjÌjjj”j‘j»j¸jâjßjAj>uŒ nametypes”}”(jI‰j>‰je‰jš‰jωj‰j”‰j»‰jâ‰jA‰uh}”(jFh£j;h·jbjAj—jhjÌjjjÒj‘jj¸j—jßj¾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.