sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/dev-tools/kcsanmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/zh_TW/dev-tools/kcsanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/it_IT/dev-tools/kcsanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/ja_JP/dev-tools/kcsanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/ko_KR/dev-tools/kcsanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/sp_SP/dev-tools/kcsanmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhP/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/dev-tools/kcsan.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h!Documentation/dev-tools/kcsan.rsth]h)}(hhh]h!Documentation/dev-tools/kcsan.rst}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h Translatorh]h Translator}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhKubh)}(h2刘浩阳 Haoyang Liu h]h)}(h1刘浩阳 Haoyang Liu h](h刘浩阳 Haoyang Liu <}(hjhhhNhNubh reference)}(htttturtleruss@hust.edu.cnh]htttturtleruss@hust.edu.cn}(hj)hhhNhNubah}(h]h ]h"]h$]h&]refuri mailto:tttturtleruss@hust.edu.cnuh1j'hjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h内核并发消毒剂(KCSAN)h]h内核并发消毒剂(KCSAN)}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjWhhhhhK ubh)}(h内核并发消毒剂(KCSAN)是一个动态竞争检测器,依赖编译时插桩,并且使用基于观察 点的采样方法来检测竞争。KCSAN 的主要目的是检测 `数据竞争`_。h](h内核并发消毒剂(KCSAN)是一个动态竞争检测器,依赖编译时插桩,并且使用基于观察 点的采样方法来检测竞争。KCSAN 的主要目的是检测 }(hjjhhhNhNubj()}(h`数据竞争`_h]h 数据竞争}(hjrhhhNhNubah}(h]h ]h"]h$]h&]name 数据竞争refidid5uh1j'hjjresolvedKubh。}(hjjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjWhhubjV)}(hhh](j[)}(h使用h]h使用}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhKubh)}(huKCSAN 受 GCC 和 Clang 支持。使用 GCC 需要版本 11 或更高,使用 Clang 也需要 版本 11 或更高。h]huKCSAN 受 GCC 和 Clang 支持。使用 GCC 需要版本 11 或更高,使用 Clang 也需要 版本 11 或更高。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h2为了启用 KCSAN,用如下参数配置内核::h]h1为了启用 KCSAN,用如下参数配置内核:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh literal_block)}(hCONFIG_KCSAN = yh]hCONFIG_KCSAN = y}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hKCSAN 提供了几个其他的配置选项来自定义行为(见 ``lib/Kconfig.kcsan`` 中的各自的 帮助文档以获取更多信息)。h](hCKCSAN 提供了几个其他的配置选项来自定义行为(见 }(hjhhhNhNubhliteral)}(h``lib/Kconfig.kcsan``h]hlib/Kconfig.kcsan}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh8 中的各自的 帮助文档以获取更多信息)。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjV)}(hhh](j[)}(h 错误报告h]h 错误报告}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhKubh)}(h/一个典型数据竞争的报告如下所示::h]h.一个典型数据竞争的报告如下所示:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hX================================================================== BUG: KCSAN: data-race in test_kernel_read / test_kernel_write write to 0xffffffffc009a628 of 8 bytes by task 487 on cpu 0: test_kernel_write+0x1d/0x30 access_thread+0x89/0xd0 kthread+0x23e/0x260 ret_from_fork+0x22/0x30 read to 0xffffffffc009a628 of 8 bytes by task 488 on cpu 6: test_kernel_read+0x10/0x20 access_thread+0x89/0xd0 kthread+0x23e/0x260 ret_from_fork+0x22/0x30 value changed: 0x00000000000009a6 -> 0x00000000000009b2 Reported by Kernel Concurrency Sanitizer on: CPU: 6 PID: 488 Comm: access_thread Not tainted 5.12.0-rc2+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================h]hX================================================================== BUG: KCSAN: data-race in test_kernel_read / test_kernel_write write to 0xffffffffc009a628 of 8 bytes by task 487 on cpu 0: test_kernel_write+0x1d/0x30 access_thread+0x89/0xd0 kthread+0x23e/0x260 ret_from_fork+0x22/0x30 read to 0xffffffffc009a628 of 8 bytes by task 488 on cpu 6: test_kernel_read+0x10/0x20 access_thread+0x89/0xd0 kthread+0x23e/0x260 ret_from_fork+0x22/0x30 value changed: 0x00000000000009a6 -> 0x00000000000009b2 Reported by Kernel Concurrency Sanitizer on: CPU: 6 PID: 488 Comm: access_thread Not tainted 5.12.0-rc2+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhK hjhhubh)}(hX报告的头部提供了一个关于竞争中涉及到的函数的简短总结。随后是竞争中的两个线程的 访问类型和堆栈信息。如果 KCSAN 发现了一个值的变化,那么那个值的旧值和新值会在 “value changed”这一行单独显示。h]hX报告的头部提供了一个关于竞争中涉及到的函数的简短总结。随后是竞争中的两个线程的 访问类型和堆栈信息。如果 KCSAN 发现了一个值的变化,那么那个值的旧值和新值会在 “value changed”这一行单独显示。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hjhhubh)}(hA另一个不太常见的数据竞争类型的报告如下所示::h]h@另一个不太常见的数据竞争类型的报告如下所示:}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hjhhubj)}(hXv================================================================== BUG: KCSAN: data-race in test_kernel_rmw_array+0x71/0xd0 race at unknown origin, with read to 0xffffffffc009bdb0 of 8 bytes by task 515 on cpu 2: test_kernel_rmw_array+0x71/0xd0 access_thread+0x89/0xd0 kthread+0x23e/0x260 ret_from_fork+0x22/0x30 value changed: 0x0000000000002328 -> 0x0000000000002329 Reported by Kernel Concurrency Sanitizer on: CPU: 2 PID: 515 Comm: access_thread Not tainted 5.12.0-rc2+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================h]hXv================================================================== BUG: KCSAN: data-race in test_kernel_rmw_array+0x71/0xd0 race at unknown origin, with read to 0xffffffffc009bdb0 of 8 bytes by task 515 on cpu 2: test_kernel_rmw_array+0x71/0xd0 access_thread+0x89/0xd0 kthread+0x23e/0x260 ret_from_fork+0x22/0x30 value changed: 0x0000000000002328 -> 0x0000000000002329 Reported by Kernel Concurrency Sanitizer on: CPU: 2 PID: 515 Comm: access_thread Not tainted 5.12.0-rc2+ #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================}hj7sbah}(h]h ]h"]h$]h&]hhuh1jhhhK`_ 中采用 的方法。与 DataCollider 不同,KCSAN 不使用硬件观察点,而是依赖于编译器插桩和“软 观测点”。h](h如果我们在设置了地址观察点的情况下故意延迟一个内存访问,然后观察到观察点被触发 ,那么两个对同一地址的访问就发生了竞争。使用硬件观察点,这是 }(hj3 hhhNhNubj()}(hV`DataCollider `_h]h DataCollider}(hj; hhhNhNubah}(h]h ]h"]h$]h&]name DataColliderjDhttp://usenix.org/legacy/events/osdi10/tech/full_papers/Erickson.pdfuh1j'hj3 ubj)}(hG h]h}(h] datacolliderah ]h"] datacolliderah$]h&]refurijK uh1jj"Khj3 ubh 中采用 的方法。与 DataCollider 不同,KCSAN 不使用硬件观察点,而是依赖于编译器插桩和“软 观测点”。}(hj3 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hX@在 KCSAN 中,观察点是通过一种高效的编码实现的,该编码将访问类型、大小和地址存储 在一个长整型变量中;使用“软观察点”的好处是具有可移植性和更大的灵活性。然后, KCSAN依赖于编译器对普通访问的插桩。对于每个插桩的普通访问:h]hX@在 KCSAN 中,观察点是通过一种高效的编码实现的,该编码将访问类型、大小和地址存储 在一个长整型变量中;使用“软观察点”的好处是具有可移植性和更大的灵活性。然后, KCSAN依赖于编译器对普通访问的插桩。对于每个插桩的普通访问:}(hjc hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubhenumerated_list)}(hhh](j)}(h检测是否存在一个符合的观测点,如果存在,并且至少有一个操作是写操作,则我们发 现了一个竞争访问。 h]h)}(h检测是否存在一个符合的观测点,如果存在,并且至少有一个操作是写操作,则我们发 现了一个竞争访问。h]h检测是否存在一个符合的观测点,如果存在,并且至少有一个操作是写操作,则我们发 现了一个竞争访问。}(hjz hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjv ubah}(h]h ]h"]h$]h&]uh1jhjs hhhhhNubj)}(hg如果不存在匹配的观察点,则定期的设置一个观测点并随机延迟一小段时间。 h]h)}(hf如果不存在匹配的观察点,则定期的设置一个观测点并随机延迟一小段时间。h]hf如果不存在匹配的观察点,则定期的设置一个观测点并随机延迟一小段时间。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhjs hhhhhNubj)}(h在延迟前检查数据值,并在延迟后重新检查数据值;如果值不匹配,我们推测存在一个 未知来源的竞争状况。 h]h)}(h在延迟前检查数据值,并在延迟后重新检查数据值;如果值不匹配,我们推测存在一个 未知来源的竞争状况。h]h在延迟前检查数据值,并在延迟后重新检查数据值;如果值不匹配,我们推测存在一个 未知来源的竞争状况。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhjs hhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1jq hj hhhhhKubh)}(hX~为了检测普通访问和标记访问之间的数据竞争,KCSAN 也对标记访问进行标记,但仅用于 检查是否存在观察点;即 KCSAN 不会在标记访问上设置观察点。通过不在标记操作上设 置观察点,如果对一个变量的所有并发访问都被正确标记,KCSAN 将永远不会触发观察点 ,因此也不会报告这些访问。h]hX~为了检测普通访问和标记访问之间的数据竞争,KCSAN 也对标记访问进行标记,但仅用于 检查是否存在观察点;即 KCSAN 不会在标记访问上设置观察点。通过不在标记操作上设 置观察点,如果对一个变量的所有并发访问都被正确标记,KCSAN 将永远不会触发观察点 ,因此也不会报告这些访问。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubjV)}(hhh](j[)}(h弱内存建模h]h弱内存建模}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj hhhhhKubh)}(hX KCSAN 通过建模访问重新排序(使用 ``CONFIG_KCSAN_WEAK_MEMORY=y``)来检测由于缺少 内存屏障而导致的数据竞争。每个设置了观察点的普通内存访问也会被选择在其函数范围 内进行模拟重新排序(最多一个正在进行的访问)。h](h.KCSAN 通过建模访问重新排序(使用 }(hj hhhNhNubj)}(h``CONFIG_KCSAN_WEAK_MEMORY=y``h]hCONFIG_KCSAN_WEAK_MEMORY=y}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh)来检测由于缺少 内存屏障而导致的数据竞争。每个设置了观察点的普通内存访问也会被选择在其函数范围 内进行模拟重新排序(最多一个正在进行的访问)。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(h一旦某个访问被选择用于重新排序,它将在函数范围内与每个其他访问进行检查。如果遇 到适当的内存屏障,该访问将不再被考虑进行模拟重新排序。h]h一旦某个访问被选择用于重新排序,它将在函数范围内与每个其他访问进行检查。如果遇 到适当的内存屏障,该访问将不再被考虑进行模拟重新排序。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(h当内存操作的结果应该由屏障排序时,KCSAN 可以检测到仅由于缺失屏障而导致的冲突的 数据竞争。考虑下面的例子::h]h当内存操作的结果应该由屏障排序时,KCSAN 可以检测到仅由于缺失屏障而导致的冲突的 数据竞争。考虑下面的例子:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj)}(hXint x, flag; void T1(void) { x = 1; // data race! WRITE_ONCE(flag, 1); // correct: smp_store_release(&flag, 1) } void T2(void) { while (!READ_ONCE(flag)); // correct: smp_load_acquire(&flag) ... = x; // data race! }h]hXint x, flag; void T1(void) { x = 1; // data race! WRITE_ONCE(flag, 1); // correct: smp_store_release(&flag, 1) } void T2(void) { while (!READ_ONCE(flag)); // correct: smp_load_acquire(&flag) ... = x; // data race! }}hj$ sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(hX当启用了弱内存建模,KCSAN 将考虑对 ``T1`` 中的 ``x`` 进行模拟重新排序。在写入 ``flag`` 之后,x再次被检查是否有并发访问:因为 ``T2`` 可以在写入 ``flag`` 之后继续进行,因此检测到数据竞争。如果遇到了正确的屏障, ``x`` 在正确 释放 ``flag`` 后将不会被考虑重新排序,因此不会检测到数据竞争。h](h1当启用了弱内存建模,KCSAN 将考虑对 }(hj2 hhhNhNubj)}(h``T1``h]hT1}(hj: hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2 ubh 中的 }(hj2 hhhNhNubj)}(h``x``h]hx}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2 ubh& 进行模拟重新排序。在写入 }(hj2 hhhNhNubj)}(h``flag``h]hflag}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2 ubh9 之后,x再次被检查是否有并发访问:因为 }(hj2 hhhNhNubj)}(h``T2``h]hT2}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2 ubh 可以在写入 }(hj2 hhhNhNubj)}(h``flag``h]hflag}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2 ubhV 之后继续进行,因此检测到数据竞争。如果遇到了正确的屏障, }(hj2 hhhNhNubj)}(h``x``h]hx}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2 ubh 在正确 释放 }(hj2 hhhNhNubj)}(h``flag``h]hflag}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj2 ubhI 后将不会被考虑重新排序,因此不会检测到数据竞争。}(hj2 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj hhubh)}(hX在复杂性上的权衡以及实际的限制意味着只能检测到一部分由于缺失内存屏障而导致的数 据竞争。由于当前可用的编译器支持,KCSAN 的实现仅限于建模“缓冲”(延迟访问)的 效果,因为运行时不能“预取”访问。同时要注意,观测点只设置在普通访问上,这是唯 一一个 KCSAN 会模拟重新排序的访问类型。这意味着标记访问的重新排序不会被建模。h]hX在复杂性上的权衡以及实际的限制意味着只能检测到一部分由于缺失内存屏障而导致的数 据竞争。由于当前可用的编译器支持,KCSAN 的实现仅限于建模“缓冲”(延迟访问)的 效果,因为运行时不能“预取”访问。同时要注意,观测点只设置在普通访问上,这是唯 一一个 KCSAN 会模拟重新排序的访问类型。这意味着标记访问的重新排序不会被建模。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h上述情况的一个后果是获取 (acquire) 操作不需要屏障插桩(不需要预取)。此外,引 入地址或控制依赖的标记访问不需要特殊处理(标记访问不能重新排序,后续依赖的访问 不能被预取)。h]h上述情况的一个后果是获取 (acquire) 操作不需要屏障插桩(不需要预取)。此外,引 入地址或控制依赖的标记访问不需要特殊处理(标记访问不能重新排序,后续依赖的访问 不能被预取)。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]id9ah ]h"]弱内存建模ah$]h&]uh1jUhj hhhhhKubjV)}(hhh](j[)}(h 关键属性h]h 关键属性}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj hhhhhMubjr )}(hhh](j)}(h**内存开销**:整体的内存开销只有几 MiB,取决于配置。当前的实现是使用一个小长 整型数组来编码观测点信息,几乎可以忽略不计。 h]h)}(h**内存开销**:整体的内存开销只有几 MiB,取决于配置。当前的实现是使用一个小长 整型数组来编码观测点信息,几乎可以忽略不计。h](hstrong)}(h**内存开销**h]h 内存开销}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh:整体的内存开销只有几 MiB,取决于配置。当前的实现是使用一个小长 整型数组来编码观测点信息,几乎可以忽略不计。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hX**性能开销**:KCSAN 的运行时旨在性能开销最小化,使用一个高效的观测点编码,在 快速路径中不需要获取任何锁。在拥有 8 个 CPU 的系统上的内核启动来说: - 使用默认 KCSAN 配置时,性能下降 5 倍; - 仅因运行时快速路径开销导致性能下降 2.8 倍(设置非常大的 ``KCSAN_SKIP_WATCH`` 并取消设置 ``KCSAN_SKIP_WATCH_RANDOMIZE``)。 h](h)}(h**性能开销**:KCSAN 的运行时旨在性能开销最小化,使用一个高效的观测点编码,在 快速路径中不需要获取任何锁。在拥有 8 个 CPU 的系统上的内核启动来说:h](j )}(h**性能开销**h]h 性能开销}(hj& hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj" ubh:KCSAN 的运行时旨在性能开销最小化,使用一个高效的观测点编码,在 快速路径中不需要获取任何锁。在拥有 8 个 CPU 的系统上的内核启动来说:}(hj" hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM!hj ubj)}(hhh](j)}(h4使用默认 KCSAN 配置时,性能下降 5 倍;h]h)}(hjC h]h4使用默认 KCSAN 配置时,性能下降 5 倍;}(hjE hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM$hjA ubah}(h]h ]h"]h$]h&]uh1jhj> ubj)}(h仅因运行时快速路径开销导致性能下降 2.8 倍(设置非常大的 ``KCSAN_SKIP_WATCH`` 并取消设置 ``KCSAN_SKIP_WATCH_RANDOMIZE``)。 h]h)}(h仅因运行时快速路径开销导致性能下降 2.8 倍(设置非常大的 ``KCSAN_SKIP_WATCH`` 并取消设置 ``KCSAN_SKIP_WATCH_RANDOMIZE``)。h](hQ仅因运行时快速路径开销导致性能下降 2.8 倍(设置非常大的 }(hj\ hhhNhNubj)}(h``KCSAN_SKIP_WATCH``h]hKCSAN_SKIP_WATCH}(hjd hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ ubh 并取消设置 }(hj\ hhhNhNubj)}(h``KCSAN_SKIP_WATCH_RANDOMIZE``h]hKCSAN_SKIP_WATCH_RANDOMIZE}(hjv hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ ubh)。}(hj\ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM%hjX ubah}(h]h ]h"]h$]h&]uh1jhj> ubeh}(h]h ]h"]h$]h&]j-uh1jhhhM$hj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhNhNubj)}(h{**注解开销**:KCSAN 运行时之外需要的注释很少。因此,随着内核的发展维护的开 销也很小。 h]h)}(hz**注解开销**:KCSAN 运行时之外需要的注释很少。因此,随着内核的发展维护的开 销也很小。h](j )}(h**注解开销**h]h 注解开销}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhj:KCSAN 运行时之外需要的注释很少。因此,随着内核的发展维护的开 销也很小。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM(hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h~**检测设备的竞争写入**:由于设置观测点时会检查数据值,设备的竞争写入也可以 被检测到。 h]h)}(h}**检测设备的竞争写入**:由于设置观测点时会检查数据值,设备的竞争写入也可以 被检测到。h](j )}(h**检测设备的竞争写入**h]h检测设备的竞争写入}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh^:由于设置观测点时会检查数据值,设备的竞争写入也可以 被检测到。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM+hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hx**内存排序**:KCSAN 只了解一部分 LKMM 排序规则;这可能会导致漏报数据竞争( 假阴性)。 h]h)}(hw**内存排序**:KCSAN 只了解一部分 LKMM 排序规则;这可能会导致漏报数据竞争( 假阴性)。h](j )}(h**内存排序**h]h 内存排序}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhg:KCSAN 只了解一部分 LKMM 排序规则;这可能会导致漏报数据竞争( 假阴性)。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM.hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h**分析准确率**: 对于观察到的执行,由于使用采样策略,分析是 *不健全* 的 (可能有假阴性),但期望得到完整的分析(没有假阳性)。 h]h)}(h**分析准确率**: 对于观察到的执行,由于使用采样策略,分析是 *不健全* 的 (可能有假阴性),但期望得到完整的分析(没有假阳性)。h](j )}(h**分析准确率**h]h分析准确率}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhD: 对于观察到的执行,由于使用采样策略,分析是 }(hj hhhNhNubjg)}(h *不健全*h]h 不健全}(hj- hhhNhNubah}(h]h ]h"]h$]h&]uh1jfhj ubhV 的 (可能有假阴性),但期望得到完整的分析(没有假阳性)。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM1hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubeh}(h]h ]h"]h$]h&]j j j hj j uh1jq hj hhhhhMubeh}(h]id10ah ]h"] 关键属性ah$]h&]uh1jUhj hhhhhMubeh}(h]id8ah ]h"] 实现细节ah$]h&]uh1jUhjWhhhhhKubjV)}(hhh](j[)}(h考虑的替代方案h]h考虑的替代方案}(hjd hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhja hhhhhM5ubh)}(hXk一个内核数据竞争检测的替代方法是 `Kernel Thread Sanitizer (KTSAN) `_。KTSAN 是一 个基于先行发生关系(happens-before)的数据竞争检测器,它显式建立内存操作之间的先 后发生顺序,这可以用来确定 `数据竞争`_ 中定义的数据竞争。h](h1一个内核数据竞争检测的替代方法是 }(hjr hhhNhNubj()}(he`Kernel Thread Sanitizer (KTSAN) `_h]hKernel Thread Sanitizer (KTSAN)}(hjz hhhNhNubah}(h]h ]h"]h$]h&]nameKernel Thread Sanitizer (KTSAN)j@https://github.com/google/kernel-sanitizers/blob/master/KTSAN.mduh1j'hjr ubj)}(hC h]h}(h]kernel-thread-sanitizer-ktsanah ]h"]kernel thread sanitizer (ktsan)ah$]h&]refurij uh1jj"Khjr ubh。KTSAN 是一 个基于先行发生关系(happens-before)的数据竞争检测器,它显式建立内存操作之间的先 后发生顺序,这可以用来确定 }(hjr hhhNhNubj()}(h`数据竞争`_h]h 数据竞争}(hj hhhNhNubah}(h]h ]h"]h$]h&]name 数据竞争jjuh1j'hjr jKubh 中定义的数据竞争。}(hjr hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM7hja hhubh)}(hX为了建立正确的先行发生关系,KTSAN 必须了解 LKMM 的所有排序规则和同步原语。不幸 的是,任何遗漏都会导致大量的假阳性,这在包含众多自定义同步机制的内核上下文中特 别有害。为了跟踪前因后果关系,KTSAN 的实现需要为每个内存位置提供元数据(影子内 存),这意味着每页内存对应 4 页影子内存,在大型系统上可能会带来数十 GiB 的开销 。h]hX为了建立正确的先行发生关系,KTSAN 必须了解 LKMM 的所有排序规则和同步原语。不幸 的是,任何遗漏都会导致大量的假阳性,这在包含众多自定义同步机制的内核上下文中特 别有害。为了跟踪前因后果关系,KTSAN 的实现需要为每个内存位置提供元数据(影子内 存),这意味着每页内存对应 4 页影子内存,在大型系统上可能会带来数十 GiB 的开销 。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM<hja hhubeh}(h]id11ah ]h"]考虑的替代方案ah$]h&]uh1jUhjWhhhhhM5ubeh}(h]kcsanah ]h"]内核并发消毒剂(kcsan)ah$]h&]uh1jUhhhhhhhK ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jZN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}( 数据竞争](jrj e'在 lkmm 中 "标记共享内存访问"]jadebug 文件系统接口]jia)lkmm 中的 "简单访问和数据竞争"]jaurefids}nameids}(j j jJjGjjjgjjjjjJjyjBj?jjjjjjj j j^ j[ jU jR j j jV jS j j j j u nametypes}(j jJjjjjjJjBjjjj j^ jU j jV j j uh}(j jWjGjjgjjjmjjjyjj?jMjjMjjjjj jj[ j jR jL j j jS j j ja j j u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j K sRparse_messages]transform_messages] transformerN include_log]4Documentation/translations/zh_CN/dev-tools/kcsan.rst(NNNNta decorationNhhub.