Commit 8fdb3dbf authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

ksm: add some comments

Added slightly more detail to the Documentation of merge_across_nodes, a
few comments in areas indicated by review, and renamed get_ksm_page()'s
argument from "locked" to "lock_it".  No functional change.
Signed-off-by: default avatarHugh Dickins <hughd@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Petr Holasek <pholasek@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Izik Eidus <izik.eidus@ravellosystems.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 49cd0a5c
...@@ -60,10 +60,18 @@ sleep_millisecs - how many milliseconds ksmd should sleep before next scan ...@@ -60,10 +60,18 @@ sleep_millisecs - how many milliseconds ksmd should sleep before next scan
merge_across_nodes - specifies if pages from different numa nodes can be merged. merge_across_nodes - specifies if pages from different numa nodes can be merged.
When set to 0, ksm merges only pages which physically When set to 0, ksm merges only pages which physically
reside in the memory area of same NUMA node. It brings reside in the memory area of same NUMA node. That brings
lower latency to access to shared page. Value can be lower latency to access of shared pages. Systems with more
changed only when there is no ksm shared pages in system. nodes, at significant NUMA distances, are likely to benefit
Default: 1 from the lower latency of setting 0. Smaller systems, which
need to minimize memory usage, are likely to benefit from
the greater sharing of setting 1 (default). You may wish to
compare how your system performs under each setting, before
deciding on which to use. merge_across_nodes setting can be
changed only when there are no ksm shared pages in system:
set run 2 to unmerge pages first, then to 1 after changing
merge_across_nodes, to remerge according to the new setting.
Default: 1 (merging across nodes as in earlier releases)
run - set 0 to stop ksmd from running but keep merged pages, run - set 0 to stop ksmd from running but keep merged pages,
set 1 to run ksmd e.g. "echo 1 > /sys/kernel/mm/ksm/run", set 1 to run ksmd e.g. "echo 1 > /sys/kernel/mm/ksm/run",
......
...@@ -87,6 +87,9 @@ ...@@ -87,6 +87,9 @@
* take 10 attempts to find a page in the unstable tree, once it is found, * 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 * 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.) * compare it against the stable tree, and then against the unstable tree.)
*
* 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.
*/ */
/** /**
...@@ -526,7 +529,7 @@ static void remove_node_from_stable_tree(struct stable_node *stable_node) ...@@ -526,7 +529,7 @@ static void remove_node_from_stable_tree(struct stable_node *stable_node)
* a page to put something that might look like our key in page->mapping. * a page to put something that might look like our key in page->mapping.
* is on its way to being freed; but it is an anomaly to bear in mind. * is on its way to being freed; but it is an anomaly to bear in mind.
*/ */
static struct page *get_ksm_page(struct stable_node *stable_node, bool locked) static struct page *get_ksm_page(struct stable_node *stable_node, bool lock_it)
{ {
struct page *page; struct page *page;
void *expected_mapping; void *expected_mapping;
...@@ -575,7 +578,7 @@ static struct page *get_ksm_page(struct stable_node *stable_node, bool locked) ...@@ -575,7 +578,7 @@ static struct page *get_ksm_page(struct stable_node *stable_node, bool locked)
goto stale; goto stale;
} }
if (locked) { if (lock_it) {
lock_page(page); lock_page(page);
if (ACCESS_ONCE(page->mapping) != expected_mapping) { if (ACCESS_ONCE(page->mapping) != expected_mapping) {
unlock_page(page); unlock_page(page);
...@@ -705,10 +708,17 @@ static int remove_stable_node(struct stable_node *stable_node) ...@@ -705,10 +708,17 @@ static int remove_stable_node(struct stable_node *stable_node)
return 0; return 0;
} }
if (WARN_ON_ONCE(page_mapped(page))) if (WARN_ON_ONCE(page_mapped(page))) {
/*
* This should not happen: but if it does, just refuse to let
* merge_across_nodes be switched - there is no need to panic.
*/
err = -EBUSY; err = -EBUSY;
else { } else {
/* /*
* The stable node did not yet appear stale to get_ksm_page(),
* since that allows for an unmapped ksm page to be recognized
* right up until it is freed; but the node is safe to remove.
* This page might be in a pagevec waiting to be freed, * This page might be in a pagevec waiting to be freed,
* or it might be PageSwapCache (perhaps under writeback), * or it might be PageSwapCache (perhaps under writeback),
* or it might have been removed from swapcache a moment ago. * or it might have been removed from swapcache a moment ago.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment