mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zenghui Yu <zenghui.yu@linux.dev>
To: kvm@vger.kernel.org, kvmarm@lists.linux.dev,
	linux-kernel@vger.kernel.org
Cc: pbonzini@redhat.com, seanjc@google.com,
	"Zenghui Yu (Huawei)" <zenghui.yu@linux.dev>
Subject: [PATCH 1/3] KVM: selftests: Fix access_tracking_perf_test for larger host page size
Date: Thu, 17 Sep 2026 19:45:41 +0800	[thread overview]
Message-ID: <20260917114543.85044-2-zenghui.yu@linux.dev> (raw)
In-Reply-To: <20260917114543.85044-1-zenghui.yu@linux.dev>

From: "Zenghui Yu (Huawei)" <zenghui.yu@linux.dev>

access_tracking_perf_test marks guest memory idle through page_idle by
walking its test region one guest page at a time and checking/marking the
host PFN backing each guest page.  The walk assumes that every guest page
maps to a distinct host page, which only holds when the guest page size is
>= the host page size.

On an arm64 host with 64K pages, the test also runs guest modes that use 4K
pages, where 16 consecutive guest pages are backed by one host page.  The
first of them marks the shared host page idle and the other 15 then see the
page as already idle and count it as "still idle", inflating still_idle to
~94% and failing the test:

  $ ./access_tracking_perf_test
  Random seed: 0x1c04f013
  lru_gen: Could not open /sys/kernel/mm/lru_gen/enabled
  Using page_idle for aging
  Testing guest mode: PA-bits:48,  VA-bits:48,  4K pages
  __vm_create: mode='PA-bits:48,  VA-bits:48,  4K pages' type='0', pages='1696'
  guest physical test memory: [0xffffbfff0000, 0xffffffff0000)

  Populating memory             : 0.299047690s
  Writing to populated memory   : 0.008723980s
  Reading from populated memory : 0.010692350s

  ==== Test Assertion Failure ====
    access_tracking_perf_test.c:164: idle_pages_warn_only
    pid=3503998 tid=3504006 errno=4 - Interrupted system call
       1	0x000000000040308f: too_many_idle_pages at access_tracking_perf_test.c:164
       2	 (inlined by) pageidle_mark_vcpu_memory_idle at access_tracking_perf_test.c:229
       3	 (inlined by) vcpu_thread_main at access_tracking_perf_test.c:339
       4	0x000000000040a267: vcpu_thread_main at memstress.c:277
       5	0x00007fff958ef09b: ?? ??:0
       6	0x00007fff959548db: ?? ??:0
    vCPU0: Too many pages still idle (245647 out of 262144)

Idle tracking is fundamentally per host page though.  Walk the region in
units of the larger of the guest and host page size instead.  This changes
nothing when the guest page size is >= the host's - if the guest page is
bigger, the guest only ever faults the first host page of each guest page
anyway.

Assisted-by: GLM-5.3 OpenCode
Signed-off-by: Zenghui Yu (Huawei) <zenghui.yu@linux.dev>
---
 .../selftests/kvm/access_tracking_perf_test.c    | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/access_tracking_perf_test.c b/tools/testing/selftests/kvm/access_tracking_perf_test.c
index 4415c94b2866..bcdfeb9c22d8 100644
--- a/tools/testing/selftests/kvm/access_tracking_perf_test.c
+++ b/tools/testing/selftests/kvm/access_tracking_perf_test.c
@@ -175,8 +175,8 @@ static void pageidle_mark_vcpu_memory_idle(struct kvm_vm *vm,
 {
 	int vcpu_idx = vcpu_args->vcpu_idx;
 	gva_t base_gva = vcpu_args->gva;
-	u64 pages = vcpu_args->pages;
-	u64 page;
+	u64 idle_page_size;
+	u64 pages, page;
 	u64 still_idle = 0;
 	u64 no_pfn = 0;
 	int page_idle_fd;
@@ -192,8 +192,18 @@ static void pageidle_mark_vcpu_memory_idle(struct kvm_vm *vm,
 	pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
 	TEST_ASSERT(pagemap_fd > 0, "Failed to open pagemap.");
 
+	/*
+	 * Idle tracking operates on host pages, so walk the region in units of
+	 * the larger of the guest and host page size.  If the host page is the
+	 * bigger one, several guest pages are backed by one host page and
+	 * checking/marking the same PFN once per guest page would make the
+	 * sanity check below count the shared page as still idle.
+	 */
+	idle_page_size = max_t(u64, memstress_args.guest_page_size, getpagesize());
+	pages = vcpu_args->pages * memstress_args.guest_page_size / idle_page_size;
+
 	for (page = 0; page < pages; page++) {
-		gva_t gva = base_gva + page * memstress_args.guest_page_size;
+		gva_t gva = base_gva + page * idle_page_size;
 		u64 pfn = lookup_pfn(pagemap_fd, vm, gva);
 
 		if (!pfn) {
-- 
2.53.0


  reply	other threads:[~2026-09-17 11:46 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-17 11:45 [PATCH 0/3] KVM: selftests: access_tracking_perf_test fixes and cleanups Zenghui Yu
2026-09-17 11:45 ` Zenghui Yu [this message]
2026-09-17 11:45 ` [PATCH 2/3] KVM: selftests: Add missing newline to access_tracking_perf_test help Zenghui Yu
2026-09-17 11:45 ` [PATCH 3/3] KVM: selftests: Remove destroy_cgroup() from access_tracking_perf_test Zenghui Yu

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=20260917114543.85044-2-zenghui.yu@linux.dev \
    --to=zenghui.yu@linux.dev \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®