Skip to content

Commit 394290c

Browse files
davidhildenbrandakpm00
authored andcommitted
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/[email protected] 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/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: David Hildenbrand <[email protected]> Acked-by: Mike Rapoport (Microsoft) <[email protected]> Reviewed-by: Russell King (Oracle) <[email protected]> Reviewed-by: Qi Zheng <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Boris Ostrovsky <[email protected]> Cc: Christian Brauner <[email protected]> Cc: Christophe Leroy <[email protected]> Cc: Dave Hansen <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Juergen Gross <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Muchun Song <[email protected]> Cc: "Naveen N. Rao" <[email protected]> Cc: Nicholas Piggin <[email protected]> Cc: Oscar Salvador <[email protected]> Cc: Peter Xu <[email protected]> Cc: Thomas Gleixner <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 57979fa commit 394290c

File tree

8 files changed

+26
-24
lines changed

8 files changed

+26
-24
lines changed

arch/arm/mm/fault-armv.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
6161
return ret;
6262
}
6363

64-
#if USE_SPLIT_PTE_PTLOCKS
64+
#if defined(CONFIG_SPLIT_PTE_PTLOCKS)
6565
/*
6666
* If we are using split PTE locks, then we need to take the page
6767
* lock here. Otherwise we are using shared mm->page_table_lock
@@ -80,10 +80,10 @@ static inline void do_pte_unlock(spinlock_t *ptl)
8080
{
8181
spin_unlock(ptl);
8282
}
83-
#else /* !USE_SPLIT_PTE_PTLOCKS */
83+
#else /* !defined(CONFIG_SPLIT_PTE_PTLOCKS) */
8484
static inline void do_pte_lock(spinlock_t *ptl) {}
8585
static inline void do_pte_unlock(spinlock_t *ptl) {}
86-
#endif /* USE_SPLIT_PTE_PTLOCKS */
86+
#endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
8787

8888
static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
8989
unsigned long pfn)

arch/x86/xen/mmu_pv.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ static spinlock_t *xen_pte_lock(struct page *page, struct mm_struct *mm)
665665
{
666666
spinlock_t *ptl = NULL;
667667

668-
#if USE_SPLIT_PTE_PTLOCKS
668+
#if defined(CONFIG_SPLIT_PTE_PTLOCKS)
669669
ptl = ptlock_ptr(page_ptdesc(page));
670670
spin_lock_nest_lock(ptl, &mm->page_table_lock);
671671
#endif
@@ -1553,7 +1553,8 @@ static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn,
15531553

15541554
__set_pfn_prot(pfn, PAGE_KERNEL_RO);
15551555

1556-
if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS && !pinned)
1556+
if (level == PT_PTE && IS_ENABLED(CONFIG_SPLIT_PTE_PTLOCKS) &&
1557+
!pinned)
15571558
__pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
15581559

15591560
xen_mc_issue(XEN_LAZY_MMU);
@@ -1581,7 +1582,7 @@ static inline void xen_release_ptpage(unsigned long pfn, unsigned level)
15811582
if (pinned) {
15821583
xen_mc_batch();
15831584

1584-
if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS)
1585+
if (level == PT_PTE && IS_ENABLED(CONFIG_SPLIT_PTE_PTLOCKS))
15851586
__pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
15861587

15871588
__set_pfn_prot(pfn, PAGE_KERNEL);

include/linux/mm.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,7 +2891,7 @@ static inline void pagetable_free(struct ptdesc *pt)
28912891
__free_pages(page, compound_order(page));
28922892
}
28932893

2894-
#if USE_SPLIT_PTE_PTLOCKS
2894+
#if defined(CONFIG_SPLIT_PTE_PTLOCKS)
28952895
#if ALLOC_SPLIT_PTLOCKS
28962896
void __init ptlock_cache_init(void);
28972897
bool ptlock_alloc(struct ptdesc *ptdesc);
@@ -2949,7 +2949,7 @@ static inline bool ptlock_init(struct ptdesc *ptdesc)
29492949
return true;
29502950
}
29512951

2952-
#else /* !USE_SPLIT_PTE_PTLOCKS */
2952+
#else /* !defined(CONFIG_SPLIT_PTE_PTLOCKS) */
29532953
/*
29542954
* We use mm->page_table_lock to guard all pagetable pages of the mm.
29552955
*/
@@ -2964,7 +2964,7 @@ static inline spinlock_t *ptep_lockptr(struct mm_struct *mm, pte_t *pte)
29642964
static inline void ptlock_cache_init(void) {}
29652965
static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; }
29662966
static inline void ptlock_free(struct ptdesc *ptdesc) {}
2967-
#endif /* USE_SPLIT_PTE_PTLOCKS */
2967+
#endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
29682968

29692969
static inline bool pagetable_pte_ctor(struct ptdesc *ptdesc)
29702970
{
@@ -3024,7 +3024,7 @@ pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd,
30243024
((unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel(pmd))? \
30253025
NULL: pte_offset_kernel(pmd, address))
30263026

3027-
#if USE_SPLIT_PMD_PTLOCKS
3027+
#if defined(CONFIG_SPLIT_PMD_PTLOCKS)
30283028

30293029
static inline struct page *pmd_pgtable_page(pmd_t *pmd)
30303030
{

include/linux/mm_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,7 @@ struct mm_struct {
947947
#ifdef CONFIG_MMU_NOTIFIER
948948
struct mmu_notifier_subscriptions *notifier_subscriptions;
949949
#endif
950-
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
950+
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !defined(CONFIG_SPLIT_PMD_PTLOCKS)
951951
pgtable_t pmd_huge_pte; /* protected by page_table_lock */
952952
#endif
953953
#ifdef CONFIG_NUMA_BALANCING

include/linux/mm_types_task.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
#include <asm/tlbbatch.h>
1717
#endif
1818

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))
2219
#define ALLOC_SPLIT_PTLOCKS (SPINLOCK_SIZE > BITS_PER_LONG/8)
2320

2421
/*

kernel/fork.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ static void check_mm(struct mm_struct *mm)
832832
pr_alert("BUG: non-zero pgtables_bytes on freeing mm: %ld\n",
833833
mm_pgtables_bytes(mm));
834834

835-
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
835+
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !defined(CONFIG_SPLIT_PMD_PTLOCKS)
836836
VM_BUG_ON_MM(mm->pmd_huge_pte, mm);
837837
#endif
838838
}
@@ -1276,7 +1276,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
12761276
RCU_INIT_POINTER(mm->exe_file, NULL);
12771277
mmu_notifier_subscriptions_init(mm);
12781278
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)
12801280
mm->pmd_huge_pte = NULL;
12811281
#endif
12821282
mm_init_uprobes_state(mm);

mm/Kconfig

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -585,17 +585,21 @@ config ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
585585
# at the same time (e.g. copy_page_range()).
586586
# DEBUG_SPINLOCK and DEBUG_LOCK_ALLOC spinlock_t also enlarge struct page.
587587
#
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
595595

596596
config ARCH_ENABLE_SPLIT_PMD_PTLOCK
597597
bool
598598

599+
config SPLIT_PMD_PTLOCKS
600+
def_bool y
601+
depends on SPLIT_PTE_PTLOCKS && ARCH_ENABLE_SPLIT_PMD_PTLOCK
602+
599603
#
600604
# support for memory balloon
601605
config MEMORY_BALLOON

mm/memory.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6571,7 +6571,7 @@ long copy_folio_from_user(struct folio *dst_folio,
65716571
}
65726572
#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
65736573

6574-
#if USE_SPLIT_PTE_PTLOCKS && ALLOC_SPLIT_PTLOCKS
6574+
#if defined(CONFIG_SPLIT_PTE_PTLOCKS) && ALLOC_SPLIT_PTLOCKS
65756575

65766576
static struct kmem_cache *page_ptl_cachep;
65776577

0 commit comments

Comments
 (0)