hsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/core-api/padatamodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/zh_TW/core-api/padatamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/it_IT/core-api/padatamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/ja_JP/core-api/padatamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/ko_KR/core-api/padatamodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/sp_SP/core-api/padatamodnameN 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/core-api/padata.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/core-api/padata.rst h]h)}(h!Documentation/core-api/padata.rsth]h!Documentation/core-api/padata.rst}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhKubh)}(h-司延腾 Yanteng Si h]h)}(h,司延腾 Yanteng Si h](h司延腾 Yanteng Si <}(hj hhhNhNubh reference)}(hsiyanteng@loongson.cnh]hsiyanteng@loongson.cn}(hj*hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:siyanteng@loongson.cnuh1j(hj ubh>}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhtarget)}(h.. _cn_core_api_padata.rst:h]h}(h]h ]h"]h$]h&]refidcn-core-api-padata-rstuh1jVhKhhhhhhubhsection)}(hhh](htitle)}(hpadata并行执行机制h]hpadata并行执行机制}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jihjfhhhhhKubh)}(hhh]h)}(hhh](h)}(h日期h]h日期}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj|hhhKubh)}(h 2020年5月 h]h)}(h 2020年5月h]h 2020年5月}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhj|ubeh}(h]h ]h"]h$]h&]uh1hhhhKhjyhhubah}(h]h ]h"]h$]h&]uh1hhjfhhhhhKubh)}(hPadata是一种机制,内核可以通过此机制将工作分散到多个CPU上并行完成,同时 可以选择保持它们的顺序。h]hPadata是一种机制,内核可以通过此机制将工作分散到多个CPU上并行完成,同时 可以选择保持它们的顺序。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjfhhubh)}(h它最初是为IPsec开发的,它需要在不对这些数据包重新排序的其前提下,为大量的数 据包进行加密和解密。这是目前padata的序列化作业支持的唯一用途。h]h它最初是为IPsec开发的,它需要在不对这些数据包重新排序的其前提下,为大量的数 据包进行加密和解密。这是目前padata的序列化作业支持的唯一用途。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjfhhubh)}(hlPadata还支持多线程作业,将作业平均分割,同时在线程之间进行负载均衡和协调。h]hlPadata还支持多线程作业,将作业平均分割,同时在线程之间进行负载均衡和协调。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjfhhubje)}(hhh](jj)}(h执行序列化作业h]h执行序列化作业}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jihjhhhhhKubje)}(hhh](jj)}(h 初始化h]h 初始化}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jihjhhhhhKubh)}(h~使用padata执行序列化作业的第一步是建立一个padata_instance结构体,以全面 控制作业的运行方式::h]h}使用padata执行序列化作业的第一步是建立一个padata_instance结构体,以全面 控制作业的运行方式:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hjhhubh literal_block)}(hR#include struct padata_instance *padata_alloc(const char *name);h]hR#include struct padata_instance *padata_alloc(const char *name);}hj sbah}(h]h ]h"]h$]h&]hhuh1j hhhK$hjhhubh)}(h!'name'即标识了这个实例。h]h%‘name’即标识了这个实例。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hjhhubh)}(hD然后,通过分配一个padata_shell来完成padata的初始化::h]hC然后,通过分配一个padata_shell来完成padata的初始化:}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK*hjhhubj )}(hGstruct padata_shell *padata_alloc_shell(struct padata_instance *pinst);h]hGstruct padata_shell *padata_alloc_shell(struct padata_instance *pinst);}hj7sbah}(h]h ]h"]h$]h&]hhuh1j hhhK,hjhhubh)}(h一个padata_shell用于向padata提交一个作业,并允许一系列这样的作业被独立地 序列化。一个padata_instance可以有一个或多个padata_shell与之相关联,每个 都允许一系列独立的作业。h]h一个padata_shell用于向padata提交一个作业,并允许一系列这样的作业被独立地 序列化。一个padata_instance可以有一个或多个padata_shell与之相关联,每个 都允许一系列独立的作业。}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjhhubeh}(h]id2ah ]h"] 初始化ah$]h&]uh1jdhjhhhhhKubje)}(hhh](jj)}(h修改cpumasksh]h修改cpumasks}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1jihj[hhhhhK3ubh)}(h用于运行作业的CPU可以通过两种方式改变,通过padata_set_cpumask()编程或通 过sysfs。前者的定义是::h]h~用于运行作业的CPU可以通过两种方式改变,通过padata_set_cpumask()编程或通 过sysfs。前者的定义是:}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hj[hhubj )}(hvint padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, cpumask_var_t cpumask);h]hvint padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, cpumask_var_t cpumask);}hjzsbah}(h]h ]h"]h$]h&]hhuh1j hhhK8hj[hhubh)}(hX<这里cpumask_type是PADATA_CPU_PARALLEL(并行)或PADATA_CPU_SERIAL(串行)之一,其中并 行cpumask描述了哪些处理器将被用来并行执行提交给这个实例的作业,串行cpumask 定义了哪些处理器被允许用作串行化回调处理器。 cpumask指定了要使用的新cpumask。h]hX<这里cpumask_type是PADATA_CPU_PARALLEL(并行)或PADATA_CPU_SERIAL(串行)之一,其中并 行cpumask描述了哪些处理器将被用来并行执行提交给这个实例的作业,串行cpumask 定义了哪些处理器被允许用作串行化回调处理器。 cpumask指定了要使用的新cpumask。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK;hj[hhubh)}(hX'一个实例的cpumasks可能有sysfs文件。例如,pcrypt的文件在 /sys/kernel/pcrypt/。在一个实例的目录中,有两个文件,parallel_cpumask 和serial_cpumask,任何一个cpumask都可以通过在文件中回显(echo)一个bitmask 来改变,比如说::h]hX&一个实例的cpumasks可能有sysfs文件。例如,pcrypt的文件在 /sys/kernel/pcrypt/。在一个实例的目录中,有两个文件,parallel_cpumask 和serial_cpumask,任何一个cpumask都可以通过在文件中回显(echo)一个bitmask 来改变,比如说:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK?hj[hhubj )}(h5echo f > /sys/kernel/pcrypt/pencrypt/parallel_cpumaskh]h5echo f > /sys/kernel/pcrypt/pencrypt/parallel_cpumask}hjsbah}(h]h ]h"]h$]h&]hhuh1j hhhKDhj[hhubh)}(he读取其中一个文件会显示用户提供的cpumask,它可能与“可用”的cpumask不同。h]he读取其中一个文件会显示用户提供的cpumask,它可能与“可用”的cpumask不同。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKFhj[hhubh)}(hX1Padata内部维护着两对cpumask,用户提供的cpumask和“可用的”cpumask(每一对由一个 并行和一个串行cpumask组成)。用户提供的cpumasks在实例分配时默认为所有可能的CPU, 并且可以如上所述进行更改。可用的cpumasks总是用户提供的cpumasks的一个子集,只包 含用户提供的掩码中的在线CPU;这些是padata实际使用的cpumasks。因此,向padata提 供一个包含离线CPU的cpumask是合法的。一旦用户提供的cpumask中的一个离线CPU上线, padata就会使用它。h]hX1Padata内部维护着两对cpumask,用户提供的cpumask和“可用的”cpumask(每一对由一个 并行和一个串行cpumask组成)。用户提供的cpumasks在实例分配时默认为所有可能的CPU, 并且可以如上所述进行更改。可用的cpumasks总是用户提供的cpumasks的一个子集,只包 含用户提供的掩码中的在线CPU;这些是padata实际使用的cpumasks。因此,向padata提 供一个包含离线CPU的cpumask是合法的。一旦用户提供的cpumask中的一个离线CPU上线, padata就会使用它。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhj[hhubh)}(hB改变CPU掩码的操作代价很高,所以不应频繁更改。h]hB改变CPU掩码的操作代价很高,所以不应频繁更改。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKOhj[hhubeh}(h]cpumasksah ]h"]修改cpumasksah$]h&]uh1jdhjhhhhhK3ubje)}(hhh](jj)}(h运行一个作业h]h运行一个作业}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jihjhhhhhKRubh)}(hd实际上向padata实例提交工作需要创建一个padata_priv结构体,它代表一个作业::h]hc实际上向padata实例提交工作需要创建一个padata_priv结构体,它代表一个作业:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKThjhhubj )}(hstruct padata_priv { /* Other stuff here... */ void (*parallel)(struct padata_priv *padata); void (*serial)(struct padata_priv *padata); };h]hstruct padata_priv { /* Other stuff here... */ void (*parallel)(struct padata_priv *padata); void (*serial)(struct padata_priv *padata); };}hjsbah}(h]h ]h"]h$]h&]hhuh1j hhhKVhjhhubh)}(hXF这个结构体几乎肯定会被嵌入到一些针对要做的工作的大结构体中。它的大部分字段对 padata来说是私有的,但是这个结构在初始化时应该被清零,并且应该提供parallel()和 serial()函数。在完成工作的过程中,这些函数将被调用,我们马上就会遇到。h]hXF这个结构体几乎肯定会被嵌入到一些针对要做的工作的大结构体中。它的大部分字段对 padata来说是私有的,但是这个结构在初始化时应该被清零,并且应该提供parallel()和 serial()函数。在完成工作的过程中,这些函数将被调用,我们马上就会遇到。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK\hjhhubh)}(h工作的提交是通过::h]h工作的提交是通过:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjhhubj )}(hpint padata_do_parallel(struct padata_shell *ps, struct padata_priv *padata, int *cb_cpu);h]hpint padata_do_parallel(struct padata_shell *ps, struct padata_priv *padata, int *cb_cpu);}hj-sbah}(h]h ]h"]h$]h&]hhuh1j hhhKbhjhhubh)}(hXps和padata结构体必须如上所述进行设置;cb_cpu指向作业完成后用于最终回调的首选CPU; 它必须在当前实例的CPU掩码中(如果不是,cb_cpu指针将被更新为指向实际选择的CPU)。 padata_do_parallel()的返回值在成功时为0,表示工作正在进行中。-EBUSY意味着有人 在其他地方正在搞乱实例的CPU掩码,而当cb_cpu不在串行cpumask中、并行或串行cpumasks 中无在线CPU,或实例停止时,则会出现-EINVAL反馈。h]hXps和padata结构体必须如上所述进行设置;cb_cpu指向作业完成后用于最终回调的首选CPU; 它必须在当前实例的CPU掩码中(如果不是,cb_cpu指针将被更新为指向实际选择的CPU)。 padata_do_parallel()的返回值在成功时为0,表示工作正在进行中。-EBUSY意味着有人 在其他地方正在搞乱实例的CPU掩码,而当cb_cpu不在串行cpumask中、并行或串行cpumasks 中无在线CPU,或实例停止时,则会出现-EINVAL反馈。}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjhhubh)}(hX每个提交给padata_do_parallel()的作业将依次传递给一个CPU上的上述parallel()函数 的一个调用,所以真正的并行是通过提交多个作业来实现的。parallel()在运行时禁用软 件中断,因此不能睡眠。parallel()函数把获得的padata_priv结构体指针作为其唯一的参 数;关于实际要做的工作的信息可能是通过使用container_of()找到封装结构体来获得的。h]hX每个提交给padata_do_parallel()的作业将依次传递给一个CPU上的上述parallel()函数 的一个调用,所以真正的并行是通过提交多个作业来实现的。parallel()在运行时禁用软 件中断,因此不能睡眠。parallel()函数把获得的padata_priv结构体指针作为其唯一的参 数;关于实际要做的工作的信息可能是通过使用container_of()找到封装结构体来获得的。}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKkhjhhubh)}(hX请注意,parallel()没有返回值;padata子系统假定parallel()将从此时开始负责这项工 作。作业不需要在这次调用中完成,但是,如果parallel()留下了未完成的工作,它应该准 备在前一个作业完成之前,被以新的作业再次调用h]hX请注意,parallel()没有返回值;padata子系统假定parallel()将从此时开始负责这项工 作。作业不需要在这次调用中完成,但是,如果parallel()留下了未完成的工作,它应该准 备在前一个作业完成之前,被以新的作业再次调用}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKphjhhubeh}(h]id3ah ]h"]运行一个作业ah$]h&]uh1jdhjhhhhhKRubje)}(hhh](jj)}(h序列化作业h]h序列化作业}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jihjmhhhhhKuubh)}(hy当一个作业完成时,parallel()(或任何实际完成该工作的函数)应该通过调用通知padata此 事::h]hx当一个作业完成时,parallel()(或任何实际完成该工作的函数)应该通过调用通知padata此 事:}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhjmhhubj )}(h2void padata_do_serial(struct padata_priv *padata);h]h2void padata_do_serial(struct padata_priv *padata);}hjsbah}(h]h ]h"]h$]h&]hhuh1j hhhKzhjmhhubh)}(hXu在未来的某个时刻,padata_do_serial()将触发对padata_priv结构体中serial()函数的调 用。这个调用将发生在最初要求调用padata_do_parallel()的CPU上;它也是在本地软件中断 被禁用的情况下运行的。 请注意,这个调用可能会被推迟一段时间,因为padata代码会努力确保作业按照提交的顺序完 成。h]hXu在未来的某个时刻,padata_do_serial()将触发对padata_priv结构体中serial()函数的调 用。这个调用将发生在最初要求调用padata_do_parallel()的CPU上;它也是在本地软件中断 被禁用的情况下运行的。 请注意,这个调用可能会被推迟一段时间,因为padata代码会努力确保作业按照提交的顺序完 成。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjmhhubeh}(h]id4ah ]h"]序列化作业ah$]h&]uh1jdhjhhhhhKuubje)}(hhh](jj)}(h销毁h]h销毁}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jihjhhhhhKubh)}(hu清理一个padata实例时,可以预见的是调用两个free函数,这两个函数对应于分配的逆过程::h]ht清理一个padata实例时,可以预见的是调用两个free函数,这两个函数对应于分配的逆过程:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj )}(havoid padata_free_shell(struct padata_shell *ps); void padata_free(struct padata_instance *pinst);h]havoid padata_free_shell(struct padata_shell *ps); void padata_free(struct padata_instance *pinst);}hjsbah}(h]h ]h"]h$]h&]hhuh1j hhhKhjhhubh)}(h`用户有责任确保在调用上述任何一项之前,所有未完成的工作都已完成。h]h`用户有责任确保在调用上述任何一项之前,所有未完成的工作都已完成。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id5ah ]h"]销毁ah$]h&]uh1jdhjhhhhhKubeh}(h]id1ah ]h"]执行序列化作业ah$]h&]uh1jdhjfhhhhhKubje)}(hhh](jj)}(h运行多线程作业h]h运行多线程作业}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jihjhhhhhKubh)}(hX一个多线程作业有一个主线程和零个或多个辅助线程,主线程参与作业,然后等待所有辅助线 程完成。padata将作业分割成称为chunk的单元,其中chunk是一个线程在一次调用线程函数 中完成的作业片段。h]hX一个多线程作业有一个主线程和零个或多个辅助线程,主线程参与作业,然后等待所有辅助线 程完成。padata将作业分割成称为chunk的单元,其中chunk是一个线程在一次调用线程函数 中完成的作业片段。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXy用户必须做三件事来运行一个多线程作业。首先,通过定义一个padata_mt_job结构体来描述 作业,这在接口部分有解释。这包括一个指向线程函数的指针,padata每次将作业块分配给线 程时都会调用这个函数。然后,定义线程函数,它接受三个参数: ``start`` 、 ``end`` 和 ``arg`` , 其中前两个参数限定了线程操作的范围,最后一个是指向作业共享状态的指针,如果有的话。 准备好共享状态,它通常被分配在主线程的堆栈中。最后,调用padata_do_multithreaded(), 它将在作业完成后返回。h](hXE用户必须做三件事来运行一个多线程作业。首先,通过定义一个padata_mt_job结构体来描述 作业,这在接口部分有解释。这包括一个指向线程函数的指针,padata每次将作业块分配给线 程时都会调用这个函数。然后,定义线程函数,它接受三个参数: }(hjhhhNhNubhliteral)}(h ``start``h]hstart}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubh 、 }(hjhhhNhNubj#)}(h``end``h]hend}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubh 和 }(hjhhhNhNubj#)}(h``arg``h]harg}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubhX , 其中前两个参数限定了线程操作的范围,最后一个是指向作业共享状态的指针,如果有的话。 准备好共享状态,它通常被分配在主线程的堆栈中。最后,调用padata_do_multithreaded(), 它将在作业完成后返回。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id6ah ]h"]运行多线程作业ah$]h&]uh1jdhjfhhhhhKubje)}(hhh](jj)}(h接口h]h接口}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jihjhhhhhhKubh)}(h该API在以下内核代码中:h]h该API在以下内核代码中:}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhhubh)}(hinclude/linux/padata.hh]hinclude/linux/padata.h}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhhubh)}(hkernel/padata.ch]hkernel/padata.c}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhhubeh}(h]id7ah ]h"]接口ah$]h&]uh1jdhjfhhhhhKubeh}(h](padatajceh ]h"](padata并行执行机制cn_core_api_padata.rsteh$]h&]uh1jdhhhhhhhKexpect_referenced_by_name}jjXsexpect_referenced_by_id}jcjXsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jiN 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_handlerjerror_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}refids}jc]jXasnameids}(jjcjjjjjXjUjjjjjgjjjjjejbjju nametypes}(jjjjXjjjjjjejuh}(jcjfjjfjjjUjjj[jgjjjmjjjbjjjhu footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages]transform_messages]hsystem_message)}(hhh]h)}(hhh]h