From nobody Wed Sep 10 01:53:13 2025 Received: from cstnet.cn (smtp21.cstnet.cn [159.226.251.21]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D234A2DFF19; Fri, 5 Sep 2025 10:44:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757069051; cv=none; b=qsGGFMaIwZnlzYGM2e59Klq74SY7ffZ6H50mpKb6m6IlkdI6BURCgOQVM5DdpTQ858GfC82TNLTpbOVohSfOBM9kIfzIQvcEa7osA8c+0WZOIXSuZF5eQiV0dtNN/WSQOC2YrBsGLgQeFVofrDYHoH0l9P2VUpJ7IvVKWWnPx6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757069051; c=relaxed/simple; bh=8mymg/kOud74YiSeOVUzABCRIQY0xQLIbZamb4FP+oo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fPX45JRJ6wE4Ialp8cy6Seh/tMDn+Y/RN144tDMN5QI0lBP6IiLQ32RHnD7N+mgmuTL0cbmwqdofrbVMglUaZIjYPEfmgfIG/X7JMGrx8vgnm/2G3qI8yEGYBvPjbrPRFU5HIBxAo5gy+AzfSgv4ftRNN/+cYsGEW6vOTSIIDoA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn; spf=pass smtp.mailfrom=iscas.ac.cn; arc=none smtp.client-ip=159.226.251.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iscas.ac.cn Received: from ubt.. (unknown [210.73.43.101]) by APP-01 (Coremail) with SMTP id qwCowABnwaNMvbpoocLNAA--.50311S3; Fri, 05 Sep 2025 18:37:02 +0800 (CST) From: Chunyan Zhang To: linux-riscv@lists.infradead.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Andrew Morton , Deepak Gupta , Ved Shanbhogue , Peter Xu , Alexander Viro , Christian Brauner , Arnd Bergmann , Jan Kara , Axel Rasmussen , Wei Xu , David Hildenbrand , Chunyan Zhang Subject: [PATCH v9 1/5] mm: softdirty: Add pte_soft_dirty_available() Date: Fri, 5 Sep 2025 18:36:47 +0800 Message-Id: <20250905103651.489197-2-zhangchunyan@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250905103651.489197-1-zhangchunyan@iscas.ac.cn> References: <20250905103651.489197-1-zhangchunyan@iscas.ac.cn> 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 X-CM-TRANSID: qwCowABnwaNMvbpoocLNAA--.50311S3 X-Coremail-Antispam: 1UD129KBjvJXoWxtrWfArykKr1DKrykXw4UXFb_yoWxKw4kpF Z3Ca4Fq3y8JFsYg3yfJr4qqryYqF4Fga4UJryfC348X3y3G345WFsYqFyFvF1SgFy8GayS vFsFyw43Gr47tr7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUPlb7Iv0xC_tr1lb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I2 0VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI 8067AKxVWUGwA2048vs2IY020Ec7CjxVAFwI0_Gr0_Xr1l8cAvFVAK0II2c7xJM28CjxkF 64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcV CY1x0267AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIE c7CjxVAFwI0_GcCE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I 8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r4j6F4UMcvjeVCF s4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwACI402YVCY1x02628vn2kIc2xKxwCY1x 0262kKe7AKxVW8ZVWrXwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC2 0s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI 0_GFv_WrylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv2 0xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2js IE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZF pf9x07jGv3bUUUUU= X-CM-SenderInfo: x2kd0wxfkx051dq6x2xfdvhtffof0/1tbiCRAQB2i6ooVpxgABsV Content-Type: text/plain; charset="utf-8" Some platforms can customize the PTE soft dirty bit and make it unavailable even if the architecture allows providing the PTE resource. Signed-off-by: Chunyan Zhang --- fs/proc/task_mmu.c | 12 +++++++++++- include/linux/pgtable.h | 9 +++++++++ mm/debug_vm_pgtable.c | 9 +++++---- mm/huge_memory.c | 13 +++++++------ mm/internal.h | 2 +- mm/mremap.c | 13 +++++++------ mm/userfaultfd.c | 12 ++++++------ 7 files changed, 46 insertions(+), 24 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 29cca0e6d0ff..32ba2fb92975 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1058,7 +1058,7 @@ static void show_smap_vma_flags(struct seq_file *m, s= truct vm_area_struct *vma) * -Werror=3Dunterminated-string-initialization warning * with GCC 15 */ - static const char mnemonics[BITS_PER_LONG][3] =3D { + static char mnemonics[BITS_PER_LONG][3] =3D { /* * In case if we meet a flag we don't know about. */ @@ -1129,6 +1129,11 @@ static void show_smap_vma_flags(struct seq_file *m, = struct vm_area_struct *vma) [ilog2(VM_SEALED)] =3D "sl", #endif }; +#ifdef CONFIG_MEM_SOFT_DIRTY + if (!pte_soft_dirty_available()) + mnemonics[ilog2(VM_SOFTDIRTY)][0] =3D 0; +#endif + size_t i; =20 seq_puts(m, "VmFlags: "); @@ -1531,6 +1536,8 @@ static inline bool pte_is_pinned(struct vm_area_struc= t *vma, unsigned long addr, static inline void clear_soft_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *pte) { + if (!pte_soft_dirty_available()) + return; /* * The soft-dirty tracker uses #PF-s to catch writes * to pages, so write-protect the pte as well. See the @@ -1566,6 +1573,9 @@ static inline void clear_soft_dirty_pmd(struct vm_are= a_struct *vma, { pmd_t old, pmd =3D *pmdp; =20 + if (!pte_soft_dirty_available()) + return; + if (pmd_present(pmd)) { /* See comment in change_huge_pmd() */ old =3D pmdp_invalidate(vma, addr, pmdp); diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 4c035637eeb7..2a489647ac96 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -1538,6 +1538,15 @@ static inline pgprot_t pgprot_modify(pgprot_t oldpro= t, pgprot_t newprot) #endif =20 #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY + +/* + * Some platforms can customize the PTE soft dirty bit and make it unavail= able + * even if the architecture allows providing the PTE resource. + */ +#ifndef pte_soft_dirty_available +#define pte_soft_dirty_available() (true) +#endif + #ifndef CONFIG_ARCH_ENABLE_THP_MIGRATION static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) { diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c index 830107b6dd08..98ed7e22ccec 100644 --- a/mm/debug_vm_pgtable.c +++ b/mm/debug_vm_pgtable.c @@ -690,7 +690,7 @@ static void __init pte_soft_dirty_tests(struct pgtable_= debug_args *args) { pte_t pte =3D pfn_pte(args->fixed_pte_pfn, args->page_prot); =20 - if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY)) + if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) || !pte_soft_dirty_available()) return; =20 pr_debug("Validating PTE soft dirty\n"); @@ -702,7 +702,7 @@ static void __init pte_swap_soft_dirty_tests(struct pgt= able_debug_args *args) { pte_t pte; =20 - if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY)) + if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) || !pte_soft_dirty_available()) return; =20 pr_debug("Validating PTE swap soft dirty\n"); @@ -718,7 +718,7 @@ static void __init pmd_soft_dirty_tests(struct pgtable_= debug_args *args) { pmd_t pmd; =20 - if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY)) + if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) || !pte_soft_dirty_available()) return; =20 if (!has_transparent_hugepage()) @@ -735,7 +735,8 @@ static void __init pmd_swap_soft_dirty_tests(struct pgt= able_debug_args *args) pmd_t pmd; =20 if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) || - !IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION)) + !pte_soft_dirty_available() || + !IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION)) return; =20 if (!has_transparent_hugepage()) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 9c38a95e9f09..2cf001b2e950 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2271,12 +2271,13 @@ static inline int pmd_move_must_withdraw(spinlock_t= *new_pmd_ptl, =20 static pmd_t move_soft_dirty_pmd(pmd_t pmd) { -#ifdef CONFIG_MEM_SOFT_DIRTY - if (unlikely(is_pmd_migration_entry(pmd))) - pmd =3D pmd_swp_mksoft_dirty(pmd); - else if (pmd_present(pmd)) - pmd =3D pmd_mksoft_dirty(pmd); -#endif + if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && pte_soft_dirty_available()) { + if (unlikely(is_pmd_migration_entry(pmd))) + pmd =3D pmd_swp_mksoft_dirty(pmd); + else if (pmd_present(pmd)) + pmd =3D pmd_mksoft_dirty(pmd); + } + return pmd; } =20 diff --git a/mm/internal.h b/mm/internal.h index 45b725c3dc03..8a5b20fac892 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1538,7 +1538,7 @@ static inline bool vma_soft_dirty_enabled(struct vm_a= rea_struct *vma) * VM_SOFTDIRTY is defined as 0x0, then !(vm_flags & VM_SOFTDIRTY) * will be constantly true. */ - if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY)) + if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) || !pte_soft_dirty_available()) return false; =20 /* diff --git a/mm/mremap.c b/mm/mremap.c index e618a706aff5..7c01320aea33 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -162,12 +162,13 @@ static pte_t move_soft_dirty_pte(pte_t pte) * Set soft dirty bit so we can notice * in userspace the ptes were moved. */ -#ifdef CONFIG_MEM_SOFT_DIRTY - if (pte_present(pte)) - pte =3D pte_mksoft_dirty(pte); - else if (is_swap_pte(pte)) - pte =3D pte_swp_mksoft_dirty(pte); -#endif + if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && pte_soft_dirty_available()) { + if (pte_present(pte)) + pte =3D pte_mksoft_dirty(pte); + else if (is_swap_pte(pte)) + pte =3D pte_swp_mksoft_dirty(pte); + } + return pte; } =20 diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 45e6290e2e8b..0e07a983c513 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -1065,9 +1065,9 @@ static int move_present_pte(struct mm_struct *mm, =20 orig_dst_pte =3D folio_mk_pte(src_folio, dst_vma->vm_page_prot); /* Set soft dirty bit so userspace can notice the pte was moved */ -#ifdef CONFIG_MEM_SOFT_DIRTY - orig_dst_pte =3D pte_mksoft_dirty(orig_dst_pte); -#endif + if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && pte_soft_dirty_available()) + orig_dst_pte =3D pte_mksoft_dirty(orig_dst_pte); + if (pte_dirty(orig_src_pte)) orig_dst_pte =3D pte_mkdirty(orig_dst_pte); orig_dst_pte =3D pte_mkwrite(orig_dst_pte, dst_vma); @@ -1134,9 +1134,9 @@ static int move_swap_pte(struct mm_struct *mm, struct= vm_area_struct *dst_vma, } =20 orig_src_pte =3D ptep_get_and_clear(mm, src_addr, src_pte); -#ifdef CONFIG_MEM_SOFT_DIRTY - orig_src_pte =3D pte_swp_mksoft_dirty(orig_src_pte); -#endif + if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && pte_soft_dirty_available()) + orig_src_pte =3D pte_swp_mksoft_dirty(orig_src_pte); + set_pte_at(mm, dst_addr, dst_pte, orig_src_pte); double_pt_unlock(dst_ptl, src_ptl); =20 --=20 2.34.1