€•³zŒ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/mm/ksm”Œ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/mm/ksm”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/it_IT/mm/ksm”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/ja_JP/mm/ksm”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/ko_KR/mm/ksm”Œ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/mm/ksm”Œ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/mm/ksm”Œ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 Samepage Merging”h]”hŒKernel Samepage Merging”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³Œ4/var/lib/git/docbuild/linux/Documentation/mm/ksm.rst”h´KubhŒ paragraph”“”)”}”(hŒßKSM is a memory-saving de-duplication feature, enabled by CONFIG_KSM=y, added to the Linux kernel in 2.6.32. See ``mm/ksm.c`` for its implementation, and http://lwn.net/Articles/306704/ and https://lwn.net/Articles/330589/”h]”(hŒrKSM is a memory-saving de-duplication feature, enabled by CONFIG_KSM=y, added to the Linux kernel in 2.6.32. See ”…””}”(hhÍh²hh³Nh´NubhŒliteral”“”)”}”(hŒ ``mm/ksm.c``”h]”hŒmm/ksm.c”…””}”(hh×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhhÍubhŒ for its implementation, and ”…””}”(hhÍh²hh³Nh´NubhŒ reference”“”)”}”(hŒhttp://lwn.net/Articles/306704/”h]”hŒhttp://lwn.net/Articles/306704/”…””}”(hhëh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”híuh1héhhÍubhŒ and ”…””}”(hhÍh²hh³Nh´Nubhê)”}”(hŒ https://lwn.net/Articles/330589/”h]”hŒ https://lwn.net/Articles/330589/”…””}”(hhþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”juh1héhhÍubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubhÌ)”}”(hŒSThe userspace interface of KSM is described in Documentation/admin-guide/mm/ksm.rst”h]”hŒSThe userspace interface of KSM is described in Documentation/admin-guide/mm/ksm.rst”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒDesign”h]”hŒDesign”…””}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj!h²hh³hÊh´K ubh¶)”}”(hhh]”(h»)”}”(hŒOverview”h]”hŒOverview”…””}”(hj5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj2h²hh³hÊh´KubhÌ)”}”(hŒfA few notes about the KSM scanning process, to make it easier to understand the data structures below:”h]”hŒfA few notes about the KSM scanning process, to make it easier to understand the data structures below:”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´K>hj2h²hubhÌ)”}”(hŒ–In order to reduce excessive scanning, KSM sorts the memory pages by their contents into a data structure that holds pointers to the pages' locations.”h]”hŒ˜In order to reduce excessive scanning, KSM sorts the memory pages by their contents into a data structure that holds pointers to the pages’ locations.”…””}”(hjRh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KAhj2h²hubhÌ)”}”(hŒßSince the contents of the pages may change at any moment, KSM cannot just insert the pages into a normal sorted tree and expect it to find anything. Therefore KSM uses two data structures - the stable and the unstable tree.”h]”hŒßSince the contents of the pages may change at any moment, KSM cannot just insert the pages into a normal sorted tree and expect it to find anything. Therefore KSM uses two data structures - the stable and the unstable tree.”…””}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KDhj2h²hubhÌ)”}”(hXThe stable tree holds pointers to all the merged pages (ksm pages), sorted by their contents. Because each such page is write-protected, searching on this tree is fully assured to be working (except when pages are unmapped), and therefore this tree is called the stable tree.”h]”hXThe stable tree holds pointers to all the merged pages (ksm pages), sorted by their contents. Because each such page is write-protected, searching on this tree is fully assured to be working (except when pages are unmapped), and therefore this tree is called the stable tree.”…””}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KHhj2h²hubhÌ)”}”(hŒThe stable tree node includes information required for reverse mapping from a KSM page to virtual addresses that map this page.”h]”hŒThe stable tree node includes information required for reverse mapping from a KSM page to virtual addresses that map this page.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KMhj2h²hubhÌ)”}”(hŒvIn order to avoid large latencies of the rmap walks on KSM pages, KSM maintains two types of nodes in the stable tree:”h]”hŒvIn order to avoid large latencies of the rmap walks on KSM pages, KSM maintains two types of nodes in the stable tree:”…””}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KPhj2h²hubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒKthe regular nodes that keep the reverse mapping structures in a linked list”h]”hÌ)”}”(hŒKthe regular nodes that keep the reverse mapping structures in a linked list”h]”hŒKthe regular nodes that keep the reverse mapping structures in a linked list”…””}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KShj¤ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjŸubj£)”}”(hŒ¦the "chains" that link nodes ("dups") that represent the same write protected memory content, but each "dup" corresponds to a different KSM page copy of that content ”h]”hÌ)”}”(hŒ¥the "chains" that link nodes ("dups") that represent the same write protected memory content, but each "dup" corresponds to a different KSM page copy of that content”h]”hŒ±the “chains†that link nodes (“dupsâ€) that represent the same write protected memory content, but each “dup†corresponds to a different KSM page copy of that content”…””}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KUhj½ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hjŸubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1jh³j¶h´KShj2h²hubhÌ)”}”(hŒsInternally, the regular nodes, "dups" and "chains" are represented using the same struct ksm_stable_node structure.”h]”hŒ{Internally, the regular nodes, “dups†and “chains†are represented using the same struct ksm_stable_node structure.”…””}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KYhj2h²hubhÌ)”}”(hX½In addition to the stable tree, KSM uses a second data structure called the unstable tree: this tree holds pointers to pages which have been found to be "unchanged for a period of time". The unstable tree sorts these pages by their contents, but since they are not write-protected, KSM cannot rely upon the unstable tree to work correctly - the unstable tree is liable to be corrupted as its contents are modified, and so it is called unstable.”h]”hXÁIn addition to the stable tree, KSM uses a second data structure called the unstable tree: this tree holds pointers to pages which have been found to be “unchanged for a period of timeâ€. The unstable tree sorts these pages by their contents, but since they are not write-protected, KSM cannot rely upon the unstable tree to work correctly - the unstable tree is liable to be corrupted as its contents are modified, and so it is called unstable.”…””}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´K\hj2h²hubhÌ)”}”(hŒ.KSM solves this problem by several techniques:”h]”hŒ.KSM solves this problem by several techniques:”…””}”(hjüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´Kchj2h²hubhŒenumerated_list”“”)”}”(hhh]”(j£)”}”(hŒ‡The unstable tree is flushed every time KSM completes scanning all memory areas, and then the tree is rebuilt again from the beginning.”h]”hÌ)”}”(hŒ‡The unstable tree is flushed every time KSM completes scanning all memory areas, and then the tree is rebuilt again from the beginning.”h]”hŒ‡The unstable tree is flushed every time KSM completes scanning all memory areas, and then the tree is rebuilt again from the beginning.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´Kehjubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hj ubj£)”}”(hŒ€KSM will only insert into the unstable tree, pages whose hash value has not changed since the previous scan of all memory areas.”h]”hÌ)”}”(hŒ€KSM will only insert into the unstable tree, pages whose hash value has not changed since the previous scan of all memory areas.”h]”hŒ€KSM will only insert into the unstable tree, pages whose hash value has not changed since the previous scan of all memory areas.”…””}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´Kghj)ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hj ubj£)”}”(hXeThe unstable tree is a RedBlack Tree - so its balancing is based on the colors of the nodes and not on their contents, assuring that even when the tree gets "corrupted" it won't get out of balance, so scanning time remains the same (also, searching and inserting nodes in an rbtree uses the same algorithm, so we have no overhead when we flush and rebuild).”h]”hÌ)”}”(hXeThe unstable tree is a RedBlack Tree - so its balancing is based on the colors of the nodes and not on their contents, assuring that even when the tree gets "corrupted" it won't get out of balance, so scanning time remains the same (also, searching and inserting nodes in an rbtree uses the same algorithm, so we have no overhead when we flush and rebuild).”h]”hXkThe unstable tree is a RedBlack Tree - so its balancing is based on the colors of the nodes and not on their contents, assuring that even when the tree gets “corrupted†it won’t get out of balance, so scanning time remains the same (also, searching and inserting nodes in an rbtree uses the same algorithm, so we have no overhead when we flush and rebuild).”…””}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´KihjBubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hj ubj£)”}”(hXKSM never flushes the stable tree, which means that even if it were to take 10 attempts to find a page in the unstable tree, once it is found, it is secured in the stable tree. (When we scan a new page, we first compare it against the stable tree, and then against the unstable tree.) ”h]”hÌ)”}”(hXKSM never flushes the stable tree, which means that even if it were to take 10 attempts to find a page in the unstable tree, once it is found, it is secured in the stable tree. (When we scan a new page, we first compare it against the stable tree, and then against the unstable tree.)”h]”hXKSM never flushes the stable tree, which means that even if it were to take 10 attempts to find a page in the unstable tree, once it is found, it is secured in the stable tree. (When we scan a new page, we first compare it against the stable tree, and then against the unstable tree.)”…””}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´Knhj[ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¢hj ubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ)”uh1j hj2h²hh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´NubhÌ)”}”(hŒ‘If the merge_across_nodes tunable is unset, then KSM maintains multiple stable trees and multiple unstable trees: one of each for each NUMA node.”h]”hŒ‘If the merge_across_nodes tunable is unset, then KSM maintains multiple stable trees and multiple unstable trees: one of each for each NUMA node.”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:17: ./mm/ksm.c”h´Kshj2h²hubeh}”(h]”Œoverview”ah ]”h"]”Œoverview”ah$]”h&]”uh1hµhj!h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒReverse mapping”h]”hŒReverse mapping”…””}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj—h²hh³hÊh´KubhÌ)”}”(hŒKKSM maintains reverse mapping information for KSM pages in the stable tree.”h]”hŒKKSM maintains reverse mapping information for KSM pages in the stable tree.”…””}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj—h²hubhÌ)”}”(hŒñIf a KSM page is shared between less than ``max_page_sharing`` VMAs, the node of the stable tree that represents such KSM page points to a list of struct ksm_rmap_item and the ``page->mapping`` of the KSM page points to the stable tree node.”h]”(hŒ*If a KSM page is shared between less than ”…””}”(hj¶h²hh³Nh´NubhÖ)”}”(hŒ``max_page_sharing``”h]”hŒmax_page_sharing”…””}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj¶ubhŒr VMAs, the node of the stable tree that represents such KSM page points to a list of struct ksm_rmap_item and the ”…””}”(hj¶h²hh³Nh´NubhÖ)”}”(hŒ``page->mapping``”h]”hŒ page->mapping”…””}”(hjÐh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj¶ubhŒ0 of the KSM page points to the stable tree node.”…””}”(hj¶h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj—h²hubhÌ)”}”(hXWhen the sharing passes this threshold, KSM adds a second dimension to the stable tree. The tree node becomes a "chain" that links one or more "dups". Each "dup" keeps reverse mapping information for a KSM page with ``page->mapping`` pointing to that "dup".”h]”(hŒäWhen the sharing passes this threshold, KSM adds a second dimension to the stable tree. The tree node becomes a “chain†that links one or more “dupsâ€. Each “dup†keeps reverse mapping information for a KSM page with ”…””}”(hjèh²hh³Nh´NubhÖ)”}”(hŒ``page->mapping``”h]”hŒ page->mapping”…””}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjèubhŒ pointing to that “dupâ€.”…””}”(hjèh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj—h²hubhÌ)”}”(hŒÖEvery "chain" and all "dups" linked into a "chain" enforce the invariant that they represent the same write protected memory content, even if each "dup" will be pointed by a different KSM page copy of that content.”h]”hŒæEvery “chain†and all “dups†linked into a “chain†enforce the invariant that they represent the same write protected memory content, even if each “dup†will be pointed by a different KSM page copy of that content.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K#hj—h²hubhÌ)”}”(hŒÝThis way the stable tree lookup computational complexity is unaffected if compared to an unlimited list of reverse mappings. It is still enforced that there cannot be KSM page content duplicates in the stable tree itself.”h]”hŒÝThis way the stable tree lookup computational complexity is unaffected if compared to an unlimited list of reverse mappings. It is still enforced that there cannot be KSM page content duplicates in the stable tree itself.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K(hj—h²hubhÌ)”}”(hXÁThe deduplication limit enforced by ``max_page_sharing`` is required to avoid the virtual memory rmap lists to grow too large. The rmap walk has O(N) complexity where N is the number of rmap_items (i.e. virtual mappings) that are sharing the page, which is in turn capped by ``max_page_sharing``. So this effectively spreads the linear O(N) computational complexity from rmap walk context over different KSM pages. The ksmd walk over the stable_node "chains" is also O(N), but N is the number of stable_node "dups", not the number of rmap_items, so it has not a significant impact on ksmd performance. In practice the best stable_node "dup" candidate will be kept and found at the head of the "dups" list.”h]”(hŒ$The deduplication limit enforced by ”…””}”(hj$h²hh³Nh´NubhÖ)”}”(hŒ``max_page_sharing``”h]”hŒmax_page_sharing”…””}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj$ubhŒÛ is required to avoid the virtual memory rmap lists to grow too large. The rmap walk has O(N) complexity where N is the number of rmap_items (i.e. virtual mappings) that are sharing the page, which is in turn capped by ”…””}”(hj$h²hh³Nh´NubhÖ)”}”(hŒ``max_page_sharing``”h]”hŒmax_page_sharing”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj$ubhXª. So this effectively spreads the linear O(N) computational complexity from rmap walk context over different KSM pages. The ksmd walk over the stable_node “chains†is also O(N), but N is the number of stable_node “dupsâ€, not the number of rmap_items, so it has not a significant impact on ksmd performance. In practice the best stable_node “dup†candidate will be kept and found at the head of the “dups†list.”…””}”(hj$h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K-hj—h²hubhÌ)”}”(hXeHigh values of ``max_page_sharing`` result in faster memory merging (because there will be fewer stable_node dups queued into the stable_node chain->hlist to check for pruning) and higher deduplication factor at the expense of slower worst case for rmap walks for any KSM page which can happen during swapping, compaction, NUMA balancing and page migration.”h]”(hŒHigh values of ”…””}”(hjVh²hh³Nh´NubhÖ)”}”(hŒ``max_page_sharing``”h]”hŒmax_page_sharing”…””}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjVubhXB result in faster memory merging (because there will be fewer stable_node dups queued into the stable_node chain->hlist to check for pruning) and higher deduplication factor at the expense of slower worst case for rmap walks for any KSM page which can happen during swapping, compaction, NUMA balancing and page migration.”…””}”(hjVh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K9hj—h²hubhÌ)”}”(hX The ``stable_node_dups/stable_node_chains`` ratio is also affected by the ``max_page_sharing`` tunable, and an high ratio may indicate fragmentation in the stable_node dups, which could be solved by introducing fragmentation algorithms in ksmd which would refile rmap_items from one stable_node dup to another stable_node dup, in order to free up stable_node "dups" with few rmap_items in them, but that may increase the ksmd CPU usage and possibly slowdown the readonly computations on the KSM pages of the applications.”h]”(hŒThe ”…””}”(hjvh²hh³Nh´NubhÖ)”}”(hŒ'``stable_node_dups/stable_node_chains``”h]”hŒ#stable_node_dups/stable_node_chains”…””}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjvubhŒ ratio is also affected by the ”…””}”(hjvh²hh³Nh´NubhÖ)”}”(hŒ``max_page_sharing``”h]”hŒmax_page_sharing”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjvubhX¯ tunable, and an high ratio may indicate fragmentation in the stable_node dups, which could be solved by introducing fragmentation algorithms in ksmd which would refile rmap_items from one stable_node dup to another stable_node dup, in order to free up stable_node “dups†with few rmap_items in them, but that may increase the ksmd CPU usage and possibly slowdown the readonly computations on the KSM pages of the applications.”…””}”(hjvh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K@hj—h²hubhÌ)”}”(hŒåThe whole list of stable_node "dups" linked in the stable_node "chains" is scanned periodically in order to prune stale stable_nodes. The frequency of such scans is defined by ``stable_node_chains_prune_millisecs`` sysfs tunable.”h]”(hŒ¸The whole list of stable_node “dups†linked in the stable_node “chains†is scanned periodically in order to prune stale stable_nodes. The frequency of such scans is defined by ”…””}”(hj¨h²hh³Nh´NubhÖ)”}”(hŒ&``stable_node_chains_prune_millisecs``”h]”hŒ"stable_node_chains_prune_millisecs”…””}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj¨ubhŒ sysfs tunable.”…””}”(hj¨h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KIhj—h²hubeh}”(h]”Œreverse-mapping”ah ]”h"]”Œreverse mapping”ah$]”h&]”uh1hµhj!h²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒ Reference”h]”hŒ Reference”…””}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÐh²hh³hÊh´KOubhŒindex”“”)”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(Œsingle”Œksm_scan (C struct)”Œ c.ksm_scan”hNt”auh1jáhjÐh²hh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´NubhŒdesc”“”)”}”(hhh]”(hŒdesc_signature”“”)”}”(hŒksm_scan”h]”hŒdesc_signature_line”“”)”}”(hŒstruct ksm_scan”h]”(hŒdesc_sig_keyword”“”)”}”(hŒstruct”h]”hŒstruct”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”Œk”ah"]”h$]”h&]”uh1jhjh²hh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´KubhŒdesc_sig_space”“”)”}”(hŒ ”h]”hŒ ”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”Œw”ah"]”h$]”h&]”uh1jhjh²hh³jh´KubhŒ desc_name”“”)”}”(hŒksm_scan”h]”hŒ desc_sig_name”“”)”}”(hjüh]”hŒksm_scan”…””}”(hj/h²hh³Nh´Nubah}”(h]”h ]”Œn”ah"]”h$]”h&]”uh1j-hj)ubah}”(h]”h ]”(Œsig-name”Œdescname”eh"]”h$]”h&]”Œ xml:space”Œpreserve”uh1j'hjh²hh³jh´Kubeh}”(h]”h ]”h"]”h$]”h&]”jEjFŒ add_permalink”ˆuh1jþŒsphinx_line_type”Œ declarator”hjúh²hh³jh´Kubah}”(h]”jðah ]”(Œsig”Œ sig-object”eh"]”h$]”h&]”Œ is_multiline”ˆŒ _toc_parts”)Œ _toc_name”huh1jøh³jh´Khjõh²hubhŒ desc_content”“”)”}”(hhh]”hÌ)”}”(hŒcursor for scanning”h]”hŒcursor for scanning”…””}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´K„hj]h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j[hjõh²hh³jh´Kubeh}”(h]”h ]”(Œc”Œstruct”eh"]”h$]”h&]”Œdomain”jxŒobjtype”jyŒdesctype”jyŒnoindex”‰Œ noindexentry”‰Œnocontentsentry”‰uh1jóh²hhjÐh³jòh´NubhŒ container”“”)”}”(hX½**Definition**:: struct ksm_scan { struct ksm_mm_slot *mm_slot; unsigned long address; struct ksm_rmap_item **rmap_list; unsigned long seqnr; }; **Members** ``mm_slot`` the current mm_slot we are scanning ``address`` the next address inside that to be scanned ``rmap_list`` link to the next rmap to be scanned in the rmap_list ``seqnr`` count of completed full scans (needed when removing unstable node)”h]”(hÌ)”}”(hŒ**Definition**::”h]”(hŒstrong”“”)”}”(hŒ**Definition**”h]”hŒ Definition”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj‰ubhŒ:”…””}”(hj‰h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´Kˆhj…ubhŒ literal_block”“”)”}”(hŒstruct ksm_scan { struct ksm_mm_slot *mm_slot; unsigned long address; struct ksm_rmap_item **rmap_list; unsigned long seqnr; };”h]”hŒstruct ksm_scan { struct ksm_mm_slot *mm_slot; unsigned long address; struct ksm_rmap_item **rmap_list; unsigned long seqnr; };”…””}”hjªsbah}”(h]”h ]”h"]”h$]”h&]”jEjFuh1j¨h³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´KŠhj…ubhÌ)”}”(hŒ **Members**”h]”jŽ)”}”(hj»h]”hŒMembers”…””}”(hj½h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¹ubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´K‘hj…ubhŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_list_item”“”)”}”(hŒ0``mm_slot`` the current mm_slot we are scanning ”h]”(hŒterm”“”)”}”(hŒ ``mm_slot``”h]”hÖ)”}”(hjàh]”hŒmm_slot”…””}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjÞubah}”(h]”h ]”h"]”h$]”h&]”uh1jÜh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´K†hjØubhŒ definition”“”)”}”(hhh]”hÌ)”}”(hŒ#the current mm_slot we are scanning”h]”hŒ#the current mm_slot we are scanning”…””}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³jõh´K†hjøubah}”(h]”h ]”h"]”h$]”h&]”uh1jöhjØubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÖh³jõh´K†hjÓubj×)”}”(hŒ7``address`` the next address inside that to be scanned ”h]”(jÝ)”}”(hŒ ``address``”h]”hÖ)”}”(hjh]”hŒaddress”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÜh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´K‡hjubj÷)”}”(hhh]”hÌ)”}”(hŒ*the next address inside that to be scanned”h]”hŒ*the next address inside that to be scanned”…””}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³j0h´K‡hj1ubah}”(h]”h ]”h"]”h$]”h&]”uh1jöhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÖh³j0h´K‡hjÓubj×)”}”(hŒC``rmap_list`` link to the next rmap to be scanned in the rmap_list ”h]”(jÝ)”}”(hŒ ``rmap_list``”h]”hÖ)”}”(hjTh]”hŒ rmap_list”…””}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjRubah}”(h]”h ]”h"]”h$]”h&]”uh1jÜh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´KˆhjNubj÷)”}”(hhh]”hÌ)”}”(hŒ4link to the next rmap to be scanned in the rmap_list”h]”hŒ4link to the next rmap to be scanned in the rmap_list”…””}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³jih´Kˆhjjubah}”(h]”h ]”h"]”h$]”h&]”uh1jöhjNubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÖh³jih´KˆhjÓubj×)”}”(hŒL``seqnr`` count of completed full scans (needed when removing unstable node)”h]”(jÝ)”}”(hŒ ``seqnr``”h]”hÖ)”}”(hjh]”hŒseqnr”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhj‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÜh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´Kˆhj‡ubj÷)”}”(hhh]”hÌ)”}”(hŒBcount of completed full scans (needed when removing unstable node)”h]”hŒBcount of completed full scans (needed when removing unstable node)”…””}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´K‰hj£ubah}”(h]”h ]”h"]”h$]”h&]”uh1jöhj‡ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÖh³j¢h´KˆhjÓubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÑhj…ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jƒhjÐh²hh³jòh´NubhÌ)”}”(hŒ**Description**”h]”jŽ)”}”(hjÐh]”hŒ Description”…””}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÎubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´KŒhjÐh²hubhÌ)”}”(hŒAThere is only the one ksm_scan instance of this cursor structure.”h]”hŒAThere is only the one ksm_scan instance of this cursor structure.”…””}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³Œ?/var/lib/git/docbuild/linux/Documentation/mm/ksm:80: ./mm/ksm.c”h´K‰hjÐh²hubhÌ)”}”(hŒ(-- Izik Eidus, Hugh Dickins, 17 Nov 2009”h]”hŒ(-- Izik Eidus, Hugh Dickins, 17 Nov 2009”…””}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KShjÐh²hubeh}”(h]”Œ reference”ah ]”h"]”Œ reference”ah$]”h&]”uh1hµhj!h²hh³hÊh´KOubeh}”(h]”Œdesign”ah ]”h"]”Œdesign”ah$]”h&]”uh1hµhh·h²hh³hÊh´K ubeh}”(h]”Œkernel-samepage-merging”ah ]”h"]”Œkernel samepage merging”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”j>Œ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”}”(jjjj j”j‘jÍjÊjjuŒ nametypes”}”(j‰j‰j”‰j͉j‰uh}”(jh·j j!j‘j2jÊj—jjÐ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”]”hŒsystem_message”“”)”}”(hhh]”hÌ)”}”(hŒ`Possible incomplete section title. Treating the overline as ordinary text because it's so short.”h]”hŒbPossible incomplete section title. Treating the overline as ordinary text because it’s so short.”…””}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËhj¢ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œline”KSŒsource”hÊuh1j hjÐh²hh³hÊh´KUubaŒtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.