selftests/mm: disable smart scan for ksm_tests
PATCH 1/1 selftests/mm: disable smart scan for ksm_tests
From: "Zenghui Yu (Huawei)" <[email protected]>
The "KSM NUMA merging" test allocates two identical pages on two NUMA nodes and verifies KSM will merge these two pages after 2 scans (see ksm_merge_pages()). But when smart scan is enabled, pages that have previously not been de-duplicated may get skipped for some scans. Verifying KSM behavior after only 2 scans may not be enough.
$ ./ksm_tests -N -d TAP version 13 1..1 pages_shared : 0 pages_sharing : 0 max_page_sharing : 256 full_scans : 211 pages_unshared : 1 pages_volatile : 2 stable_node_chains: 0 stable_node_dups : 0 general_profit : -128 ksm_rmap_items 2 ksm_zero_pages 0 ksm_merging_pages 0 ksm_process_profit -128 ksm_merge_any: no ksm_mergeable: yes not ok 1 KSM NUMA merging # Totals: pass:0 fail:1 xfail:0 xpass:0 skip:0 error:0
This specific test fails because KSM started scanning the second page whilst the first page had already been scanned for 16 times (ksm_rmap_item::age of page 0 is 16 greater than page 1). It's not difficult to infer that should_skip_rmap_item() cannot be false at the same time for these two pages - they cannot be merged even after 211 full scans.
Given the current implementation of smart scan, it may not be appropriate to enable it for selftests. Let's disable it for now.
--- tools/testing/selftests/mm/ksm_tests.c | 4 ++++ 1 file changed, 4 insertions(+)
tools/testing/selftests/mm/ksm_tests.c +4 -0
@@ -33,6 +33,7 @@ struct ksm_sysfs {unsigned long pages_to_scan;unsigned long run;unsigned long sleep_millisecs; +unsigned long smart_scan;unsigned long stable_node_chains_prune_millisecs;unsigned long use_zero_pages; };
@@ -293,6 +294,7 @@ static int ksm_save_def(struct ksm_sysfs *ksm_sysfs)ksm_read_sysfs (KSM_FP ("sleep_millisecs" ), &ksm_sysfs->sleep_millisecs) ||ksm_read_sysfs (KSM_FP ("pages_to_scan" ), &ksm_sysfs->pages_to_scan) ||ksm_read_sysfs (KSM_FP ("run" ), &ksm_sysfs->run) || +ksm_read_sysfs (KSM_FP ("smart_scan" ), &ksm_sysfs->smart_scan) ||ksm_read_sysfs (KSM_FP ("stable_node_chains_prune_millisecs" ), &ksm_sysfs->stable_node_chains_prune_millisecs) || ksm_read_sysfs(KSM_FP("use_zero_pages"), &ksm_sysfs->use_zero_pages))
@@ -309,6 +311,7 @@ static int ksm_restore(struct ksm_sysfs *ksm_sysfs)ksm_write_sysfs (KSM_FP ("pages_to_scan" ), ksm_sysfs->pages_to_scan) ||ksm_write_sysfs (KSM_FP ("run" ), ksm_sysfs->run) ||ksm_write_sysfs (KSM_FP ("sleep_millisecs" ), ksm_sysfs->sleep_millisecs) || +ksm_write_sysfs (KSM_FP ("smart_scan" ), ksm_sysfs->smart_scan) ||ksm_write_sysfs (KSM_FP ("stable_node_chains_prune_millisecs" ), ksm_sysfs->stable_node_chains_prune_millisecs) || ksm_write_sysfs(KSM_FP("use_zero_pages"), ksm_sysfs->use_zero_pages))
@@ -846,6 +849,7 @@ int main(int argc, char *argv[])if (ksm_write_sysfs (KSM_FP ("run" ),2 ) ||ksm_write_sysfs (KSM_FP ("sleep_millisecs" ),0 ) || +ksm_write_sysfs (KSM_FP ("smart_scan" ),0 ) || (numa_available () ?0 :ksm_write_sysfs (KSM_FP ("merge_across_nodes" ),1 )) ||ksm_write_sysfs (KSM_FP ("pages_to_scan" ), page_count))
Signature · 1 line
2.53.0
David Hildenbrand (Arm)
maintainerQuoted 20 lines · Zenghui Yu
From: "Zenghui Yu (Huawei)" <[email protected]>
The "KSM NUMA merging" test allocates two identical pages on two NUMA nodes and verifies KSM will merge these two pages after 2 scans (see
ksm_merge_pages()). But when smart scan is enabled, pages that have previously not been de-duplicated may get skipped for some scans. Verifying KSM behavior after only 2 scans may not be enough.$ ./ksm_tests -N -d TAP version 13 1..1 pages_shared : 0 pages_sharing : 0 max_page_sharing : 256 full_scans : 211 pages_unshared : 1 pages_volatile : 2 stable_node_chains: 0 stable_node_dups : 0 general_profit : -128
Quoted 8 lines
ksm_rmap_items 2 ksm_zero_pages 0 ksm_merging_pages 0 ksm_process_profit -128 ksm_merge_any: no ksm_mergeable: yes not ok 1 KSM NUMA merging # Totals: pass:0 fail:1 xfail:0 xpass:0 skip:0 error:0
How did you reproduce this? Is this an actual test result?
~/linux/tools/testing/selftests/mm$ cat /sys/kernel/mm/ksm/smart_scan 1
~/linux/tools/testing/selftests/mm$ sudo ./ksm_tests -N -d TAP version 13
1..1pages_shared : 1pages_sharing : 1max_page_sharing : 256full_scans : 1283pages_unshared : 0pages_volatile : 0stable_node_chains: 0stable_node_dups : 0general_profit : 3968ksm_rmap_items 2ksm_zero_pages 0ksm_merging_pages 2ksm_process_profit 8064ksm_merge_any: noksm_mergeable: yes
ok 1 KSM NUMA merging
# Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0
Quoted 3 lines
This specific test fails because KSM started scanning the second page whilst the first page had already been scanned for 16 times
How is that supposed to happen? The sequence we have is:
numa1_map_ptr = numa_alloc_onnode(page_size, first_node); numa2_map_ptr = numa_alloc_onnode(page_size, second_node);
...memset(numa1_map_ptr, '*', page_size);memset(numa2_map_ptr, '*', page_size);
...
if (ksm_merge_pages(merge_type, numa1_map_ptr, page_size, start_time, timeout) ...
KSM smart scan operates on rmap entries. rmap entries are per MM.
Signature · 3 lines
Cheers, David
Hi David,
Quoted 30 lines · David Hildenbrand (Arm)
Quoted 20 lines · Zenghui Yu
From: "Zenghui Yu (Huawei)" <[email protected]>
The "KSM NUMA merging" test allocates two identical pages on two NUMA nodes and verifies KSM will merge these two pages after 2 scans (see
ksm_merge_pages()). But when smart scan is enabled, pages that have previously not been de-duplicated may get skipped for some scans. Verifying KSM behavior after only 2 scans may not be enough.$ ./ksm_tests -N -d TAP version 13 1..1 pages_shared : 0 pages_sharing : 0 max_page_sharing : 256 full_scans : 211 pages_unshared : 1 pages_volatile : 2 stable_node_chains: 0 stable_node_dups : 0 general_profit : -128Quoted 8 lines
ksm_rmap_items 2 ksm_zero_pages 0 ksm_merging_pages 0 ksm_process_profit -128 ksm_merge_any: no ksm_mergeable: yes not ok 1 KSM NUMA merging # Totals: pass:0 fail:1 xfail:0 xpass:0 skip:0 error:0
Quoted 1 line
How did you reproduce this? Is this an actual test result?
I reproduced this in a guest, using arm64's virtconfig. I don't think there is any particular configuration. This is an actual test result but this is not 100% reproducible.
Quoted 38 lines
~/linux/tools/testing/selftests/mm$ cat
/sys/kernel/mm/ksm/smart_scan1
~/linux/tools/testing/selftests/mm$ sudo ./ksm_tests -N -d TAP version 13
1..1pages_shared: 1pages_sharing: 1max_page_sharing: 256full_scans: 1283pages_unshared: 0pages_volatile: 0stable_node_chains: 0stable_node_dups: 0general_profit: 3968ksm_rmap_items2ksm_zero_pages0ksm_merging_pages2ksm_process_profit8064ksm_merge_any: noksm_mergeable: yes
ok 1 KSM NUMA merging
# Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0Quoted 3 lines
This specific test fails because KSM started scanning the second page whilst the first page had already been scanned for 16 times
How is that supposed to happen? The sequence we have is:
numa1_map_ptr=numa_alloc_onnode(page_size, first_node);numa2_map_ptr=numa_alloc_onnode(page_size, second_node);
...memset(numa1_map_ptr, '*', page_size);memset(numa2_map_ptr, '*', page_size);
...
if (ksm_merge_pages(merge_type, numa1_map_ptr, page_size, start_time, timeout)...
Quoted 1 line
KSM smart scan operates on rmap entries. rmap entries are per MM.
This is what I had for debugging:
mm/ksm.c +5 -1
@@ -2495,6 +2495,8 @@ static bool should_skip_rmap_item(struct folio *folio,if (age !=U8_MAX ) rmap_item->age++; +pr_info ("addr=%lx age=%u r_skips=%u\n" , rmap_item->address, age, rmap_item->remaining_skips); +/* * Smaller ages are not skipped, they need to get a chance to go * through the different phases of the KSM merging.
@@ -2820,8 +2822,10 @@ static void ksm_do_scan(unsigned int scan_npages)while (scan_npages-- &&likely (!freezing (current))) {cond_resched (); rmap_item =scan_get_next_rmap_item (&page); -if (!rmap_item) +if (!rmap_item) { +pr_info ("\n" );return ; + }cmp_and_merge_page (page, rmap_item);put_page (page); ksm_pages_scanned++;
$ dmesg [ 309.111144] addr=7fff959d4000 age=0 r_skips=0
[ 309.111215] addr=7fff959d4000 age=1 r_skips=0
[ 309.111223] addr=7fff959d4101 age=2 r_skips=0
[ 309.111230] addr=7fff959d4102 age=3 r_skips=0
[ 309.111237] addr=7fff959d4103 age=4 r_skips=1
[ 309.111241] addr=7fff959d4000 age=5 r_skips=0
[ 309.111248] addr=7fff959d4105 age=6 r_skips=2
[ 309.111251] addr=7fff959d4000 age=7 r_skips=1
[ 309.111255] addr=7fff959d4000 age=8 r_skips=0
[ 309.111262] addr=7fff959d4108 age=9 r_skips=4
[ 309.111265] addr=7fff959d4000 age=10 r_skips=3
[ 309.111269] addr=7fff959d4000 age=11 r_skips=2
[ 309.111272] addr=7fff959d4000 age=12 r_skips=1
[ 309.111297] addr=7fff959ac000 age=0 r_skips=0 [ 309.111303] addr=7fff959d4000 age=13 r_skips=0 -> page 0's age is 13 greater that page 1's
[ 309.111311] addr=7fff959ac000 age=1 r_skips=0 [ 309.111316] addr=7fff959d410d age=14 r_skips=8
[ 309.111320] addr=7fff959ac10e age=2 r_skips=0 [ 309.111325] addr=7fff959d4000 age=15 r_skips=7
[ 309.111329] addr=7fff959ac10f age=3 r_skips=0 [ 309.111334] addr=7fff959d4000 age=16 r_skips=6
[ 309.111338] addr=7fff959ac110 age=4 r_skips=1 [ 309.111339] addr=7fff959d4000 age=17 r_skips=5
[ 309.111343] addr=7fff959ac000 age=5 r_skips=0 [ 309.111348] addr=7fff959d4000 age=18 r_skips=4
[ 309.111352] addr=7fff959ac112 age=6 r_skips=2 [ 309.111353] addr=7fff959d4000 age=19 r_skips=3
[ 309.111357] addr=7fff959ac000 age=7 r_skips=1 [ 309.111358] addr=7fff959d4000 age=20 r_skips=2
[ 309.111362] addr=7fff959ac000 age=8 r_skips=0 [ 309.111367] addr=7fff959d4000 age=21 r_skips=1
[ 309.111372] addr=7fff959ac115 age=9 r_skips=4 [ 309.111373] addr=7fff959d4000 age=22 r_skips=0 -> remaining_skips can not be 0 at the same time for both pages
Not sure if I had misunderstood something.
Thanks,
Zenghui