From: Zenghui Yu <zenghui.yu@linux.dev>
To: "David Hildenbrand (Arm)" <david@kernel.org>
Cc: linux-mm@kvack.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
xu.xin16@zte.com.cn, chengming.zhou@linux.dev, shr@devkernel.io,
ljs@kernel.org, vbabka@kernel.org, rppt@kernel.org,
surenb@google.com, mhocko@suse.com, shuah@kernel.org
Subject: Re: [PATCH] selftests/mm: disable smart scan for ksm_tests
Date: Mon, 24 Aug 2026 19:55:33 +0800 [thread overview]
Message-ID: <5da6d1ef-28c7-4aed-abd4-a0d74da7998c@linux.dev> (raw)
In-Reply-To: <24cdec9c-28b5-4e44-bb05-fef27ef09846@kernel.org>
Hi David,
On 8/24/26 6:33 PM, David Hildenbrand (Arm) wrote:
> On 8/23/26 20:43, Zenghui Yu wrote:
> > From: "Zenghui Yu (Huawei)" <zenghui.yu@linux.dev>
> >
> > 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
>
> 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.
> ~/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..1
> pages_shared : 1
> pages_sharing : 1
> max_page_sharing : 256
> full_scans : 1283
> pages_unshared : 0
> pages_volatile : 0
> stable_node_chains: 0
> stable_node_dups : 0
> general_profit : 3968
> ksm_rmap_items 2
> ksm_zero_pages 0
> ksm_merging_pages 2
> ksm_process_profit 8064
> ksm_merge_any: no
> ksm_mergeable: yes
> ok 1 KSM NUMA merging
> # Totals: pass:1 fail:0 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
>
> 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.
This is what I had for debugging:
diff --git a/mm/ksm.c b/mm/ksm.c
index 49d48d1e0998..aec2a292cba5 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -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
prev parent reply other threads:[~2026-08-24 11:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-23 18:43 [PATCH] selftests/mm: disable smart scan for ksm_tests Zenghui Yu
2026-08-24 10:33 ` David Hildenbrand (Arm)
2026-08-24 11:55 ` Zenghui Yu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5da6d1ef-28c7-4aed-abd4-a0d74da7998c@linux.dev \
--to=zenghui.yu@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=chengming.zhou@linux.dev \
--cc=david@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=rppt@kernel.org \
--cc=shr@devkernel.io \
--cc=shuah@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=xu.xin16@zte.com.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.