From mboxrd@z Thu Jan 1 00:00:00 1970 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: 8bit 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 table > 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 access 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 ARM64 can also set the access bit only for the PTE corresponding to the actual fault 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, unsigned long addr, #endif #define set_pte_at(mm, addr, ptep, pte) set_ptes(mm, addr, ptep, pte, 1) +#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 = pte_young(pte); + + page_table_check_ptes_set(mm, ptep, pte, nr); + + for (;;) { + if (young && addr == fault_addr) + pte = pte_mkyoung(pte); + else + pte = pte_mkold(pte); + + set_pte(ptep, pte); + if (--nr == 0) + break; + + addr += PAGE_SIZE; + ptep++; + pte = 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 = 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); /* No need to invalidate - it was non-present before */ update_mmu_cache_range(vmf, vma, addr, vmf->pte, nr_pages); -- 2.45.0