* [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode
2023-09-26 4:09 [PATCH v3 0/4] Smart scanning mode for KSM Stefan Roesch
@ 2023-09-26 4:09 ` Stefan Roesch
2023-09-26 7:41 ` David Hildenbrand
2023-09-26 4:09 ` [PATCH v3 2/4] mm/ksm: add pages_skipped metric Stefan Roesch
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Stefan Roesch @ 2023-09-26 4:09 UTC (permalink / raw)
To: kernel-team; +Cc: shr, akpm, david, hannes, riel, linux-kernel, linux-mm
This change adds a "smart" page scanning mode for KSM. So far all the
candidate pages are continuously scanned to find candidates for
de-duplication. There are a considerably number of pages that cannot be
de-duplicated. This is costly in terms of CPU. By using smart scanning
considerable CPU savings can be achieved.
This change takes the history of scanning pages into account and skips
the page scanning of certain pages for a while if de-deduplication for
this page has not been successful in the past.
To do this it introduces two new fields in the ksm_rmap_item structure:
age and remaining_skips. age, is the KSM age and remaining_skips
determines how often scanning of this page is skipped. The age field is
incremented each time the page is scanned and the page cannot be de-
duplicated. age updated is capped at U8_MAX.
How often a page is skipped is dependent how often de-duplication has
been tried so far and the number of skips is currently limited to 8.
This value has shown to be effective with different workloads.
The feature is currently disable by default and can be enabled with the
new smart_scan knob.
The feature has shown to be very effective: upt to 25% of the page scans
can be eliminated; the pages_to_scan rate can be reduced by 40 - 50% and
a similar de-duplication rate can be maintained.
Signed-off-by: Stefan Roesch <shr@devkernel.io>
---
mm/ksm.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/mm/ksm.c b/mm/ksm.c
index 981af9c72e7a..d65eb48f9a13 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -56,6 +56,8 @@
#define DO_NUMA(x) do { } while (0)
#endif
+typedef u8 rmap_age_t;
+
/**
* DOC: Overview
*
@@ -193,6 +195,8 @@ struct ksm_stable_node {
* @node: rb node of this rmap_item in the unstable tree
* @head: pointer to stable_node heading this list in the stable tree
* @hlist: link into hlist of rmap_items hanging off that stable_node
+ * @age: number of scan iterations since creation
+ * @remaining_skips: how many scans to skip
*/
struct ksm_rmap_item {
struct ksm_rmap_item *rmap_list;
@@ -205,6 +209,8 @@ struct ksm_rmap_item {
struct mm_struct *mm;
unsigned long address; /* + low bits used for flags below */
unsigned int oldchecksum; /* when unstable */
+ rmap_age_t age;
+ rmap_age_t remaining_skips;
union {
struct rb_node node; /* when node of unstable tree */
struct { /* when listed from stable tree */
@@ -281,6 +287,9 @@ static unsigned int zero_checksum __read_mostly;
/* Whether to merge empty (zeroed) pages with actual zero pages */
static bool ksm_use_zero_pages __read_mostly;
+/* Skip pages that couldn't be de-duplicated previously */
+static bool ksm_smart_scan;
+
/* The number of zero pages which is placed by KSM */
unsigned long ksm_zero_pages;
@@ -2305,6 +2314,73 @@ static struct ksm_rmap_item *get_next_rmap_item(struct ksm_mm_slot *mm_slot,
return rmap_item;
}
+/*
+ * Calculate skip age for the ksm page age. The age determines how often
+ * de-duplicating has already been tried unsuccessfully. If the age is
+ * smaller, the scanning of this page is skipped for less scans.
+ *
+ * @age: rmap_item age of page
+ */
+static unsigned int skip_age(rmap_age_t age)
+{
+ if (age <= 3)
+ return 1;
+ if (age <= 5)
+ return 2;
+ if (age <= 8)
+ return 4;
+
+ return 8;
+}
+
+/*
+ * Determines if a page should be skipped for the current scan.
+ *
+ * @page: page to check
+ * @rmap_item: associated rmap_item of page
+ */
+static bool should_skip_rmap_item(struct page *page,
+ struct ksm_rmap_item *rmap_item)
+{
+ rmap_age_t age;
+
+ if (!ksm_smart_scan)
+ return false;
+
+ /*
+ * Never skip pages that are already KSM; pages cmp_and_merge_page()
+ * will essentially ignore them, but we still have to process them
+ * properly.
+ */
+ if (PageKsm(page))
+ return false;
+
+ age = rmap_item->age;
+ if (age != U8_MAX)
+ rmap_item->age++;
+
+ /*
+ * Smaller ages are not skipped, they need to get a chance to go
+ * through the different phases of the KSM merging.
+ */
+ if (age < 3)
+ return false;
+
+ /*
+ * Are we still allowed to skip? If not, then don't skip it
+ * and determine how much more often we are allowed to skip next.
+ */
+ if (!rmap_item->remaining_skips) {
+ rmap_item->remaining_skips = skip_age(age);
+ return false;
+ }
+
+ /* Skip this page */
+ rmap_item->remaining_skips--;
+ remove_rmap_item_from_tree(rmap_item);
+ return true;
+}
+
static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page)
{
struct mm_struct *mm;
@@ -2409,6 +2485,10 @@ static struct ksm_rmap_item *scan_get_next_rmap_item(struct page **page)
if (rmap_item) {
ksm_scan.rmap_list =
&rmap_item->rmap_list;
+
+ if (should_skip_rmap_item(*page, rmap_item))
+ goto next_page;
+
ksm_scan.address += PAGE_SIZE;
} else
put_page(*page);
@@ -3449,6 +3529,28 @@ static ssize_t full_scans_show(struct kobject *kobj,
}
KSM_ATTR_RO(full_scans);
+static ssize_t smart_scan_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%u\n", ksm_smart_scan);
+}
+
+static ssize_t smart_scan_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ bool value;
+
+ err = kstrtobool(buf, &value);
+ if (err)
+ return -EINVAL;
+
+ ksm_smart_scan = value;
+ return count;
+}
+KSM_ATTR(smart_scan);
+
static struct attribute *ksm_attrs[] = {
&sleep_millisecs_attr.attr,
&pages_to_scan_attr.attr,
@@ -3469,6 +3571,7 @@ static struct attribute *ksm_attrs[] = {
&stable_node_chains_prune_millisecs_attr.attr,
&use_zero_pages_attr.attr,
&general_profit_attr.attr,
+ &smart_scan_attr.attr,
NULL,
};
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode
2023-09-26 4:09 ` [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode Stefan Roesch
@ 2023-09-26 7:41 ` David Hildenbrand
2023-09-26 16:13 ` Stefan Roesch
0 siblings, 1 reply; 10+ messages in thread
From: David Hildenbrand @ 2023-09-26 7:41 UTC (permalink / raw)
To: Stefan Roesch, kernel-team; +Cc: akpm, hannes, riel, linux-kernel, linux-mm
On 26.09.23 06:09, Stefan Roesch wrote:
> This change adds a "smart" page scanning mode for KSM. So far all the
> candidate pages are continuously scanned to find candidates for
> de-duplication. There are a considerably number of pages that cannot be
> de-duplicated. This is costly in terms of CPU. By using smart scanning
> considerable CPU savings can be achieved.
>
> This change takes the history of scanning pages into account and skips
> the page scanning of certain pages for a while if de-deduplication for
> this page has not been successful in the past.
>
> To do this it introduces two new fields in the ksm_rmap_item structure:
> age and remaining_skips. age, is the KSM age and remaining_skips
> determines how often scanning of this page is skipped. The age field is
> incremented each time the page is scanned and the page cannot be de-
> duplicated. age updated is capped at U8_MAX.
>
> How often a page is skipped is dependent how often de-duplication has
> been tried so far and the number of skips is currently limited to 8.
> This value has shown to be effective with different workloads.
>
> The feature is currently disable by default and can be enabled with the
> new smart_scan knob.
>
> The feature has shown to be very effective: upt to 25% of the page scans
> can be eliminated; the pages_to_scan rate can be reduced by 40 - 50% and
> a similar de-duplication rate can be maintained.
Thinking about it, what are the cons of just enabling this always and
not exposing new toggles? Alternatively, we could make this a
compile-time option.
In general, LGTM, just curious if we really have to make this configurable.
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode
2023-09-26 7:41 ` David Hildenbrand
@ 2023-09-26 16:13 ` Stefan Roesch
2023-09-26 21:09 ` Andrew Morton
0 siblings, 1 reply; 10+ messages in thread
From: Stefan Roesch @ 2023-09-26 16:13 UTC (permalink / raw)
To: David Hildenbrand; +Cc: kernel-team, akpm, hannes, riel, linux-kernel, linux-mm
David Hildenbrand <david@redhat.com> writes:
> On 26.09.23 06:09, Stefan Roesch wrote:
>> This change adds a "smart" page scanning mode for KSM. So far all the
>> candidate pages are continuously scanned to find candidates for
>> de-duplication. There are a considerably number of pages that cannot be
>> de-duplicated. This is costly in terms of CPU. By using smart scanning
>> considerable CPU savings can be achieved.
>> This change takes the history of scanning pages into account and skips
>> the page scanning of certain pages for a while if de-deduplication for
>> this page has not been successful in the past.
>> To do this it introduces two new fields in the ksm_rmap_item structure:
>> age and remaining_skips. age, is the KSM age and remaining_skips
>> determines how often scanning of this page is skipped. The age field is
>> incremented each time the page is scanned and the page cannot be de-
>> duplicated. age updated is capped at U8_MAX.
>> How often a page is skipped is dependent how often de-duplication has
>> been tried so far and the number of skips is currently limited to 8.
>> This value has shown to be effective with different workloads.
>> The feature is currently disable by default and can be enabled with the
>> new smart_scan knob.
>> The feature has shown to be very effective: upt to 25% of the page scans
>> can be eliminated; the pages_to_scan rate can be reduced by 40 - 50% and
>> a similar de-duplication rate can be maintained.
>
> Thinking about it, what are the cons of just enabling this always and not
> exposing new toggles? Alternatively, we could make this a compile-time option.
>
> In general, LGTM, just curious if we really have to make this configurable.
>
The only downside I can see is that it might take a longer time for some
pages to be de-duplicated (a new candidate page is added, but its
duplicate is skipped in this round). So it will take longer to
de-duplicate this page.
I tested with more than one workload, but it might be useful to get some
data with additional workloads. I was thinking of enabling it after one or
two releases.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode
2023-09-26 16:13 ` Stefan Roesch
@ 2023-09-26 21:09 ` Andrew Morton
2023-09-27 0:39 ` Stefan Roesch
0 siblings, 1 reply; 10+ messages in thread
From: Andrew Morton @ 2023-09-26 21:09 UTC (permalink / raw)
To: Stefan Roesch
Cc: David Hildenbrand, kernel-team, hannes, riel, linux-kernel, linux-mm
On Tue, 26 Sep 2023 09:13:31 -0700 Stefan Roesch <shr@devkernel.io> wrote:
> > Thinking about it, what are the cons of just enabling this always and not
> > exposing new toggles? Alternatively, we could make this a compile-time option.
> >
> > In general, LGTM, just curious if we really have to make this configurable.
> >
>
> The only downside I can see is that it might take a longer time for some
> pages to be de-duplicated (a new candidate page is added, but its
> duplicate is skipped in this round). So it will take longer to
> de-duplicate this page.
>
> I tested with more than one workload, but it might be useful to get some
> data with additional workloads. I was thinking of enabling it after one or
> two releases.
We could keep the tunable and make it default "on"?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode
2023-09-26 21:09 ` Andrew Morton
@ 2023-09-27 0:39 ` Stefan Roesch
2023-09-27 9:57 ` David Hildenbrand
0 siblings, 1 reply; 10+ messages in thread
From: Stefan Roesch @ 2023-09-27 0:39 UTC (permalink / raw)
To: Andrew Morton
Cc: David Hildenbrand, kernel-team, hannes, riel, linux-kernel, linux-mm
Andrew Morton <akpm@linux-foundation.org> writes:
> On Tue, 26 Sep 2023 09:13:31 -0700 Stefan Roesch <shr@devkernel.io> wrote:
>
>> > Thinking about it, what are the cons of just enabling this always and not
>> > exposing new toggles? Alternatively, we could make this a compile-time option.
>> >
>> > In general, LGTM, just curious if we really have to make this configurable.
>> >
>>
>> The only downside I can see is that it might take a longer time for some
>> pages to be de-duplicated (a new candidate page is added, but its
>> duplicate is skipped in this round). So it will take longer to
>> de-duplicate this page.
>>
>> I tested with more than one workload, but it might be useful to get some
>> data with additional workloads. I was thinking of enabling it after one or
>> two releases.
>
> We could keep the tunable and make it default "on"?
Sounds good to me
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode
2023-09-27 0:39 ` Stefan Roesch
@ 2023-09-27 9:57 ` David Hildenbrand
0 siblings, 0 replies; 10+ messages in thread
From: David Hildenbrand @ 2023-09-27 9:57 UTC (permalink / raw)
To: Stefan Roesch, Andrew Morton
Cc: kernel-team, hannes, riel, linux-kernel, linux-mm
On 27.09.23 02:39, Stefan Roesch wrote:
>
> Andrew Morton <akpm@linux-foundation.org> writes:
>
>> On Tue, 26 Sep 2023 09:13:31 -0700 Stefan Roesch <shr@devkernel.io> wrote:
>>
>>>> Thinking about it, what are the cons of just enabling this always and not
>>>> exposing new toggles? Alternatively, we could make this a compile-time option.
>>>>
>>>> In general, LGTM, just curious if we really have to make this configurable.
>>>>
>>>
>>> The only downside I can see is that it might take a longer time for some
>>> pages to be de-duplicated (a new candidate page is added, but its
>>> duplicate is skipped in this round). So it will take longer to
>>> de-duplicate this page.
>>>
>>> I tested with more than one workload, but it might be useful to get some
>>> data with additional workloads. I was thinking of enabling it after one or
>>> two releases.
>>
>> We could keep the tunable and make it default "on"?
>
> Sounds good to me
>
+1
Reviewed-by: David Hildenbrand <david@redhat.com>
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 2/4] mm/ksm: add pages_skipped metric
2023-09-26 4:09 [PATCH v3 0/4] Smart scanning mode for KSM Stefan Roesch
2023-09-26 4:09 ` [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode Stefan Roesch
@ 2023-09-26 4:09 ` Stefan Roesch
2023-09-26 4:09 ` [PATCH v3 3/4] mm/ksm: document smart scan mode Stefan Roesch
2023-09-26 4:09 ` [PATCH v3 4/4] mm/ksm: document pages_skipped sysfs knob Stefan Roesch
3 siblings, 0 replies; 10+ messages in thread
From: Stefan Roesch @ 2023-09-26 4:09 UTC (permalink / raw)
To: kernel-team; +Cc: shr, akpm, david, hannes, riel, linux-kernel, linux-mm
This change adds the "pages skipped" metric. To be able to evaluate how
successful smart page scanning is, the pages skipped metric can be
compared to the pages scanned metric.
The pages skipped metric is a cumulative counter. The counter is stored
under /sys/kernel/mm/ksm/pages_skipped.
Signed-off-by: Stefan Roesch <shr@devkernel.io>
Reviewed-by: David Hildenbrand <david@redhat.com>
---
mm/ksm.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/mm/ksm.c b/mm/ksm.c
index d65eb48f9a13..3de130d170b7 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -293,6 +293,9 @@ static bool ksm_smart_scan;
/* The number of zero pages which is placed by KSM */
unsigned long ksm_zero_pages;
+/* The number of pages that have been skipped due to "smart scanning" */
+static unsigned long ksm_pages_skipped;
+
#ifdef CONFIG_NUMA
/* Zeroed when merging across nodes is not allowed */
static unsigned int ksm_merge_across_nodes = 1;
@@ -2376,6 +2379,7 @@ static bool should_skip_rmap_item(struct page *page,
}
/* Skip this page */
+ ksm_pages_skipped++;
rmap_item->remaining_skips--;
remove_rmap_item_from_tree(rmap_item);
return true;
@@ -3463,6 +3467,13 @@ static ssize_t pages_volatile_show(struct kobject *kobj,
}
KSM_ATTR_RO(pages_volatile);
+static ssize_t pages_skipped_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%lu\n", ksm_pages_skipped);
+}
+KSM_ATTR_RO(pages_skipped);
+
static ssize_t ksm_zero_pages_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -3560,6 +3571,7 @@ static struct attribute *ksm_attrs[] = {
&pages_sharing_attr.attr,
&pages_unshared_attr.attr,
&pages_volatile_attr.attr,
+ &pages_skipped_attr.attr,
&ksm_zero_pages_attr.attr,
&full_scans_attr.attr,
#ifdef CONFIG_NUMA
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v3 3/4] mm/ksm: document smart scan mode
2023-09-26 4:09 [PATCH v3 0/4] Smart scanning mode for KSM Stefan Roesch
2023-09-26 4:09 ` [PATCH v3 1/4] mm/ksm: add "smart" page scanning mode Stefan Roesch
2023-09-26 4:09 ` [PATCH v3 2/4] mm/ksm: add pages_skipped metric Stefan Roesch
@ 2023-09-26 4:09 ` Stefan Roesch
2023-09-26 4:09 ` [PATCH v3 4/4] mm/ksm: document pages_skipped sysfs knob Stefan Roesch
3 siblings, 0 replies; 10+ messages in thread
From: Stefan Roesch @ 2023-09-26 4:09 UTC (permalink / raw)
To: kernel-team; +Cc: shr, akpm, david, hannes, riel, linux-kernel, linux-mm
This adds documentation for the smart scan mode of KSM.
Signed-off-by: Stefan Roesch <shr@devkernel.io>
Reviewed-by: David Hildenbrand <david@redhat.com>
---
Documentation/admin-guide/mm/ksm.rst | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Documentation/admin-guide/mm/ksm.rst b/Documentation/admin-guide/mm/ksm.rst
index 776f244bdae4..1762219baf51 100644
--- a/Documentation/admin-guide/mm/ksm.rst
+++ b/Documentation/admin-guide/mm/ksm.rst
@@ -155,6 +155,15 @@ stable_node_chains_prune_millisecs
scan. It's a noop if not a single KSM page hit the
``max_page_sharing`` yet.
+smart_scan
+ By default KSM checks every candidate page for each scan. It does
+ not take into account historic information. When smart scan is
+ enabled, pages that have previously not been de-duplicated get
+ skipped. How often these pages are skipped depends on how often
+ de-duplication has already been tried and failed. By default this
+ optimization is disabled. The ``pages_skipped`` metric shows how
+ effetive the setting is.
+
The effectiveness of KSM and MADV_MERGEABLE is shown in ``/sys/kernel/mm/ksm/``:
general_profit
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v3 4/4] mm/ksm: document pages_skipped sysfs knob
2023-09-26 4:09 [PATCH v3 0/4] Smart scanning mode for KSM Stefan Roesch
` (2 preceding siblings ...)
2023-09-26 4:09 ` [PATCH v3 3/4] mm/ksm: document smart scan mode Stefan Roesch
@ 2023-09-26 4:09 ` Stefan Roesch
3 siblings, 0 replies; 10+ messages in thread
From: Stefan Roesch @ 2023-09-26 4:09 UTC (permalink / raw)
To: kernel-team; +Cc: shr, akpm, david, hannes, riel, linux-kernel, linux-mm
This adds documentation for the new metric pages_skipped.
Signed-off-by: Stefan Roesch <shr@devkernel.io>
Reviewed-by: David Hildenbrand <david@redhat.com>
---
Documentation/admin-guide/mm/ksm.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/admin-guide/mm/ksm.rst b/Documentation/admin-guide/mm/ksm.rst
index 1762219baf51..27d949250b67 100644
--- a/Documentation/admin-guide/mm/ksm.rst
+++ b/Documentation/admin-guide/mm/ksm.rst
@@ -178,6 +178,8 @@ pages_unshared
how many pages unique but repeatedly checked for merging
pages_volatile
how many pages changing too fast to be placed in a tree
+pages_skipped
+ how many pages did the "smart" page scanning algorithm skip
full_scans
how many times all mergeable areas have been scanned
stable_node_chains
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread