Commit 54c8d911 authored by Yu Zhao's avatar Yu Zhao Committed by Will Deacon

arm64: mm: enable per pmd page table lock

Switch from per mm_struct to per pmd page table lock by enabling
ARCH_ENABLE_SPLIT_PMD_PTLOCK. This provides better granularity for
large system.

I'm not sure if there is contention on mm->page_table_lock. Given
the option comes at no cost (apart from initializing more spin
locks), why not enable it now.

We only do so when pmd is not folded, so we don't mistakenly call
pgtable_pmd_page_ctor() on pud or p4d in pgd_pgtable_alloc().
Signed-off-by: default avatarYu Zhao <yuzhao@google.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 14b94d07
...@@ -889,6 +889,9 @@ config ARCH_WANT_HUGE_PMD_SHARE ...@@ -889,6 +889,9 @@ config ARCH_WANT_HUGE_PMD_SHARE
config ARCH_HAS_CACHE_LINE_SIZE config ARCH_HAS_CACHE_LINE_SIZE
def_bool y def_bool y
config ARCH_ENABLE_SPLIT_PMD_PTLOCK
def_bool y if PGTABLE_LEVELS > 2
config SECCOMP config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode" bool "Enable seccomp to safely compute untrusted bytecode"
---help--- ---help---
......
...@@ -33,12 +33,22 @@ ...@@ -33,12 +33,22 @@
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{ {
return (pmd_t *)__get_free_page(PGALLOC_GFP); struct page *page;
page = alloc_page(PGALLOC_GFP);
if (!page)
return NULL;
if (!pgtable_pmd_page_ctor(page)) {
__free_page(page);
return NULL;
}
return page_address(page);
} }
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp) static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
{ {
BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1)); BUG_ON((unsigned long)pmdp & (PAGE_SIZE-1));
pgtable_pmd_page_dtor(virt_to_page(pmdp));
free_page((unsigned long)pmdp); free_page((unsigned long)pmdp);
} }
......
...@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, ...@@ -62,7 +62,10 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr) unsigned long addr)
{ {
tlb_remove_table(tlb, virt_to_page(pmdp)); struct page *page = virt_to_page(pmdp);
pgtable_pmd_page_dtor(page);
tlb_remove_table(tlb, page);
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment