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.

mm: turn USE_SPLIT_PTE_PTLOCKS / USE_SPLIT_PTE_PTLOCKS into Kconfig options

Patch series "mm: split PTE/PMD PT table Kconfig cleanups+clarifications".

This series is a follow up to the fixes:
"[PATCH v1 0/2] mm/hugetlb: fix hugetlb vs. core-mm PT locking"

When working on the fixes, I wondered why 8xx is fine (-> never uses split
PT locks) and how PT locking even works properly with PMD page table
sharing (-> always requires split PMD PT locks).

Let's improve the split PT lock detection, make hugetlb properly depend on
it and make 8xx bail out if it would ever get enabled by accident.

As an alternative to patch #3 we could extend the Kconfig
SPLIT_PTE_PTLOCKS option from patch #2 -- but enforcing it closer to the
code that actually implements it feels a bit nicer for documentation
purposes, and there is no need to actually disable it because it should
always be disabled (!SMP).

Did a bunch of cross-compilations to make sure that split PTE/PMD PT locks
are still getting used where we would expect them.

[1] https://lkml.kernel.org/r/20240725183955.2268884-1-david@redhat.com


This patch (of 3):

Let's clean that up a bit and prepare for depending on
CONFIG_SPLIT_PMD_PTLOCKS in other Kconfig options.

More cleanups would be reasonable (like the arch-specific "depends on" for
CONFIG_SPLIT_PTE_PTLOCKS), but we'll leave that for another day.

Link: https://lkml.kernel.org/r/20240726150728.3159964-1-david@redhat.com
Link: https://lkml.kernel.org/r/20240726150728.3159964-2-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Qi Zheng <zhengqi.arch@bytedance.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: "Naveen N. Rao" <naveen.n.rao@linux.ibm.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Peter Xu <peterx@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

David Hildenbrand and committed by
Andrew Morton
394290cb 57979fab

+26 -24
+3 -3
arch/arm/mm/fault-armv.c
··· 61 61 return ret; 62 62 } 63 63 64 - #if USE_SPLIT_PTE_PTLOCKS 64 + #if defined(CONFIG_SPLIT_PTE_PTLOCKS) 65 65 /* 66 66 * If we are using split PTE locks, then we need to take the page 67 67 * lock here. Otherwise we are using shared mm->page_table_lock ··· 80 80 { 81 81 spin_unlock(ptl); 82 82 } 83 - #else /* !USE_SPLIT_PTE_PTLOCKS */ 83 + #else /* !defined(CONFIG_SPLIT_PTE_PTLOCKS) */ 84 84 static inline void do_pte_lock(spinlock_t *ptl) {} 85 85 static inline void do_pte_unlock(spinlock_t *ptl) {} 86 - #endif /* USE_SPLIT_PTE_PTLOCKS */ 86 + #endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */ 87 87 88 88 static int adjust_pte(struct vm_area_struct *vma, unsigned long address, 89 89 unsigned long pfn)
+4 -3
arch/x86/xen/mmu_pv.c
··· 665 665 { 666 666 spinlock_t *ptl = NULL; 667 667 668 - #if USE_SPLIT_PTE_PTLOCKS 668 + #if defined(CONFIG_SPLIT_PTE_PTLOCKS) 669 669 ptl = ptlock_ptr(page_ptdesc(page)); 670 670 spin_lock_nest_lock(ptl, &mm->page_table_lock); 671 671 #endif ··· 1553 1553 1554 1554 __set_pfn_prot(pfn, PAGE_KERNEL_RO); 1555 1555 1556 - if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS && !pinned) 1556 + if (level == PT_PTE && IS_ENABLED(CONFIG_SPLIT_PTE_PTLOCKS) && 1557 + !pinned) 1557 1558 __pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); 1558 1559 1559 1560 xen_mc_issue(XEN_LAZY_MMU); ··· 1582 1581 if (pinned) { 1583 1582 xen_mc_batch(); 1584 1583 1585 - if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS) 1584 + if (level == PT_PTE && IS_ENABLED(CONFIG_SPLIT_PTE_PTLOCKS)) 1586 1585 __pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); 1587 1586 1588 1587 __set_pfn_prot(pfn, PAGE_KERNEL);
+4 -4
include/linux/mm.h
··· 2891 2891 __free_pages(page, compound_order(page)); 2892 2892 } 2893 2893 2894 - #if USE_SPLIT_PTE_PTLOCKS 2894 + #if defined(CONFIG_SPLIT_PTE_PTLOCKS) 2895 2895 #if ALLOC_SPLIT_PTLOCKS 2896 2896 void __init ptlock_cache_init(void); 2897 2897 bool ptlock_alloc(struct ptdesc *ptdesc); ··· 2949 2949 return true; 2950 2950 } 2951 2951 2952 - #else /* !USE_SPLIT_PTE_PTLOCKS */ 2952 + #else /* !defined(CONFIG_SPLIT_PTE_PTLOCKS) */ 2953 2953 /* 2954 2954 * We use mm->page_table_lock to guard all pagetable pages of the mm. 2955 2955 */ ··· 2964 2964 static inline void ptlock_cache_init(void) {} 2965 2965 static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; } 2966 2966 static inline void ptlock_free(struct ptdesc *ptdesc) {} 2967 - #endif /* USE_SPLIT_PTE_PTLOCKS */ 2967 + #endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */ 2968 2968 2969 2969 static inline bool pagetable_pte_ctor(struct ptdesc *ptdesc) 2970 2970 { ··· 3024 3024 ((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd))? \ 3025 3025 NULL: pte_offset_kernel(pmd, address)) 3026 3026 3027 - #if USE_SPLIT_PMD_PTLOCKS 3027 + #if defined(CONFIG_SPLIT_PMD_PTLOCKS) 3028 3028 3029 3029 static inline struct page *pmd_pgtable_page(pmd_t *pmd) 3030 3030 {
+1 -1
include/linux/mm_types.h
··· 947 947 #ifdef CONFIG_MMU_NOTIFIER 948 948 struct mmu_notifier_subscriptions *notifier_subscriptions; 949 949 #endif 950 - #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS 950 + #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !defined(CONFIG_SPLIT_PMD_PTLOCKS) 951 951 pgtable_t pmd_huge_pte; /* protected by page_table_lock */ 952 952 #endif 953 953 #ifdef CONFIG_NUMA_BALANCING
-3
include/linux/mm_types_task.h
··· 16 16 #include <asm/tlbbatch.h> 17 17 #endif 18 18 19 - #define USE_SPLIT_PTE_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS) 20 - #define USE_SPLIT_PMD_PTLOCKS (USE_SPLIT_PTE_PTLOCKS && \ 21 - IS_ENABLED(CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK)) 22 19 #define ALLOC_SPLIT_PTLOCKS (SPINLOCK_SIZE > BITS_PER_LONG/8) 23 20 24 21 /*
+2 -2
kernel/fork.c
··· 832 832 pr_alert("BUG: non-zero pgtables_bytes on freeing mm: %ld\n", 833 833 mm_pgtables_bytes(mm)); 834 834 835 - #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS 835 + #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !defined(CONFIG_SPLIT_PMD_PTLOCKS) 836 836 VM_BUG_ON_MM(mm->pmd_huge_pte, mm); 837 837 #endif 838 838 } ··· 1276 1276 RCU_INIT_POINTER(mm->exe_file, NULL); 1277 1277 mmu_notifier_subscriptions_init(mm); 1278 1278 init_tlb_flush_pending(mm); 1279 - #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS 1279 + #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !defined(CONFIG_SPLIT_PMD_PTLOCKS) 1280 1280 mm->pmd_huge_pte = NULL; 1281 1281 #endif 1282 1282 mm_init_uprobes_state(mm);
+11 -7
mm/Kconfig
··· 585 585 # at the same time (e.g. copy_page_range()). 586 586 # DEBUG_SPINLOCK and DEBUG_LOCK_ALLOC spinlock_t also enlarge struct page. 587 587 # 588 - config SPLIT_PTLOCK_CPUS 589 - int 590 - default "999999" if !MMU 591 - default "999999" if ARM && !CPU_CACHE_VIPT 592 - default "999999" if PARISC && !PA20 593 - default "999999" if SPARC32 594 - default "4" 588 + config SPLIT_PTE_PTLOCKS 589 + def_bool y 590 + depends on MMU 591 + depends on NR_CPUS >= 4 592 + depends on !ARM || CPU_CACHE_VIPT 593 + depends on !PARISC || PA20 594 + depends on !SPARC32 595 595 596 596 config ARCH_ENABLE_SPLIT_PMD_PTLOCK 597 597 bool 598 + 599 + config SPLIT_PMD_PTLOCKS 600 + def_bool y 601 + depends on SPLIT_PTE_PTLOCKS && ARCH_ENABLE_SPLIT_PMD_PTLOCK 598 602 599 603 # 600 604 # support for memory balloon
+1 -1
mm/memory.c
··· 6571 6571 } 6572 6572 #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ 6573 6573 6574 - #if USE_SPLIT_PTE_PTLOCKS && ALLOC_SPLIT_PTLOCKS 6574 + #if defined(CONFIG_SPLIT_PTE_PTLOCKS) && ALLOC_SPLIT_PTLOCKS 6575 6575 6576 6576 static struct kmem_cache *page_ptl_cachep; 6577 6577