| From 7d1a899f667cf3ced1089821d74ea9e456428103 Mon Sep 17 00:00:00 2001 |
| From: Yongqin Liu <yongqin.liu@linaro.org> |
| Date: Fri, 28 Jul 2023 15:52:11 +0800 |
| Subject: [PATCH 1/7] Revert "mm/pgtable: allow pte_offset_map[_lock]() to |
| fail" |
| |
| This reverts commit 0d940a9b270b9220dcff74d8e9123c9788365751. |
| --- |
| Documentation/mm/split_page_table_lock.rst | 17 +++---- |
| include/linux/mm.h | 27 ++++------- |
| include/linux/pgtable.h | 22 +++------ |
| mm/pgtable-generic.c | 56 ---------------------- |
| 4 files changed, 21 insertions(+), 101 deletions(-) |
| |
| diff --git a/Documentation/mm/split_page_table_lock.rst b/Documentation/mm/split_page_table_lock.rst |
| index a834fad9de12..50ee0dfc95be 100644 |
| --- a/Documentation/mm/split_page_table_lock.rst |
| +++ b/Documentation/mm/split_page_table_lock.rst |
| @@ -14,20 +14,15 @@ tables. Access to higher level tables protected by mm->page_table_lock. |
| There are helpers to lock/unlock a table and other accessor functions: |
| |
| - pte_offset_map_lock() |
| - maps PTE and takes PTE table lock, returns pointer to PTE with |
| - pointer to its PTE table lock, or returns NULL if no PTE table; |
| - - pte_offset_map_nolock() |
| - maps PTE, returns pointer to PTE with pointer to its PTE table |
| - lock (not taken), or returns NULL if no PTE table; |
| - - pte_offset_map() |
| - maps PTE, returns pointer to PTE, or returns NULL if no PTE table; |
| - - pte_unmap() |
| - unmaps PTE table; |
| + maps pte and takes PTE table lock, returns pointer to the taken |
| + lock; |
| - pte_unmap_unlock() |
| unlocks and unmaps PTE table; |
| - pte_alloc_map_lock() |
| - allocates PTE table if needed and takes its lock, returns pointer to |
| - PTE with pointer to its lock, or returns NULL if allocation failed; |
| + allocates PTE table if needed and take the lock, returns pointer |
| + to taken lock or NULL if allocation failed; |
| + - pte_lockptr() |
| + returns pointer to PTE table lock; |
| - pmd_lock() |
| takes PMD table lock, returns pointer to taken lock; |
| - pmd_lockptr() |
| diff --git a/include/linux/mm.h b/include/linux/mm.h |
| index ae866bc9bad6..09bd0eaf1253 100644 |
| --- a/include/linux/mm.h |
| +++ b/include/linux/mm.h |
| @@ -2824,25 +2824,14 @@ static inline void pgtable_pte_page_dtor(struct page *page) |
| dec_lruvec_page_state(page, NR_PAGETABLE); |
| } |
| |
| -pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp); |
| -static inline pte_t *pte_offset_map(pmd_t *pmd, unsigned long addr) |
| -{ |
| - return __pte_offset_map(pmd, addr, NULL); |
| -} |
| - |
| -pte_t *__pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd, |
| - unsigned long addr, spinlock_t **ptlp); |
| -static inline pte_t *pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd, |
| - unsigned long addr, spinlock_t **ptlp) |
| -{ |
| - pte_t *pte; |
| - |
| - __cond_lock(*ptlp, pte = __pte_offset_map_lock(mm, pmd, addr, ptlp)); |
| - return pte; |
| -} |
| - |
| -pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd, |
| - unsigned long addr, spinlock_t **ptlp); |
| +#define pte_offset_map_lock(mm, pmd, address, ptlp) \ |
| +({ \ |
| + spinlock_t *__ptl = pte_lockptr(mm, pmd); \ |
| + pte_t *__pte = pte_offset_map(pmd, address); \ |
| + *(ptlp) = __ptl; \ |
| + spin_lock(__ptl); \ |
| + __pte; \ |
| +}) |
| |
| #define pte_unmap_unlock(pte, ptl) do { \ |
| spin_unlock(ptl); \ |
| diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h |
| index 5063b482e34f..e4e9734ac395 100644 |
| --- a/include/linux/pgtable.h |
| +++ b/include/linux/pgtable.h |
| @@ -94,22 +94,14 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address) |
| #define pte_offset_kernel pte_offset_kernel |
| #endif |
| |
| -#ifdef CONFIG_HIGHPTE |
| -#define __pte_map(pmd, address) \ |
| - ((pte_t *)kmap_local_page(pmd_page(*(pmd))) + pte_index((address))) |
| -#define pte_unmap(pte) do { \ |
| - kunmap_local((pte)); \ |
| - /* rcu_read_unlock() to be added later */ \ |
| -} while (0) |
| +#if defined(CONFIG_HIGHPTE) |
| +#define pte_offset_map(dir, address) \ |
| + ((pte_t *)kmap_local_page(pmd_page(*(dir))) + \ |
| + pte_index((address))) |
| +#define pte_unmap(pte) kunmap_local((pte)) |
| #else |
| -static inline pte_t *__pte_map(pmd_t *pmd, unsigned long address) |
| -{ |
| - return pte_offset_kernel(pmd, address); |
| -} |
| -static inline void pte_unmap(pte_t *pte) |
| -{ |
| - /* rcu_read_unlock() to be added later */ |
| -} |
| +#define pte_offset_map(dir, address) pte_offset_kernel((dir), (address)) |
| +#define pte_unmap(pte) ((void)(pte)) /* NOP */ |
| #endif |
| |
| /* Find an entry in the second-level page table.. */ |
| diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c |
| index 4d454953046f..e6c582e659c9 100644 |
| --- a/mm/pgtable-generic.c |
| +++ b/mm/pgtable-generic.c |
| @@ -10,8 +10,6 @@ |
| #include <linux/pagemap.h> |
| #include <linux/hugetlb.h> |
| #include <linux/pgtable.h> |
| -#include <linux/swap.h> |
| -#include <linux/swapops.h> |
| #include <linux/mm_inline.h> |
| #include <asm/tlb.h> |
| |
| @@ -231,57 +229,3 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address, |
| } |
| #endif |
| #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
| - |
| -pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp) |
| -{ |
| - pmd_t pmdval; |
| - |
| - /* rcu_read_lock() to be added later */ |
| - pmdval = pmdp_get_lockless(pmd); |
| - if (pmdvalp) |
| - *pmdvalp = pmdval; |
| - if (unlikely(pmd_none(pmdval) || is_pmd_migration_entry(pmdval))) |
| - goto nomap; |
| - if (unlikely(pmd_trans_huge(pmdval) || pmd_devmap(pmdval))) |
| - goto nomap; |
| - if (unlikely(pmd_bad(pmdval))) { |
| - pmd_clear_bad(pmd); |
| - goto nomap; |
| - } |
| - return __pte_map(&pmdval, addr); |
| -nomap: |
| - /* rcu_read_unlock() to be added later */ |
| - return NULL; |
| -} |
| - |
| -pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd, |
| - unsigned long addr, spinlock_t **ptlp) |
| -{ |
| - pmd_t pmdval; |
| - pte_t *pte; |
| - |
| - pte = __pte_offset_map(pmd, addr, &pmdval); |
| - if (likely(pte)) |
| - *ptlp = pte_lockptr(mm, &pmdval); |
| - return pte; |
| -} |
| - |
| -pte_t *__pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd, |
| - unsigned long addr, spinlock_t **ptlp) |
| -{ |
| - spinlock_t *ptl; |
| - pmd_t pmdval; |
| - pte_t *pte; |
| -again: |
| - pte = __pte_offset_map(pmd, addr, &pmdval); |
| - if (unlikely(!pte)) |
| - return pte; |
| - ptl = pte_lockptr(mm, &pmdval); |
| - spin_lock(ptl); |
| - if (likely(pmd_same(pmdval, pmdp_get_lockless(pmd)))) { |
| - *ptlp = ptl; |
| - return pte; |
| - } |
| - pte_unmap_unlock(pte, ptl); |
| - goto again; |
| -} |
| -- |
| 2.25.1 |
| |