Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

riscv: mm: add soft-dirty page tracking support

The Svrsw60t59b extension allows to free the PTE reserved bits 60 and 59
for software, this patch uses bit 59 for soft-dirty.

To add swap PTE soft-dirty tracking, we borrow bit 3 which is available
for swap PTEs on RISC-V systems.

Link: https://lkml.kernel.org/r/20251113072806.795029-5-zhangchunyan@iscas.ac.cn
Signed-off-by: Chunyan Zhang <zhangchunyan@iscas.ac.cn>
Reviewed-by: Deepak Gupta <debug@rivosinc.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Andrew Jones <ajones@ventanamicro.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Conor Dooley <conor.dooley@microchip.com>
Cc: Conor Dooley <conor@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Yuanchu Xie <yuanchu@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Chunyan Zhang and committed by
Andrew Morton
2a3ebad4 59f6acb4

+93 -2
+1
arch/riscv/Kconfig
··· 142 142 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT 143 143 select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET 144 144 select HAVE_ARCH_SECCOMP_FILTER 145 + select HAVE_ARCH_SOFT_DIRTY if 64BIT && MMU && RISCV_ISA_SVRSW60T59B 145 146 select HAVE_ARCH_THREAD_STRUCT_WHITELIST 146 147 select HAVE_ARCH_TRACEHOOK 147 148 select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU
+19
arch/riscv/include/asm/pgtable-bits.h
··· 19 19 #define _PAGE_SOFT (3 << 8) /* Reserved for software */ 20 20 21 21 #define _PAGE_SPECIAL (1 << 8) /* RSW: 0x1 */ 22 + 23 + #ifdef CONFIG_MEM_SOFT_DIRTY 24 + 25 + /* ext_svrsw60t59b: bit 59 for soft-dirty tracking */ 26 + #define _PAGE_SOFT_DIRTY \ 27 + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ 28 + (1UL << 59) : 0) 29 + /* 30 + * Bit 3 is always zero for swap entry computation, so we 31 + * can borrow it for swap page soft-dirty tracking. 32 + */ 33 + #define _PAGE_SWP_SOFT_DIRTY \ 34 + ((riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) ? \ 35 + _PAGE_EXEC : 0) 36 + #else 37 + #define _PAGE_SOFT_DIRTY 0 38 + #define _PAGE_SWP_SOFT_DIRTY 0 39 + #endif /* CONFIG_MEM_SOFT_DIRTY */ 40 + 22 41 #define _PAGE_TABLE _PAGE_PRESENT 23 42 24 43 /*
+73 -2
arch/riscv/include/asm/pgtable.h
··· 428 428 429 429 static inline pte_t pte_mkdirty(pte_t pte) 430 430 { 431 - return __pte(pte_val(pte) | _PAGE_DIRTY); 431 + return __pte(pte_val(pte) | _PAGE_DIRTY | _PAGE_SOFT_DIRTY); 432 432 } 433 433 434 434 static inline pte_t pte_mkclean(pte_t pte) ··· 455 455 { 456 456 return pte; 457 457 } 458 + 459 + #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY 460 + #define pgtable_supports_soft_dirty() \ 461 + (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && \ 462 + riscv_has_extension_unlikely(RISCV_ISA_EXT_SVRSW60T59B)) 463 + 464 + static inline bool pte_soft_dirty(pte_t pte) 465 + { 466 + return !!(pte_val(pte) & _PAGE_SOFT_DIRTY); 467 + } 468 + 469 + static inline pte_t pte_mksoft_dirty(pte_t pte) 470 + { 471 + return __pte(pte_val(pte) | _PAGE_SOFT_DIRTY); 472 + } 473 + 474 + static inline pte_t pte_clear_soft_dirty(pte_t pte) 475 + { 476 + return __pte(pte_val(pte) & ~(_PAGE_SOFT_DIRTY)); 477 + } 478 + 479 + static inline bool pte_swp_soft_dirty(pte_t pte) 480 + { 481 + return !!(pte_val(pte) & _PAGE_SWP_SOFT_DIRTY); 482 + } 483 + 484 + static inline pte_t pte_swp_mksoft_dirty(pte_t pte) 485 + { 486 + return __pte(pte_val(pte) | _PAGE_SWP_SOFT_DIRTY); 487 + } 488 + 489 + static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) 490 + { 491 + return __pte(pte_val(pte) & ~(_PAGE_SWP_SOFT_DIRTY)); 492 + } 493 + #endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ 458 494 459 495 #ifdef CONFIG_RISCV_ISA_SVNAPOT 460 496 #define pte_leaf_size(pte) (pte_napot(pte) ? \ ··· 841 805 } 842 806 #endif 843 807 808 + #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY 809 + static inline bool pmd_soft_dirty(pmd_t pmd) 810 + { 811 + return pte_soft_dirty(pmd_pte(pmd)); 812 + } 813 + 814 + static inline pmd_t pmd_mksoft_dirty(pmd_t pmd) 815 + { 816 + return pte_pmd(pte_mksoft_dirty(pmd_pte(pmd))); 817 + } 818 + 819 + static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd) 820 + { 821 + return pte_pmd(pte_clear_soft_dirty(pmd_pte(pmd))); 822 + } 823 + 824 + #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION 825 + static inline bool pmd_swp_soft_dirty(pmd_t pmd) 826 + { 827 + return pte_swp_soft_dirty(pmd_pte(pmd)); 828 + } 829 + 830 + static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) 831 + { 832 + return pte_pmd(pte_swp_mksoft_dirty(pmd_pte(pmd))); 833 + } 834 + 835 + static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) 836 + { 837 + return pte_pmd(pte_swp_clear_soft_dirty(pmd_pte(pmd))); 838 + } 839 + #endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */ 840 + #endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ 841 + 844 842 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, 845 843 pmd_t *pmdp, pmd_t pmd) 846 844 { ··· 1073 1003 * 1074 1004 * Format of swap PTE: 1075 1005 * bit 0: _PAGE_PRESENT (zero) 1076 - * bit 1 to 3: _PAGE_LEAF (zero) 1006 + * bit 1 to 2: (zero) 1007 + * bit 3: _PAGE_SWP_SOFT_DIRTY 1077 1008 * bit 5: _PAGE_PROT_NONE (zero) 1078 1009 * bit 6: exclusive marker 1079 1010 * bits 7 to 11: swap type