€•*aŒ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/networking/iou-zcrx”Œ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/networking/iou-zcrx”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/it_IT/networking/iou-zcrx”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ja_JP/networking/iou-zcrx”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/ko_KR/networking/iou-zcrx”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ'/translations/pt_BR/networking/iou-zcrx”Œ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/networking/iou-zcrx”Œ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”h]”hŒ SPDX-License-Identifier: GPL-2.0”…””}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒA/var/lib/git/docbuild/linux/Documentation/networking/iou-zcrx.rst”h´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒio_uring zero copy Rx”h]”hŒio_uring zero copy Rx”…””}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒ Introduction”h]”hŒ Introduction”…””}”(hhàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÝh²hh³hÇh´KubhŒ paragraph”“”)”}”(hX¬io_uring zero copy Rx (ZC Rx) is a feature that removes kernel-to-user copy on the network receive path, allowing packet data to be received directly into userspace memory. This feature is different to TCP_ZEROCOPY_RECEIVE in that there are no strict alignment requirements and no need to mmap()/munmap(). Compared to kernel bypass solutions such as e.g. DPDK, the packet headers are processed by the kernel TCP stack as normal.”h]”hX¬io_uring zero copy Rx (ZC Rx) is a feature that removes kernel-to-user copy on the network receive path, allowing packet data to be received directly into userspace memory. This feature is different to TCP_ZEROCOPY_RECEIVE in that there are no strict alignment requirements and no need to mmap()/munmap(). Compared to kernel bypass solutions such as e.g. DPDK, the packet headers are processed by the kernel TCP stack as normal.”…””}”(hhðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K hhÝh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒNIC HW Requirements”h]”hŒNIC HW Requirements”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´Kubhï)”}”(hŒ“Several NIC HW features are required for io_uring ZC Rx to work. For now the kernel API does not configure the NIC and it must be done by the user.”h]”hŒ“Several NIC HW features are required for io_uring ZC Rx to work. For now the kernel API does not configure the NIC and it must be done by the user.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Khjh²hubhÉ)”}”(hhh]”(hÎ)”}”(hŒHeader/data split”h]”hŒHeader/data split”…””}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj%h²hh³hÇh´Kubhï)”}”(hŒÛRequired to split packets at the L4 boundary into a header and a payload. Headers are received into kernel memory as normal and processed by the TCP stack as normal. Payloads are received into userspace memory directly.”h]”hŒÛRequired to split packets at the L4 boundary into a header and a payload. Headers are received into kernel memory as normal and processed by the TCP stack as normal. Payloads are received into userspace memory directly.”…””}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Khj%h²hubeh}”(h]”Œheader-data-split”ah ]”h"]”Œheader/data split”ah$]”h&]”uh1hÈhjh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒ Flow steering”h]”hŒ Flow steering”…””}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjLh²hh³hÇh´Kubhï)”}”(hŒýSpecific HW Rx queues are configured for this feature, but modern NICs typically distribute flows across all HW Rx queues. Flow steering is required to ensure that only desired flows are directed towards HW queues that are configured for io_uring ZC Rx.”h]”hŒýSpecific HW Rx queues are configured for this feature, but modern NICs typically distribute flows across all HW Rx queues. Flow steering is required to ensure that only desired flows are directed towards HW queues that are configured for io_uring ZC Rx.”…””}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K!hjLh²hubeh}”(h]”Œ flow-steering”ah ]”h"]”Œ flow steering”ah$]”h&]”uh1hÈhjh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒRSS”h]”hŒRSS”…””}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjsh²hh³hÇh´K'ubhï)”}”(hŒ“In addition to flow steering above, RSS is required to steer all other non-zero copy flows away from queues that are configured for io_uring ZC Rx.”h]”hŒ“In addition to flow steering above, RSS is required to steer all other non-zero copy flows away from queues that are configured for io_uring ZC Rx.”…””}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K)hjsh²hubeh}”(h]”Œrss”ah ]”h"]”Œrss”ah$]”h&]”uh1hÈhjh²hh³hÇh´K'ubeh}”(h]”Œnic-hw-requirements”ah ]”h"]”Œnic hw requirements”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒUsage”h]”hŒUsage”…””}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj¢h²hh³hÇh´K-ubhÉ)”}”(hhh]”(hÎ)”}”(hŒ Setup NIC”h]”hŒ Setup NIC”…””}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj³h²hh³hÇh´K0ubhï)”}”(hŒ!Must be done out of band for now.”h]”hŒ!Must be done out of band for now.”…””}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K2hj³h²hubhï)”}”(hŒ&Ensure there are at least two queues::”h]”hŒ%Ensure there are at least two queues:”…””}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K4hj³h²hubhŒ literal_block”“”)”}”(hŒethtool -L eth0 combined 2”h]”hŒethtool -L eth0 combined 2”…””}”hjâsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´K6hj³h²hubhï)”}”(hŒEnable header/data split::”h]”hŒEnable header/data split:”…””}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K8hj³h²hubjá)”}”(hŒ!ethtool -G eth0 tcp-data-split on”h]”hŒ!ethtool -G eth0 tcp-data-split on”…””}”hjþsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´K:hj³h²hubhï)”}”(hŒhj³h²hubhï)”}”(hŒASet up flow steering, bearing in mind that queues are 0-indexed::”h]”hŒ@Set up flow steering, bearing in mind that queues are 0-indexed:”…””}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K@hj³h²hubjá)”}”(hŒ+ethtool -N eth0 flow-type tcp6 ... action 1”h]”hŒ+ethtool -N eth0 flow-type tcp6 ... action 1”…””}”hj6sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´KBhj³h²hubeh}”(h]”Œ setup-nic”ah ]”h"]”Œ setup nic”ah$]”h&]”uh1hÈhj¢h²hh³hÇh´K0ubhÉ)”}”(hhh]”(hÎ)”}”(hŒSetup io_uring”h]”hŒSetup io_uring”…””}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjLh²hh³hÇh´KEubhï)”}”(hŒ…This section describes the low level io_uring kernel API. Please refer to liburing documentation for how to use the higher level API.”h]”hŒ…This section describes the low level io_uring kernel API. Please refer to liburing documentation for how to use the higher level API.”…””}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KGhjLh²hubhï)”}”(hŒECreate an io_uring instance with the following required setup flags::”h]”hŒDCreate an io_uring instance with the following required setup flags:”…””}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KJhjLh²hubjá)”}”(hŒbIORING_SETUP_SINGLE_ISSUER IORING_SETUP_DEFER_TASKRUN IORING_SETUP_CQE32 or IORING_SETUP_CQE_MIXED”h]”hŒbIORING_SETUP_SINGLE_ISSUER IORING_SETUP_DEFER_TASKRUN IORING_SETUP_CQE32 or IORING_SETUP_CQE_MIXED”…””}”hjysbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´KLhjLh²hubeh}”(h]”Œsetup-io-uring”ah ]”h"]”Œsetup io_uring”ah$]”h&]”uh1hÈhj¢h²hh³hÇh´KEubhÉ)”}”(hhh]”(hÎ)”}”(hŒCreate memory area”h]”hŒCreate memory area”…””}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´KQubhï)”}”(hŒ=Allocate userspace memory area for receiving zero copy data::”h]”hŒioprio |= IORING_RECV_MULTISHOT;”h]”hŒ˜struct io_uring_sqe *sqe; sqe = io_uring_get_sqe(ring); io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, fd, NULL, 0, 0); sqe->ioprio |= IORING_RECV_MULTISHOT;”…””}”hjàsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´KžhjÁh²hubhï)”}”(hŒNow, submit and wait::”h]”hŒNow, submit and wait:”…””}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K¤hjÁh²hubjá)”}”(hŒ"io_uring_submit_and_wait(ring, 1);”h]”hŒ"io_uring_submit_and_wait(ring, 1);”…””}”hjüsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´K¦hjÁh²hubhï)”}”(hŒFinally, process completions::”h]”hŒFinally, process completions:”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K¨hjÁh²hubjá)”}”(hX€struct io_uring_cqe *cqe; unsigned int count = 0; unsigned int head; io_uring_for_each_cqe(ring, head, cqe) { struct io_uring_zcrx_cqe *rcqe = (struct io_uring_zcrx_cqe *)(cqe + 1); unsigned long mask = (1ULL << IORING_ZCRX_AREA_SHIFT) - 1; unsigned char *data = area_ptr + (rcqe->off & mask); /* do something with the data */ count++; } io_uring_cq_advance(ring, count);”h]”hX€struct io_uring_cqe *cqe; unsigned int count = 0; unsigned int head; io_uring_for_each_cqe(ring, head, cqe) { struct io_uring_zcrx_cqe *rcqe = (struct io_uring_zcrx_cqe *)(cqe + 1); unsigned long mask = (1ULL << IORING_ZCRX_AREA_SHIFT) - 1; unsigned char *data = area_ptr + (rcqe->off & mask); /* do something with the data */ count++; } io_uring_cq_advance(ring, count);”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´KªhjÁh²hubeh}”(h]”Œreceiving-data”ah ]”h"]”Œreceiving data”ah$]”h&]”uh1hÈhj¢h²hh³hÇh´KšubhÉ)”}”(hhh]”(hÎ)”}”(hŒRecycling buffers”h]”hŒRecycling buffers”…””}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj.h²hh³hÇh´Kºubhï)”}”(hŒ4Return buffers back to the kernel to be used again::”h]”hŒ3Return buffers back to the kernel to be used again:”…””}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K¼hj.h²hubjá)”}”(hXHstruct io_uring_zcrx_rqe *rqe; unsigned mask = refill_ring.ring_entries - 1; rqe = &refill_ring.rqes[refill_ring.rq_tail & mask]; unsigned long area_offset = rcqe->off & ~IORING_ZCRX_AREA_MASK; rqe->off = area_offset | area_reg.rq_area_token; rqe->len = cqe->res; IO_URING_WRITE_ONCE(*refill_ring.ktail, ++refill_ring.rq_tail);”h]”hXHstruct io_uring_zcrx_rqe *rqe; unsigned mask = refill_ring.ring_entries - 1; rqe = &refill_ring.rqes[refill_ring.rq_tail & mask]; unsigned long area_offset = rcqe->off & ~IORING_ZCRX_AREA_MASK; rqe->off = area_offset | area_reg.rq_area_token; rqe->len = cqe->res; IO_URING_WRITE_ONCE(*refill_ring.ktail, ++refill_ring.rq_tail);”…””}”hjMsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jàh³hÇh´K¾hj.h²hubeh}”(h]”Œrecycling-buffers”ah ]”h"]”Œrecycling buffers”ah$]”h&]”uh1hÈhj¢h²hh³hÇh´KºubhÉ)”}”(hhh]”(hÎ)”}”(hŒ Area chunking”h]”hŒ Area chunking”…””}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjch²hh³hÇh´KÈubhï)”}”(hXŒzcrx splits the memory area into fixed-length physically contiguous chunks. This limits the maximum buffer size returned in a single io_uring CQE. Users can provide a hint to the kernel to use larger chunks by setting the ``rx_buf_len`` field of ``struct io_uring_zcrx_ifq_reg`` to the desired length during registration. If this field is set to zero, the kernel defaults to the system page size.”h]”(hŒÞzcrx splits the memory area into fixed-length physically contiguous chunks. This limits the maximum buffer size returned in a single io_uring CQE. Users can provide a hint to the kernel to use larger chunks by setting the ”…””}”(hjth²hh³Nh´Nubjú)”}”(hŒ``rx_buf_len``”h]”hŒ rx_buf_len”…””}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jùhjtubhŒ field of ”…””}”(hjth²hh³Nh´Nubjú)”}”(hŒ ``struct io_uring_zcrx_ifq_reg``”h]”hŒstruct io_uring_zcrx_ifq_reg”…””}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jùhjtubhŒv to the desired length during registration. If this field is set to zero, the kernel defaults to the system page size.”…””}”(hjth²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KÊhjch²hubhï)”}”(hXTo use larger sizes, the memory area must be backed by physically contiguous ranges whose sizes are multiples of ``rx_buf_len``. It also requires kernel and hardware support. If registration fails, users are generally expected to fall back to defaults by setting ``rx_buf_len`` to zero.”h]”(hŒqTo use larger sizes, the memory area must be backed by physically contiguous ranges whose sizes are multiples of ”…””}”(hj¦h²hh³Nh´Nubjú)”}”(hŒ``rx_buf_len``”h]”hŒ rx_buf_len”…””}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jùhj¦ubhŒˆ. It also requires kernel and hardware support. If registration fails, users are generally expected to fall back to defaults by setting ”…””}”(hj¦h²hh³Nh´Nubjú)”}”(hŒ``rx_buf_len``”h]”hŒ rx_buf_len”…””}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jùhj¦ubhŒ to zero.”…””}”(hj¦h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KÑhjch²hubhï)”}”(hŒõLarger chunks don't give any additional guarantees about buffer sizes returned in CQEs, and they can vary depending on many factors like traffic pattern, hardware offload, etc. It doesn't require any application changes beyond zcrx registration.”h]”hŒùLarger chunks don’t give any additional guarantees about buffer sizes returned in CQEs, and they can vary depending on many factors like traffic pattern, hardware offload, etc. It doesn’t require any application changes beyond zcrx registration.”…””}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KÖhjch²hubeh}”(h]”Œ area-chunking”ah ]”h"]”Œ area chunking”ah$]”h&]”uh1hÈhj¢h²hh³hÇh´KÈubeh}”(h]”Œusage”ah ]”h"]”Œusage”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K-ubhÉ)”}”(hhh]”(hÎ)”}”(hŒTesting”h]”hŒTesting”…””}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjöh²hh³hÇh´KÜubhï)”}”(hŒ9See ``tools/testing/selftests/drivers/net/hw/iou-zcrx.c``”h]”(hŒSee ”…””}”(hjh²hh³Nh´Nubjú)”}”(hŒ5``tools/testing/selftests/drivers/net/hw/iou-zcrx.c``”h]”hŒ1tools/testing/selftests/drivers/net/hw/iou-zcrx.c”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jùhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KÞhjöh²hubeh}”(h]”Œtesting”ah ]”h"]”Œtesting”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KÜubeh}”(h]”Œio-uring-zero-copy-rx”ah ]”h"]”Œio_uring zero copy rx”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”jVŒ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”}”(j0j-jjjŸjœjIjFjpjmj—j”jójðjIjFjŒj‰jÁj¾j&j#jwjtj¾j»j+j(j`j]jëjèj(j%uŒ nametypes”}”(j0‰j‰jŸ‰jI‰jp‰j—‰jó‰jI‰jŒ‰jÁ‰j&‰jw‰j¾‰j+‰j`‰jë‰j(‰uh}”(j-hÊjhÝjœjjFj%jmjLj”jsjðj¢jFj³j‰jLj¾jj#jÄjtj)j»jzj(jÁj]j.jèjcj%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.