[isphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/translations/zh_CN/RCU/UPmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/zh_TW/RCU/UPmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/it_IT/RCU/UPmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ja_JP/RCU/UPmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ko_KR/RCU/UPmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/sp_SP/RCU/UPmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhtarget)}(h .. _up_doc:h]h}(h]h ]h"]h$]h&]refidup-docuh1hhKhhhhh4/var/lib/git/docbuild/linux/Documentation/RCU/UP.rstubhsection)}(hhh](htitle)}(hRCU on Uniprocessor Systemsh]hRCU on Uniprocessor Systems}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hXA common misconception is that, on UP systems, the call_rcu() primitive may immediately invoke its function. The basis of this misconception is that since there is only one CPU, it should not be necessary to wait for anything else to get done, since there are no other CPUs for anything else to be happening on. Although this approach will *sort of* work a surprising amount of the time, it is a very bad idea in general. This document presents three examples that demonstrate exactly how bad an idea this is.h](hXVA common misconception is that, on UP systems, the call_rcu() primitive may immediately invoke its function. The basis of this misconception is that since there is only one CPU, it should not be necessary to wait for anything else to get done, since there are no other CPUs for anything else to be happening on. Although this approach will }(hhhhhNhNubhemphasis)}(h *sort of*h]hsort of}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubh work a surprising amount of the time, it is a very bad idea in general. This document presents three examples that demonstrate exactly how bad an idea this is.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hExample 1: softirq Suicideh]hExample 1: softirq Suicide}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hXvSuppose that an RCU-based algorithm scans a linked list containing elements A, B, and C in process context, and can delete elements from this same list in softirq context. Suppose that the process-context scan is referencing element B when it is interrupted by softirq processing, which deletes element B, and then invokes call_rcu() to free element B after a grace period.h]hXvSuppose that an RCU-based algorithm scans a linked list containing elements A, B, and C in process context, and can delete elements from this same list in softirq context. Suppose that the process-context scan is referencing element B when it is interrupted by softirq processing, which deletes element B, and then invokes call_rcu() to free element B after a grace period.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hNow, if call_rcu() were to directly invoke its arguments, then upon return from softirq, the list scan would find itself referencing a newly freed element B. This situation can greatly decrease the life expectancy of your kernel.h]hNow, if call_rcu() were to directly invoke its arguments, then upon return from softirq, the list scan would find itself referencing a newly freed element B. This situation can greatly decrease the life expectancy of your kernel.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hWThis same problem can occur if call_rcu() is invoked from a hardware interrupt handler.h]hWThis same problem can occur if call_rcu() is invoked from a hardware interrupt handler.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]example-1-softirq-suicideah ]h"]example 1: softirq suicideah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h!Example 2: Function-Call Fatalityh]h!Example 2: Function-Call Fatality}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj,hhhhhK"ubh)}(hOf course, one could avert the suicide described in the preceding example by having call_rcu() directly invoke its arguments only if it was called from process context. However, this can fail in a similar manner.h]hOf course, one could avert the suicide described in the preceding example by having call_rcu() directly invoke its arguments only if it was called from process context. However, this can fail in a similar manner.}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hj,hhubh)}(hXSuppose that an RCU-based algorithm again scans a linked list containing elements A, B, and C in process context, but that it invokes a function on each element as it is scanned. Suppose further that this function deletes element B from the list, then passes it to call_rcu() for deferred freeing. This may be a bit unconventional, but it is perfectly legal RCU usage, since call_rcu() must wait for a grace period to elapse. Therefore, in this case, allowing call_rcu() to immediately invoke its arguments would cause it to fail to make the fundamental guarantee underlying RCU, namely that call_rcu() defers invoking its arguments until all RCU read-side critical sections currently executing have completed.h]hXSuppose that an RCU-based algorithm again scans a linked list containing elements A, B, and C in process context, but that it invokes a function on each element as it is scanned. Suppose further that this function deletes element B from the list, then passes it to call_rcu() for deferred freeing. This may be a bit unconventional, but it is perfectly legal RCU usage, since call_rcu() must wait for a grace period to elapse. Therefore, in this case, allowing call_rcu() to immediately invoke its arguments would cause it to fail to make the fundamental guarantee underlying RCU, namely that call_rcu() defers invoking its arguments until all RCU read-side critical sections currently executing have completed.}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hj,hhubhdefinition_list)}(hhh]hdefinition_list_item)}(hOQuick Quiz #1: Why is it *not* legal to invoke synchronize_rcu() in this case? h](hterm)}(hQuick Quiz #1:h]hQuick Quiz #1:}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jdhhhK4hj`ubh definition)}(hhh]h)}(h?Why is it *not* legal to invoke synchronize_rcu() in this case?h](h Why is it }(hjyhhhNhNubh)}(h*not*h]hnot}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubh0 legal to invoke synchronize_rcu() in this case?}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK4hjvubah}(h]h ]h"]h$]h&]uh1jthj`ubeh}(h]h ]h"]h$]h&]uh1j^hhhK4hj[ubah}(h]h ]h"]h$]h&]uh1jYhj,hhhhhNubh)}(h3:ref:`Answers to Quick Quiz `h]h)}(hjh]hinline)}(hjh]hAnswers to Quick Quiz}(hjhhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]refdocRCU/UP refdomainjreftyperef refexplicitrefwarn reftargetanswer_quick_quiz_upuh1hhhhK6hjubah}(h]h ]h"]h$]h&]uh1hhhhK6hj,hhubeh}(h] example-2-function-call-fatalityah ]h"]!example 2: function-call fatalityah$]h&]uh1hhhhhhhhK"ubh)}(hhh](h)}(hExample 3: Death by Deadlockh]hExample 3: Death by Deadlock}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK9ubh)}(hX:Suppose that call_rcu() is invoked while holding a lock, and that the callback function must acquire this same lock. In this case, if call_rcu() were to directly invoke the callback, the result would be self-deadlock *even if* this invocation occurred from a later call_rcu() invocation a full grace period later.h](hSuppose that call_rcu() is invoked while holding a lock, and that the callback function must acquire this same lock. In this case, if call_rcu() were to directly invoke the callback, the result would be self-deadlock }(hjhhhNhNubh)}(h *even if*h]heven if}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhW this invocation occurred from a later call_rcu() invocation a full grace period later.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK;hjhhubh)}(hIn some cases, it would possible to restructure to code so that the call_rcu() is delayed until after the lock is released. However, there are cases where this can be quite ugly:h]hIn some cases, it would possible to restructure to code so that the call_rcu() is delayed until after the lock is released. However, there are cases where this can be quite ugly:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKAhjhhubhenumerated_list)}(hhh](h list_item)}(hIf a number of items need to be passed to call_rcu() within the same critical section, then the code would need to create a list of them, then traverse the list once the lock was released. h]h)}(hIf a number of items need to be passed to call_rcu() within the same critical section, then the code would need to create a list of them, then traverse the list once the lock was released.h]hIf a number of items need to be passed to call_rcu() within the same critical section, then the code would need to create a list of them, then traverse the list once the lock was released.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEhj'ubah}(h]h ]h"]h$]h&]uh1j%hj"hhhhhNubj&)}(hXaIn some cases, the lock will be held across some kernel API, so that delaying the call_rcu() until the lock is released requires that the data item be passed up via a common API. It is far better to guarantee that callbacks are invoked with no locks held than to have to modify such APIs to allow arbitrary data items to be passed back up through them. h]h)}(hX`In some cases, the lock will be held across some kernel API, so that delaying the call_rcu() until the lock is released requires that the data item be passed up via a common API. It is far better to guarantee that callbacks are invoked with no locks held than to have to modify such APIs to allow arbitrary data items to be passed back up through them.h]hX`In some cases, the lock will be held across some kernel API, so that delaying the call_rcu() until the lock is released requires that the data item be passed up via a common API. It is far better to guarantee that callbacks are invoked with no locks held than to have to modify such APIs to allow arbitrary data items to be passed back up through them.}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhj?ubah}(h]h ]h"]h$]h&]uh1j%hj"hhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1j hjhhhhhKEubh)}(hkIf call_rcu() directly invokes the callback, painful locking restrictions or API changes would be required.h]hkIf call_rcu() directly invokes the callback, painful locking restrictions or API changes would be required.}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKQhjhhubjZ)}(hhh]j_)}(hDQuick Quiz #2: What locking restriction must RCU callbacks respect? h](je)}(hQuick Quiz #2:h]hQuick Quiz #2:}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1jdhhhKUhjsubju)}(hhh]h)}(h4What locking restriction must RCU callbacks respect?h]h4What locking restriction must RCU callbacks respect?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKUhjubah}(h]h ]h"]h$]h&]uh1jthjsubeh}(h]h ]h"]h$]h&]uh1j^hhhKUhjpubah}(h]h ]h"]h$]h&]uh1jYhjhhhhhNubh)}(h3:ref:`Answers to Quick Quiz `h]h)}(hjh]j)}(hjh]hAnswers to Quick Quiz}(hjhhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]refdocj refdomainjreftyperef refexplicitrefwarnjanswer_quick_quiz_upuh1hhhhKWhjubah}(h]h ]h"]h$]h&]uh1hhhhKWhjhhubh)}(hXIt is important to note that userspace RCU implementations *do* permit call_rcu() to directly invoke callbacks, but only if a full grace period has elapsed since those callbacks were queued. This is the case because some userspace environments are extremely constrained. Nevertheless, people writing userspace RCU implementations are strongly encouraged to avoid invoking callbacks from call_rcu(), thus obtaining the deadlock-avoidance benefits called out above.h](h;It is important to note that userspace RCU implementations }(hjhhhNhNubh)}(h*do*h]hdo}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhX permit call_rcu() to directly invoke callbacks, but only if a full grace period has elapsed since those callbacks were queued. This is the case because some userspace environments are extremely constrained. Nevertheless, people writing userspace RCU implementations are strongly encouraged to avoid invoking callbacks from call_rcu(), thus obtaining the deadlock-avoidance benefits called out above.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKYhjhhubeh}(h]example-3-death-by-deadlockah ]h"]example 3: death by deadlockah$]h&]uh1hhhhhhhhK9ubh)}(hhh](h)}(hSummaryh]hSummary}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKbubh)}(hXPermitting call_rcu() to immediately invoke its arguments breaks RCU, even on a UP system. So do not do it! Even on a UP system, the RCU infrastructure *must* respect grace periods, and *must* invoke callbacks from a known environment in which no locks are held.h](hPermitting call_rcu() to immediately invoke its arguments breaks RCU, even on a UP system. So do not do it! Even on a UP system, the RCU infrastructure }(hj hhhNhNubh)}(h*must*h]hmust}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh respect grace periods, and }(hj hhhNhNubh)}(h*must*h]hmust}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhF invoke callbacks from a known environment in which no locks are held.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKdhjhhubh)}(hNote that it *is* safe for synchronize_rcu() to return immediately on UP systems, including PREEMPT SMP builds running on UP systems.h](h Note that it }(hj<hhhNhNubh)}(h*is*h]his}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj<ubht safe for synchronize_rcu() to return immediately on UP systems, including PREEMPT SMP builds running on UP systems.}(hj<hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKihjhhubjZ)}(hhh]j_)}(heQuick Quiz #3: Why can't synchronize_rcu() return immediately on UP systems running preemptible RCU? h](je)}(hQuick Quiz #3:h]hQuick Quiz #3:}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1jdhhhKnhj_ubju)}(hhh]h)}(hUWhy can't synchronize_rcu() return immediately on UP systems running preemptible RCU?h]hWWhy can’t synchronize_rcu() return immediately on UP systems running preemptible RCU?}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKmhjqubah}(h]h ]h"]h$]h&]uh1jthj_ubeh}(h]h ]h"]h$]h&]uh1j^hhhKnhj\ubah}(h]h ]h"]h$]h&]uh1jYhjhhhhhNubh)}(h.. _answer_quick_quiz_up:h]h}(h]h ]h"]h$]h&]hanswer-quick-quiz-upuh1hhKphjhhhhubjZ)}(hhh](j_)}(hXUAnswer to Quick Quiz #1: Why is it *not* legal to invoke synchronize_rcu() in this case? Because the calling function is scanning an RCU-protected linked list, and is therefore within an RCU read-side critical section. Therefore, the called function has been invoked within an RCU read-side critical section, and is not permitted to block. h](je)}(hAnswer to Quick Quiz #1:h]hAnswer to Quick Quiz #1:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jdhhhKxhjubju)}(hhh](h)}(h?Why is it *not* legal to invoke synchronize_rcu() in this case?h](h Why is it }(hjhhhNhNubh)}(h*not*h]hnot}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh0 legal to invoke synchronize_rcu() in this case?}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKshjubh)}(hBecause the calling function is scanning an RCU-protected linked list, and is therefore within an RCU read-side critical section. Therefore, the called function has been invoked within an RCU read-side critical section, and is not permitted to block.h]hBecause the calling function is scanning an RCU-protected linked list, and is therefore within an RCU read-side critical section. Therefore, the called function has been invoked within an RCU read-side critical section, and is not permitted to block.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKuhjubeh}(h]h ]h"]h$]h&]uh1jthjubeh}(h]h ]h"]h$]h&]uh1j^hhhKxhjubj_)}(hXAnswer to Quick Quiz #2: What locking restriction must RCU callbacks respect? Any lock that is acquired within an RCU callback must be acquired elsewhere using an _bh variant of the spinlock primitive. For example, if "mylock" is acquired by an RCU callback, then a process-context acquisition of this lock must use something like spin_lock_bh() to acquire the lock. Please note that it is also OK to use _irq variants of spinlocks, for example, spin_lock_irqsave(). If the process-context code were to simply use spin_lock(), then, since RCU callbacks can be invoked from softirq context, the callback might be called from a softirq that interrupted the process-context critical section. This would result in self-deadlock. This restriction might seem gratuitous, since very few RCU callbacks acquire locks directly. However, a great many RCU callbacks do acquire locks *indirectly*, for example, via the kfree() primitive. h](je)}(hAnswer to Quick Quiz #2:h]hAnswer to Quick Quiz #2:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jdhhhKhjubju)}(hhh](h)}(h4What locking restriction must RCU callbacks respect?h]h4What locking restriction must RCU callbacks respect?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK{hjubh)}(hXAny lock that is acquired within an RCU callback must be acquired elsewhere using an _bh variant of the spinlock primitive. For example, if "mylock" is acquired by an RCU callback, then a process-context acquisition of this lock must use something like spin_lock_bh() to acquire the lock. Please note that it is also OK to use _irq variants of spinlocks, for example, spin_lock_irqsave().h]hXAny lock that is acquired within an RCU callback must be acquired elsewhere using an _bh variant of the spinlock primitive. For example, if “mylock” is acquired by an RCU callback, then a process-context acquisition of this lock must use something like spin_lock_bh() to acquire the lock. Please note that it is also OK to use _irq variants of spinlocks, for example, spin_lock_irqsave().}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK}hjubh)}(hXIf the process-context code were to simply use spin_lock(), then, since RCU callbacks can be invoked from softirq context, the callback might be called from a softirq that interrupted the process-context critical section. This would result in self-deadlock.h]hXIf the process-context code were to simply use spin_lock(), then, since RCU callbacks can be invoked from softirq context, the callback might be called from a softirq that interrupted the process-context critical section. This would result in self-deadlock.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThis restriction might seem gratuitous, since very few RCU callbacks acquire locks directly. However, a great many RCU callbacks do acquire locks *indirectly*, for example, via the kfree() primitive.h](hThis restriction might seem gratuitous, since very few RCU callbacks acquire locks directly. However, a great many RCU callbacks do acquire locks }(hj0hhhNhNubh)}(h *indirectly*h]h indirectly}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj0ubh), for example, via the kfree() primitive.}(hj0hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jthjubeh}(h]h ]h"]h$]h&]uh1j^hhhKhjhhubj_)}(hXAnswer to Quick Quiz #3: Why can't synchronize_rcu() return immediately on UP systems running preemptible RCU? Because some other task might have been preempted in the middle of an RCU read-side critical section. If synchronize_rcu() simply immediately returned, it would prematurely signal the end of the grace period, which would come as a nasty shock to that other thread when it started running again.h](je)}(hAnswer to Quick Quiz #3:h]hAnswer to Quick Quiz #3:}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1jdhhhKhj\ubju)}(hhh](h)}(hUWhy can't synchronize_rcu() return immediately on UP systems running preemptible RCU?h]hWWhy can’t synchronize_rcu() return immediately on UP systems running preemptible RCU?}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjnubh)}(hX'Because some other task might have been preempted in the middle of an RCU read-side critical section. If synchronize_rcu() simply immediately returned, it would prematurely signal the end of the grace period, which would come as a nasty shock to that other thread when it started running again.h]hX'Because some other task might have been preempted in the middle of an RCU read-side critical section. If synchronize_rcu() simply immediately returned, it would prematurely signal the end of the grace period, which would come as a nasty shock to that other thread when it started running again.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjnubeh}(h]h ]h"]h$]h&]uh1jthj\ubeh}(h]h ]h"]h$]h&]uh1j^hhhKhjhhubeh}(h]jah ]h"]answer_quick_quiz_upah$]h&]uh1jYhjhhhhhNexpect_referenced_by_name}jjsexpect_referenced_by_id}jjsubeh}(h]summaryah ]h"]summaryah$]h&]uh1hhhhhhhhKbubeh}(h](rcu-on-uniprocessor-systemsheh ]h"](rcu on uniprocessor systemsup_doceh$]h&]uh1hhhhhhhhKj}jhsj}hhsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN 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}(h]haj]jaunameids}(jhjjj)j&jjjjjjjju nametypes}(jjj)jjjjuh}(hhjhj&hjj,jjjjjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages](hsystem_message)}(hhh]h)}(hhh]h,Hyperlink target "up-doc" is not referenced.}hjEsbah}(h]h ]h"]h$]h&]uh1hhjBubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1j@ubjA)}(hhh]h)}(hhh]h:Hyperlink target "answer-quick-quiz-up" is not referenced.}hj`sbah}(h]h ]h"]h$]h&]uh1hhj]ubah}(h]h ]h"]h$]h&]levelKtypejZsourcehlineKpuh1j@ube transformerN include_log] decorationNhhub.