From nobody Tue Feb 10 23:53:35 2026 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ADFE62E9729 for ; Tue, 10 Feb 2026 04:35:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770698126; cv=none; b=C1elILM/v4Hr7Xof3N7ulDMBdQdI+nbHRciuNvWi60Dui6iwQbUCrY9QCyC5dbYxqMvxokcOJHX55JD1Tj8I+BbMeDqM230SXn6O+KQr8WoQ75WsDYBhsam14g/8NEt/AbfLsJScQN6ZEss3aVvsXSeVfOAqMvtKPu9FSuIN+4k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770698126; c=relaxed/simple; bh=QMETk0boA0UypXC7lJ4u4qjAF32umMsEhojmWnRORpM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=F5tQMpQDdNFyxLvBoQCQr25E9uG746TqgQioo9I9NEc8Bid04q4Nt0GcJBtALmC6c78T9eAFvL9Rn0X6fvOOc0t7IjP7GRGqZk97+wHyD/mKUib8xiibYiZMdCxrBM7HCOI1uHQdGXPwVmWLwOPl5P8YW6WXAErqHiJ6ITIwS1I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l9aacduD; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l9aacduD" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-2aaf59c4f7cso1861805ad.1 for ; Mon, 09 Feb 2026 20:35:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770698125; x=1771302925; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=zk5udZmeLlvColjrGc71yG3tENWgemEd1spLI7Qf+eQ=; b=l9aacduD+p7yVvJFlDzp3k2WVThIilk68DebQg/VFvPGToK+ofC8tH37iwIZPovZUY JzqdWwSV/zNT/35TuURmEbSTqWv+68fHecb8i8LpMLIMXnw5cjW5p7DG/9KLZFPTKBmu LNhcCQI0FUi4Dvk/BRGRjWZsrN8Iqs1j1NYxeaovNCmkqCHK3H1pT+rfCDEeBMyQGUfn as5iUC+3H8WdH8Axt/o6zT563BQUBToxmphYh+tb/ykuvGo+Y6hjn/OtSAa0Vu83Rzge 4Rq1IrQ/0OqhH0sYq3QNQVPQbjAab7JTZZhVjuN7xiOeqgQLwqz5oYxBQpciuoEKR5xq JQjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770698125; x=1771302925; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=zk5udZmeLlvColjrGc71yG3tENWgemEd1spLI7Qf+eQ=; b=tqy1/LyGLR06dK1ZpM9GbSjrzOM1xge1WeLXfQP+Yt9DtkRg0JHjbCx3qSEinND642 AUYsZEM7gUoaFrZzJx7/1lhHJD5JkOdvPWbCD6HpYZU+vO6E8Np+sPC3uanm6hyp/FXc KOhOjwZGdlzAS+dqvtg5RJ99ZC4mfQlw7EKxsRDnOwYWeUhi9FRox7Q7+/k1CwJWRoPQ lwDg/OKPDZxObHCgN1niKOYkq6oTca+vFJ8WBgs/tyedG2gRrBFtn2IVRKGJyVUgPeBv Zlix3595Ux94PQpmSezKO9aK3s6GzojT5u4Nxf4VL3HGVmQGjBqr7swDY8qAuvd1fgn6 tSGQ== X-Forwarded-Encrypted: i=1; AJvYcCUkEO28FhiAtT2nfEkveFJVt8pvhYNWCO+mhMsHD5nH8HAmvUy6QaDW2w6uYvfSUT8KH6cezpPwHX2yvYE=@vger.kernel.org X-Gm-Message-State: AOJu0YzjhyqnIWxEKhRCuXFEvB2tXFVWKvXMnXPAjntZ1IdbZFh1NCGc agiPE6R2+MeVqXQ02uZI1zNxUfOajG3f/aorLzlGnmjrlM0Vp6J8Bksj X-Gm-Gg: AZuq6aI7N/dTP+NrLdyUC3hW8MDhCsDXLfP/CKpXjppVwG3leuNUHdKIsoTSvePpHLv qaiVu6KIMp4XochTyPErefE4cUYDENG/oI/cidRQA8NbMN9Ci3JcJQFgClqfWeS2JyypVnh00JP UsWTGe+l/lgvmYNbuwcjVv4ax7brfckJBYdzrezwEy3u+6zRdaovaDCAvAepma7nKl5oJY2kbiZ uKCAl00TsA9Jqy+a/jpHH0lguTmsOzrjRbeN5wvCA7TUFvhNxzsRxZvW+/RpWl7GXzm1yYXkoAl mI8iF7aYS9BnDz6AL2D0s4kItMBLOL3r99s22L+uny7KjKKU4K1D0io1D8+qMssXGtZMES2Hn+O 2XpoH9RQSmFqXntTOOIvMW3J79Vy2Lyn4XlIq8mT/natUtfdiel4jgvKq4mqvprMuXk67ecxZX4 whwfwIQZVtKnFX8MUoK8Pk X-Received: by 2002:a17:903:32c2:b0:2a8:fc90:c8b7 with SMTP id d9443c01a7336-2a9516299a0mr127392405ad.19.1770698124897; Mon, 09 Feb 2026 20:35:24 -0800 (PST) Received: from localhost ([240e:3a5:3184:2a50:fc86:2a4b:6ee6:4]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82457ef1000sm8441957b3a.34.2026.02.09.20.35.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Feb 2026 20:35:24 -0800 (PST) From: Wenchao Hao To: Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R . Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: Wenchao Hao Subject: [RFC PATCH] mm: only set fault addrsss' access bit in do_anonymous_page Date: Tue, 10 Feb 2026 12:34:56 +0800 Message-ID: <20260210043456.2137482-1-haowenchao22@gmail.com> X-Mailer: git-send-email 2.45.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When do_anonymous_page() creates mappings for huge pages, it currently sets the access bit for all mapped PTEs (Page Table Entries) by default. This causes an issue where the Referenced field in /proc/pid/smaps cannot distinguish whether a page was actually accessed. So here introduces a new interface, set_anon_ptes(), which only sets the access bit for the PTE corresponding to the faulting address. This allows accurate tracking of page access status in /proc/pid/smaps before memory reclaim scan the folios. During memory reclaim: folio_referenced() checks and clears the access bits of PTEs, rmap verifies all PTEs under a folio. If any PTE mapped subpage of folio has access bit set, the folio is retained during reclaim. So only set the access bit for the faulting PTE in do_anonymous_page() is safe, as it does not interfere with reclaim decisions. The patch only supports architectures without custom set_ptes() implementations (e.g., x86). ARM64 and other architectures are not yet supported. Additionally, I have some questions regarding the contiguous page tables for 64K huge pages on the ARM64 architecture. 'commit 4602e5757bcc ("arm64/mm: wire up PTE_CONT for user mappings")' described as following: > Since a contpte block only has a single access and dirty bit, the semantic > here changes slightly; when getting a pte (e.g. ptep_get()) that is part > of a contpte mapping, the access and dirty information are pulled from the > block (so all ptes in the block return the same access/dirty info). While the ARM64 manual states: > If hardware updates a translation table entry, and if the Contiguous bit = in > that entry is 1, then the members in a group of contiguous translation ta= ble > entries can have different AF, AP[2], and S2AP[1] values. Does this mean the 16 PTEs are not necessary to share same AF for ARM? Currently, for ARM64 huge pages with contiguous page tables enabled, the ac= cess and dirty bits for 64K huge pages are actually folded in software. However, I haven't found whether these access and dirty bits affect the TLB coalescing of contiguous page tables. If they do not affect it, I think ARM= 64 can also set the access bit only for the PTE corresponding to the actual fa= ult address in do_anonymous_page(). Signed-off-by: Wenchao Hao --- include/linux/pgtable.h | 28 ++++++++++++++++++++++++++++ mm/memory.c | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 652f287c1ef6..e2f3c932d672 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -302,6 +302,34 @@ static inline void set_ptes(struct mm_struct *mm, unsi= gned long addr, #endif #define set_pte_at(mm, addr, ptep, pte) set_ptes(mm, addr, ptep, pte, 1) =20 +#ifndef set_ptes +static inline void set_anon_ptes(struct mm_struct *mm, unsigned long addr, + unsigned long fault_addr, pte_t *ptep, pte_t pte, unsigned int nr) +{ + bool young =3D pte_young(pte); + + page_table_check_ptes_set(mm, ptep, pte, nr); + + for (;;) { + if (young && addr =3D=3D fault_addr) + pte =3D pte_mkyoung(pte); + else + pte =3D pte_mkold(pte); + + set_pte(ptep, pte); + if (--nr =3D=3D 0) + break; + + addr +=3D PAGE_SIZE; + ptep++; + pte =3D pte_next_pfn(pte); + } +} +#else +#define set_anon_ptes(mm, addr, fault_addr, ptep, pte, nr) \ + set_ptes(mm, addr, ptep, pte, nr) +#endif + #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, diff --git a/mm/memory.c b/mm/memory.c index da360a6eb8a4..65c69c7116a7 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -5273,7 +5273,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *= vmf) setpte: if (vmf_orig_pte_uffd_wp(vmf)) entry =3D pte_mkuffd_wp(entry); - set_ptes(vma->vm_mm, addr, vmf->pte, entry, nr_pages); + set_anon_ptes(vma->vm_mm, addr, vmf->address, vmf->pte, entry, nr_pages); =20 /* No need to invalidate - it was non-present before */ update_mmu_cache_range(vmf, vma, addr, vmf->pte, nr_pages); --=20 2.45.0