* [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries
@ 2024-09-13 8:44 Anshuman Khandual
2024-09-13 8:44 ` [PATCH 1/7] m68k/mm: Change pmd_val() Anshuman Khandual
` (6 more replies)
0 siblings, 7 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users
This series converts all generic page table entries direct derefences via
pxdp_get() based helpers extending the changes brought in via the commit
c33c794828f2 ("mm: ptep_get() conversion"). First it does some platform
specific changes for m68k and x86 architecture.
This series has been build tested on multiple architecture such as x86,
arm64, powerpc, powerpc64le, riscv, and m68k etc.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: "Mike Rapoport (IBM)" <rppt@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: x86@kernel.org
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-mm@kvack.org
Cc: linux-fsdevel@vger.kernel.org
Cc: kasan-dev@googlegroups.com
Cc: linux-kernel@vger.kernel.org
Cc: linux-perf-users@vger.kernel.org
Cc: kasan-dev@googlegroups.com
Anshuman Khandual (7):
m68k/mm: Change pmd_val()
x86/mm: Drop page table entry address output from pxd_ERROR()
mm: Use ptep_get() for accessing PTE entries
mm: Use pmdp_get() for accessing PMD entries
mm: Use pudp_get() for accessing PUD entries
mm: Use p4dp_get() for accessing P4D entries
mm: Use pgdp_get() for accessing PGD entries
arch/m68k/include/asm/page.h | 2 +-
arch/x86/include/asm/pgtable-3level.h | 12 ++---
arch/x86/include/asm/pgtable_64.h | 20 +++----
drivers/misc/sgi-gru/grufault.c | 10 ++--
fs/proc/task_mmu.c | 26 ++++-----
fs/userfaultfd.c | 6 +--
include/linux/huge_mm.h | 5 +-
include/linux/mm.h | 6 +--
include/linux/pgtable.h | 38 +++++++-------
kernel/events/core.c | 6 +--
mm/gup.c | 40 +++++++-------
mm/hmm.c | 2 +-
mm/huge_memory.c | 76 +++++++++++++--------------
mm/hugetlb.c | 10 ++--
mm/hugetlb_vmemmap.c | 4 +-
mm/kasan/init.c | 38 +++++++-------
mm/kasan/shadow.c | 12 ++---
mm/khugepaged.c | 4 +-
mm/madvise.c | 6 +--
mm/mapping_dirty_helpers.c | 2 +-
mm/memory-failure.c | 14 ++---
mm/memory.c | 59 +++++++++++----------
mm/mempolicy.c | 4 +-
mm/migrate.c | 4 +-
mm/migrate_device.c | 10 ++--
mm/mlock.c | 6 +--
mm/mprotect.c | 2 +-
mm/mremap.c | 4 +-
mm/page_table_check.c | 4 +-
mm/page_vma_mapped.c | 6 +--
mm/pagewalk.c | 10 ++--
mm/percpu.c | 8 +--
mm/pgalloc-track.h | 6 +--
mm/pgtable-generic.c | 24 ++++-----
mm/ptdump.c | 8 +--
mm/rmap.c | 8 +--
mm/sparse-vmemmap.c | 10 ++--
mm/vmalloc.c | 46 ++++++++--------
mm/vmscan.c | 6 +--
39 files changed, 283 insertions(+), 281 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/7] m68k/mm: Change pmd_val()
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
@ 2024-09-13 8:44 ` Anshuman Khandual
2024-09-13 8:44 ` [PATCH 2/7] x86/mm: Drop page table entry address output from pxd_ERROR() Anshuman Khandual
` (5 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Geert Uytterhoeven, Guo Ren
This changes platform's pmd_val() to access the pmd_t element directly like
other architectures rather than current pointer address based dereferencing
that prevents transition into pmdp_get().
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/m68k/include/asm/page.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h
index 8cfb84b49975..be3f2c2a656c 100644
--- a/arch/m68k/include/asm/page.h
+++ b/arch/m68k/include/asm/page.h
@@ -19,7 +19,7 @@
*/
#if !defined(CONFIG_MMU) || CONFIG_PGTABLE_LEVELS == 3
typedef struct { unsigned long pmd; } pmd_t;
-#define pmd_val(x) ((&x)->pmd)
+#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) } )
#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/7] x86/mm: Drop page table entry address output from pxd_ERROR()
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
2024-09-13 8:44 ` [PATCH 1/7] m68k/mm: Change pmd_val() Anshuman Khandual
@ 2024-09-13 8:44 ` Anshuman Khandual
2024-09-13 17:21 ` Dave Hansen
2024-09-13 8:44 ` [PATCH 3/7] mm: Use ptep_get() for accessing PTE entries Anshuman Khandual
` (4 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
This drops page table entry address output from all pxd_ERROR() definitions
which now matches with other architectures. This also prevents build issues
while transitioning into pxdp_get() based page table entry accesses.
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
arch/x86/include/asm/pgtable-3level.h | 12 ++++++------
arch/x86/include/asm/pgtable_64.h | 20 ++++++++++----------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h
index dabafba957ea..e1fa4dd87753 100644
--- a/arch/x86/include/asm/pgtable-3level.h
+++ b/arch/x86/include/asm/pgtable-3level.h
@@ -10,14 +10,14 @@
*/
#define pte_ERROR(e) \
- pr_err("%s:%d: bad pte %p(%08lx%08lx)\n", \
- __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low)
+ pr_err("%s:%d: bad pte (%08lx%08lx)\n", \
+ __FILE__, __LINE__, (e).pte_high, (e).pte_low)
#define pmd_ERROR(e) \
- pr_err("%s:%d: bad pmd %p(%016Lx)\n", \
- __FILE__, __LINE__, &(e), pmd_val(e))
+ pr_err("%s:%d: bad pmd (%016Lx)\n", \
+ __FILE__, __LINE__, pmd_val(e))
#define pgd_ERROR(e) \
- pr_err("%s:%d: bad pgd %p(%016Lx)\n", \
- __FILE__, __LINE__, &(e), pgd_val(e))
+ pr_err("%s:%d: bad pgd (%016Lx)\n", \
+ __FILE__, __LINE__, pgd_val(e))
#define pxx_xchg64(_pxx, _ptr, _val) ({ \
_pxx##val_t *_p = (_pxx##val_t *)_ptr; \
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 3c4407271d08..4e462c825cab 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -32,24 +32,24 @@ extern void paging_init(void);
static inline void sync_initial_page_table(void) { }
#define pte_ERROR(e) \
- pr_err("%s:%d: bad pte %p(%016lx)\n", \
- __FILE__, __LINE__, &(e), pte_val(e))
+ pr_err("%s:%d: bad pte (%016lx)\n", \
+ __FILE__, __LINE__, pte_val(e))
#define pmd_ERROR(e) \
- pr_err("%s:%d: bad pmd %p(%016lx)\n", \
- __FILE__, __LINE__, &(e), pmd_val(e))
+ pr_err("%s:%d: bad pmd (%016lx)\n", \
+ __FILE__, __LINE__, pmd_val(e))
#define pud_ERROR(e) \
- pr_err("%s:%d: bad pud %p(%016lx)\n", \
- __FILE__, __LINE__, &(e), pud_val(e))
+ pr_err("%s:%d: bad pud (%016lx)\n", \
+ __FILE__, __LINE__, pud_val(e))
#if CONFIG_PGTABLE_LEVELS >= 5
#define p4d_ERROR(e) \
- pr_err("%s:%d: bad p4d %p(%016lx)\n", \
- __FILE__, __LINE__, &(e), p4d_val(e))
+ pr_err("%s:%d: bad p4d (%016lx)\n", \
+ __FILE__, __LINE__, p4d_val(e))
#endif
#define pgd_ERROR(e) \
- pr_err("%s:%d: bad pgd %p(%016lx)\n", \
- __FILE__, __LINE__, &(e), pgd_val(e))
+ pr_err("%s:%d: bad pgd (%016lx)\n", \
+ __FILE__, __LINE__, pgd_val(e))
struct mm_struct;
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/7] mm: Use ptep_get() for accessing PTE entries
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
2024-09-13 8:44 ` [PATCH 1/7] m68k/mm: Change pmd_val() Anshuman Khandual
2024-09-13 8:44 ` [PATCH 2/7] x86/mm: Drop page table entry address output from pxd_ERROR() Anshuman Khandual
@ 2024-09-13 8:44 ` Anshuman Khandual
2024-09-13 10:27 ` Ryan Roberts
2024-09-13 8:44 ` [PATCH 4/7] mm: Use pmdp_get() for accessing PMD entries Anshuman Khandual
` (3 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users
Convert PTE accesses via ptep_get() helper that defaults as READ_ONCE() but
also provides the platform an opportunity to override when required.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: "Mike Rapoport (IBM)" <rppt@kernel.org>
Cc: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
include/linux/pgtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 2a6a3cccfc36..05e6995c1b93 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1060,7 +1060,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
*/
#define set_pte_safe(ptep, pte) \
({ \
- WARN_ON_ONCE(pte_present(*ptep) && !pte_same(*ptep, pte)); \
+ WARN_ON_ONCE(pte_present(ptep_get(ptep)) && !pte_same(ptep_get(ptep), pte)); \
set_pte(ptep, pte); \
})
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/7] mm: Use pmdp_get() for accessing PMD entries
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
` (2 preceding siblings ...)
2024-09-13 8:44 ` [PATCH 3/7] mm: Use ptep_get() for accessing PTE entries Anshuman Khandual
@ 2024-09-13 8:44 ` Anshuman Khandual
2024-09-13 10:38 ` Ryan Roberts
2024-09-13 8:44 ` [PATCH 5/7] mm: Use pudp_get() for accessing PUD entries Anshuman Khandual
` (2 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Dimitri Sivanich, Muchun Song, Andrey Ryabinin, Miaohe Lin,
Naoya Horiguchi, Pasha Tatashin, Dennis Zhou, Tejun Heo,
Christoph Lameter, Uladzislau Rezki, Christoph Hellwig
Convert PMD accesses via pmdp_get() helper that defaults as READ_ONCE() but
also provides the platform an opportunity to override when required.
Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Uladzislau Rezki <urezki@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: "Mike Rapoport (IBM)" <rppt@kernel.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: kasan-dev@googlegroups.com
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
drivers/misc/sgi-gru/grufault.c | 4 +--
fs/proc/task_mmu.c | 26 +++++++-------
include/linux/huge_mm.h | 3 +-
include/linux/mm.h | 2 +-
include/linux/pgtable.h | 14 ++++----
mm/gup.c | 14 ++++----
mm/huge_memory.c | 60 ++++++++++++++++-----------------
mm/hugetlb_vmemmap.c | 4 +--
mm/kasan/init.c | 10 +++---
mm/kasan/shadow.c | 4 +--
mm/khugepaged.c | 4 +--
mm/madvise.c | 6 ++--
mm/memory-failure.c | 6 ++--
mm/memory.c | 25 +++++++-------
mm/mempolicy.c | 4 +--
mm/migrate.c | 4 +--
mm/migrate_device.c | 10 +++---
mm/mlock.c | 6 ++--
mm/mprotect.c | 2 +-
mm/mremap.c | 4 +--
mm/page_table_check.c | 2 +-
mm/pagewalk.c | 4 +--
mm/percpu.c | 2 +-
mm/pgtable-generic.c | 16 ++++-----
mm/ptdump.c | 2 +-
mm/rmap.c | 2 +-
mm/sparse-vmemmap.c | 4 +--
mm/vmalloc.c | 12 +++----
28 files changed, 129 insertions(+), 127 deletions(-)
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 3557d78ee47a..f3d6249b7dfb 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -224,10 +224,10 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
goto err;
pmdp = pmd_offset(pudp, vaddr);
- if (unlikely(pmd_none(*pmdp)))
+ if (unlikely(pmd_none(pmdp_get(pmdp))))
goto err;
#ifdef CONFIG_X86_64
- if (unlikely(pmd_leaf(*pmdp)))
+ if (unlikely(pmd_leaf(pmdp_get(pmdp))))
pte = ptep_get((pte_t *)pmdp);
else
#endif
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 5f171ad7b436..8bb90f877dc5 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -862,11 +862,11 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
bool present = false;
struct folio *folio;
- if (pmd_present(*pmd)) {
- page = vm_normal_page_pmd(vma, addr, *pmd);
+ if (pmd_present(pmdp_get(pmd))) {
+ page = vm_normal_page_pmd(vma, addr, pmdp_get(pmd));
present = true;
- } else if (unlikely(thp_migration_supported() && is_swap_pmd(*pmd))) {
- swp_entry_t entry = pmd_to_swp_entry(*pmd);
+ } else if (unlikely(thp_migration_supported() && is_swap_pmd(pmdp_get(pmd)))) {
+ swp_entry_t entry = pmd_to_swp_entry(pmdp_get(pmd));
if (is_pfn_swap_entry(entry))
page = pfn_swap_entry_to_page(entry);
@@ -883,7 +883,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
else
mss->file_thp += HPAGE_PMD_SIZE;
- smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd),
+ smaps_account(mss, page, true, pmd_young(pmdp_get(pmd)), pmd_dirty(pmdp_get(pmd)),
locked, present);
}
#else
@@ -1426,7 +1426,7 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma,
static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma,
unsigned long addr, pmd_t *pmdp)
{
- pmd_t old, pmd = *pmdp;
+ pmd_t old, pmd = pmdp_get(pmdp);
if (pmd_present(pmd)) {
/* See comment in change_huge_pmd() */
@@ -1468,10 +1468,10 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
goto out;
}
- if (!pmd_present(*pmd))
+ if (!pmd_present(pmdp_get(pmd)))
goto out;
- folio = pmd_folio(*pmd);
+ folio = pmd_folio(pmdp_get(pmd));
/* Clear accessed and referenced bits. */
pmdp_test_and_clear_young(vma, addr, pmd);
@@ -1769,7 +1769,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
if (ptl) {
unsigned int idx = (addr & ~PMD_MASK) >> PAGE_SHIFT;
u64 flags = 0, frame = 0;
- pmd_t pmd = *pmdp;
+ pmd_t pmd = pmdp_get(pmdp);
struct page *page = NULL;
struct folio *folio = NULL;
@@ -2189,7 +2189,7 @@ static unsigned long pagemap_thp_category(struct pagemap_scan_private *p,
static void make_uffd_wp_pmd(struct vm_area_struct *vma,
unsigned long addr, pmd_t *pmdp)
{
- pmd_t old, pmd = *pmdp;
+ pmd_t old, pmd = pmdp_get(pmdp);
if (pmd_present(pmd)) {
old = pmdp_invalidate_ad(vma, addr, pmdp);
@@ -2416,7 +2416,7 @@ static int pagemap_scan_thp_entry(pmd_t *pmd, unsigned long start,
return -ENOENT;
categories = p->cur_vma_category |
- pagemap_thp_category(p, vma, start, *pmd);
+ pagemap_thp_category(p, vma, start, pmdp_get(pmd));
if (!pagemap_scan_is_interesting_page(categories, p))
goto out_unlock;
@@ -2947,9 +2947,9 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
if (ptl) {
struct page *page;
- page = can_gather_numa_stats_pmd(*pmd, vma, addr);
+ page = can_gather_numa_stats_pmd(pmdp_get(pmd), vma, addr);
if (page)
- gather_stats(page, md, pmd_dirty(*pmd),
+ gather_stats(page, md, pmd_dirty(pmdp_get(pmd)),
HPAGE_PMD_SIZE/PAGE_SIZE);
spin_unlock(ptl);
return 0;
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index e25d9ebfdf89..351d6c72af9e 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -369,7 +369,8 @@ static inline int is_swap_pmd(pmd_t pmd)
static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
struct vm_area_struct *vma)
{
- if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd))
+ if (is_swap_pmd(pmdp_get(pmd)) || pmd_trans_huge(pmdp_get(pmd)) ||
+ pmd_devmap(pmdp_get(pmd)))
return __pmd_trans_huge_lock(pmd, vma);
else
return NULL;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 147073601716..258e49323306 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2921,7 +2921,7 @@ static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc)
static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd)
{
- return ptlock_ptr(page_ptdesc(pmd_page(*pmd)));
+ return ptlock_ptr(page_ptdesc(pmd_page(pmdp_get(pmd))));
}
static inline spinlock_t *ptep_lockptr(struct mm_struct *mm, pte_t *pte)
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 05e6995c1b93..188a183205b3 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -367,7 +367,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
unsigned long address,
pmd_t *pmdp)
{
- pmd_t pmd = *pmdp;
+ pmd_t pmd = pmdp_get(pmdp);
int r = 1;
if (!pmd_young(pmd))
r = 0;
@@ -598,7 +598,7 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
unsigned long address,
pmd_t *pmdp)
{
- pmd_t pmd = *pmdp;
+ pmd_t pmd = pmdp_get(pmdp);
pmd_clear(pmdp);
page_table_check_pmd_clear(mm, pmd);
@@ -876,7 +876,7 @@ static inline pte_t pte_sw_mkyoung(pte_t pte)
static inline void pmdp_set_wrprotect(struct mm_struct *mm,
unsigned long address, pmd_t *pmdp)
{
- pmd_t old_pmd = *pmdp;
+ pmd_t old_pmd = pmdp_get(pmdp);
set_pmd_at(mm, address, pmdp, pmd_wrprotect(old_pmd));
}
#else
@@ -945,7 +945,7 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
static inline pmd_t generic_pmdp_establish(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp, pmd_t pmd)
{
- pmd_t old_pmd = *pmdp;
+ pmd_t old_pmd = pmdp_get(pmdp);
set_pmd_at(vma->vm_mm, address, pmdp, pmd);
return old_pmd;
}
@@ -1066,7 +1066,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
#define set_pmd_safe(pmdp, pmd) \
({ \
- WARN_ON_ONCE(pmd_present(*pmdp) && !pmd_same(*pmdp, pmd)); \
+ WARN_ON_ONCE(pmd_present(pmdp_get(pmdp)) && !pmd_same(pmdp_get(pmdp), pmd)); \
set_pmd(pmdp, pmd); \
})
@@ -1270,9 +1270,9 @@ static inline int pud_none_or_clear_bad(pud_t *pud)
static inline int pmd_none_or_clear_bad(pmd_t *pmd)
{
- if (pmd_none(*pmd))
+ if (pmd_none(pmdp_get(pmd)))
return 1;
- if (unlikely(pmd_bad(*pmd))) {
+ if (unlikely(pmd_bad(pmdp_get(pmd)))) {
pmd_clear_bad(pmd);
return 1;
}
diff --git a/mm/gup.c b/mm/gup.c
index 54d0dc3831fb..aeeac0a54944 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -699,7 +699,7 @@ static struct page *follow_huge_pmd(struct vm_area_struct *vma,
struct follow_page_context *ctx)
{
struct mm_struct *mm = vma->vm_mm;
- pmd_t pmdval = *pmd;
+ pmd_t pmdval = pmdp_get(pmd);
struct page *page;
int ret;
@@ -714,7 +714,7 @@ static struct page *follow_huge_pmd(struct vm_area_struct *vma,
if ((flags & FOLL_DUMP) && is_huge_zero_pmd(pmdval))
return ERR_PTR(-EFAULT);
- if (pmd_protnone(*pmd) && !gup_can_follow_protnone(vma, flags))
+ if (pmd_protnone(pmdp_get(pmd)) && !gup_can_follow_protnone(vma, flags))
return NULL;
if (!pmd_write(pmdval) && gup_must_unshare(vma, flags, page))
@@ -957,7 +957,7 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma,
return no_page_table(vma, flags, address);
ptl = pmd_lock(mm, pmd);
- pmdval = *pmd;
+ pmdval = pmdp_get(pmd);
if (unlikely(!pmd_present(pmdval))) {
spin_unlock(ptl);
return no_page_table(vma, flags, address);
@@ -1120,7 +1120,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
if (pud_none(*pud))
return -EFAULT;
pmd = pmd_offset(pud, address);
- if (!pmd_present(*pmd))
+ if (!pmd_present(pmdp_get(pmd)))
return -EFAULT;
pte = pte_offset_map(pmd, address);
if (!pte)
@@ -2898,7 +2898,7 @@ static int gup_fast_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
if (!folio)
goto pte_unmap;
- if (unlikely(pmd_val(pmd) != pmd_val(*pmdp)) ||
+ if (unlikely(pmd_val(pmd) != pmd_val(pmdp_get(pmdp))) ||
unlikely(pte_val(pte) != pte_val(ptep_get(ptep)))) {
gup_put_folio(folio, 1, flags);
goto pte_unmap;
@@ -3007,7 +3007,7 @@ static int gup_fast_devmap_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
if (!gup_fast_devmap_leaf(fault_pfn, addr, end, flags, pages, nr))
return 0;
- if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
+ if (unlikely(pmd_val(orig) != pmd_val(pmdp_get(pmdp)))) {
gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
return 0;
}
@@ -3074,7 +3074,7 @@ static int gup_fast_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
if (!folio)
return 0;
- if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
+ if (unlikely(pmd_val(orig) != pmd_val(pmdp_get(pmdp)))) {
gup_put_folio(folio, refs, flags);
return 0;
}
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 67c86a5d64a6..3545142a5dc9 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1065,7 +1065,7 @@ static void set_huge_zero_folio(pgtable_t pgtable, struct mm_struct *mm,
struct folio *zero_folio)
{
pmd_t entry;
- if (!pmd_none(*pmd))
+ if (!pmd_none(pmdp_get(pmd)))
return;
entry = mk_pmd(&zero_folio->page, vma->vm_page_prot);
entry = pmd_mkhuge(entry);
@@ -1148,13 +1148,13 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
spinlock_t *ptl;
ptl = pmd_lock(mm, pmd);
- if (!pmd_none(*pmd)) {
+ if (!pmd_none(pmdp_get(pmd))) {
if (write) {
- if (pmd_pfn(*pmd) != pfn_t_to_pfn(pfn)) {
- WARN_ON_ONCE(!is_huge_zero_pmd(*pmd));
+ if (pmd_pfn(pmdp_get(pmd)) != pfn_t_to_pfn(pfn)) {
+ WARN_ON_ONCE(!is_huge_zero_pmd(pmdp_get(pmd)));
goto out_unlock;
}
- entry = pmd_mkyoung(*pmd);
+ entry = pmd_mkyoung(pmdp_get(pmd));
entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
if (pmdp_set_access_flags(vma, addr, pmd, entry, 1))
update_mmu_cache_pmd(vma, addr, pmd);
@@ -1318,7 +1318,7 @@ void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
{
pmd_t _pmd;
- _pmd = pmd_mkyoung(*pmd);
+ _pmd = pmd_mkyoung(pmdp_get(pmd));
if (write)
_pmd = pmd_mkdirty(_pmd);
if (pmdp_set_access_flags(vma, addr & HPAGE_PMD_MASK,
@@ -1329,17 +1329,17 @@ void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr,
pmd_t *pmd, int flags, struct dev_pagemap **pgmap)
{
- unsigned long pfn = pmd_pfn(*pmd);
+ unsigned long pfn = pmd_pfn(pmdp_get(pmd));
struct mm_struct *mm = vma->vm_mm;
struct page *page;
int ret;
assert_spin_locked(pmd_lockptr(mm, pmd));
- if (flags & FOLL_WRITE && !pmd_write(*pmd))
+ if (flags & FOLL_WRITE && !pmd_write(pmdp_get(pmd)))
return NULL;
- if (pmd_present(*pmd) && pmd_devmap(*pmd))
+ if (pmd_present(pmdp_get(pmd)) && pmd_devmap(pmdp_get(pmd)))
/* pass */;
else
return NULL;
@@ -1772,7 +1772,7 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
if (!ptl)
goto out_unlocked;
- orig_pmd = *pmd;
+ orig_pmd = pmdp_get(pmd);
if (is_huge_zero_pmd(orig_pmd))
goto out;
@@ -2006,12 +2006,12 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
return 0;
#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
- if (is_swap_pmd(*pmd)) {
- swp_entry_t entry = pmd_to_swp_entry(*pmd);
+ if (is_swap_pmd(pmdp_get(pmd))) {
+ swp_entry_t entry = pmd_to_swp_entry(pmdp_get(pmd));
struct folio *folio = pfn_swap_entry_folio(entry);
pmd_t newpmd;
- VM_BUG_ON(!is_pmd_migration_entry(*pmd));
+ VM_BUG_ON(!is_pmd_migration_entry(pmdp_get(pmd)));
if (is_writable_migration_entry(entry)) {
/*
* A protection check is difficult so
@@ -2022,17 +2022,17 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
else
entry = make_readable_migration_entry(swp_offset(entry));
newpmd = swp_entry_to_pmd(entry);
- if (pmd_swp_soft_dirty(*pmd))
+ if (pmd_swp_soft_dirty(pmdp_get(pmd)))
newpmd = pmd_swp_mksoft_dirty(newpmd);
} else {
- newpmd = *pmd;
+ newpmd = pmdp_get(pmd);
}
if (uffd_wp)
newpmd = pmd_swp_mkuffd_wp(newpmd);
else if (uffd_wp_resolve)
newpmd = pmd_swp_clear_uffd_wp(newpmd);
- if (!pmd_same(*pmd, newpmd))
+ if (!pmd_same(pmdp_get(pmd), newpmd))
set_pmd_at(mm, addr, pmd, newpmd);
goto unlock;
}
@@ -2046,13 +2046,13 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
* data is likely to be read-cached on the local CPU and
* local/remote hits to the zero page are not interesting.
*/
- if (is_huge_zero_pmd(*pmd))
+ if (is_huge_zero_pmd(pmdp_get(pmd)))
goto unlock;
- if (pmd_protnone(*pmd))
+ if (pmd_protnone(pmdp_get(pmd)))
goto unlock;
- folio = pmd_folio(*pmd);
+ folio = pmd_folio(pmdp_get(pmd));
toptier = node_is_toptier(folio_nid(folio));
/*
* Skip scanning top tier node if normal numa
@@ -2266,8 +2266,8 @@ spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma)
{
spinlock_t *ptl;
ptl = pmd_lock(vma->vm_mm, pmd);
- if (likely(is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) ||
- pmd_devmap(*pmd)))
+ if (likely(is_swap_pmd(pmdp_get(pmd)) || pmd_trans_huge(pmdp_get(pmd)) ||
+ pmd_devmap(pmdp_get(pmd))))
return ptl;
spin_unlock(ptl);
return NULL;
@@ -2404,8 +2404,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
VM_BUG_ON(haddr & ~HPAGE_PMD_MASK);
VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PMD_SIZE, vma);
- VM_BUG_ON(!is_pmd_migration_entry(*pmd) && !pmd_trans_huge(*pmd)
- && !pmd_devmap(*pmd));
+ VM_BUG_ON(!is_pmd_migration_entry(pmdp_get(pmd)) && !pmd_trans_huge(pmdp_get(pmd))
+ && !pmd_devmap(pmdp_get(pmd)));
count_vm_event(THP_SPLIT_PMD);
@@ -2438,7 +2438,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
return;
}
- if (is_huge_zero_pmd(*pmd)) {
+ if (is_huge_zero_pmd(pmdp_get(pmd))) {
/*
* FIXME: Do we want to invalidate secondary mmu by calling
* mmu_notifier_arch_invalidate_secondary_tlbs() see comments below
@@ -2451,11 +2451,11 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
return __split_huge_zero_page_pmd(vma, haddr, pmd);
}
- pmd_migration = is_pmd_migration_entry(*pmd);
+ pmd_migration = is_pmd_migration_entry(pmdp_get(pmd));
if (unlikely(pmd_migration)) {
swp_entry_t entry;
- old_pmd = *pmd;
+ old_pmd = pmdp_get(pmd);
entry = pmd_to_swp_entry(old_pmd);
page = pfn_swap_entry_to_page(entry);
write = is_writable_migration_entry(entry);
@@ -2620,9 +2620,9 @@ void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
* require a folio to check the PMD against. Otherwise, there
* is a risk of replacing the wrong folio.
*/
- if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||
- is_pmd_migration_entry(*pmd)) {
- if (folio && folio != pmd_folio(*pmd))
+ if (pmd_trans_huge(pmdp_get(pmd)) || pmd_devmap(pmdp_get(pmd)) ||
+ is_pmd_migration_entry(pmdp_get(pmd))) {
+ if (folio && folio != pmd_folio(pmdp_get(pmd)))
return;
__split_huge_pmd_locked(vma, pmd, address, freeze);
}
@@ -2719,7 +2719,7 @@ static bool __discard_anon_folio_pmd_locked(struct vm_area_struct *vma,
{
struct mm_struct *mm = vma->vm_mm;
int ref_count, map_count;
- pmd_t orig_pmd = *pmdp;
+ pmd_t orig_pmd = pmdp_get(pmdp);
if (folio_test_dirty(folio) || pmd_dirty(orig_pmd))
return false;
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 0c3f56b3578e..9deb82654d5b 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -70,7 +70,7 @@ static int vmemmap_split_pmd(pmd_t *pmd, struct page *head, unsigned long start,
}
spin_lock(&init_mm.page_table_lock);
- if (likely(pmd_leaf(*pmd))) {
+ if (likely(pmd_leaf(pmdp_get(pmd)))) {
/*
* Higher order allocations from buddy allocator must be able to
* be treated as indepdenent small pages (as they can be freed
@@ -104,7 +104,7 @@ static int vmemmap_pmd_entry(pmd_t *pmd, unsigned long addr,
walk->action = ACTION_CONTINUE;
spin_lock(&init_mm.page_table_lock);
- head = pmd_leaf(*pmd) ? pmd_page(*pmd) : NULL;
+ head = pmd_leaf(pmdp_get(pmd)) ? pmd_page(pmdp_get(pmd)) : NULL;
/*
* Due to HugeTLB alignment requirements and the vmemmap
* pages being at the start of the hotplugged memory
diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index 89895f38f722..4418bcdcb2aa 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -121,7 +121,7 @@ static int __ref zero_pmd_populate(pud_t *pud, unsigned long addr,
continue;
}
- if (pmd_none(*pmd)) {
+ if (pmd_none(pmdp_get(pmd))) {
pte_t *p;
if (slab_is_available())
@@ -300,7 +300,7 @@ static void kasan_free_pte(pte_t *pte_start, pmd_t *pmd)
return;
}
- pte_free_kernel(&init_mm, (pte_t *)page_to_virt(pmd_page(*pmd)));
+ pte_free_kernel(&init_mm, (pte_t *)page_to_virt(pmd_page(pmdp_get(pmd))));
pmd_clear(pmd);
}
@@ -311,7 +311,7 @@ static void kasan_free_pmd(pmd_t *pmd_start, pud_t *pud)
for (i = 0; i < PTRS_PER_PMD; i++) {
pmd = pmd_start + i;
- if (!pmd_none(*pmd))
+ if (!pmd_none(pmdp_get(pmd)))
return;
}
@@ -381,10 +381,10 @@ static void kasan_remove_pmd_table(pmd_t *pmd, unsigned long addr,
next = pmd_addr_end(addr, end);
- if (!pmd_present(*pmd))
+ if (!pmd_present(pmdp_get(pmd)))
continue;
- if (kasan_pte_table(*pmd)) {
+ if (kasan_pte_table(pmdp_get(pmd))) {
if (IS_ALIGNED(addr, PMD_SIZE) &&
IS_ALIGNED(next, PMD_SIZE)) {
pmd_clear(pmd);
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index d6210ca48dda..aec16a7236f7 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -202,9 +202,9 @@ static bool shadow_mapped(unsigned long addr)
if (pud_leaf(*pud))
return true;
pmd = pmd_offset(pud, addr);
- if (pmd_none(*pmd))
+ if (pmd_none(pmdp_get(pmd)))
return false;
- if (pmd_leaf(*pmd))
+ if (pmd_leaf(pmdp_get(pmd)))
return true;
pte = pte_offset_kernel(pmd, addr);
return !pte_none(ptep_get(pte));
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index cdd1d8655a76..793da996313f 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1192,7 +1192,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,
if (pte)
pte_unmap(pte);
spin_lock(pmd_ptl);
- BUG_ON(!pmd_none(*pmd));
+ BUG_ON(!pmd_none(pmdp_get(pmd)));
/*
* We can only use set_pmd_at when establishing
* hugepmds and never for establishing regular pmds that
@@ -1229,7 +1229,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,
_pmd = maybe_pmd_mkwrite(pmd_mkdirty(_pmd), vma);
spin_lock(pmd_ptl);
- BUG_ON(!pmd_none(*pmd));
+ BUG_ON(!pmd_none(pmdp_get(pmd)));
folio_add_new_anon_rmap(folio, vma, address, RMAP_EXCLUSIVE);
folio_add_lru_vma(folio, vma);
pgtable_trans_huge_deposit(mm, pmd, pgtable);
diff --git a/mm/madvise.c b/mm/madvise.c
index 89089d84f8df..382c55d2ec94 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -357,7 +357,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
!can_do_file_pageout(vma);
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
- if (pmd_trans_huge(*pmd)) {
+ if (pmd_trans_huge(pmdp_get(pmd))) {
pmd_t orig_pmd;
unsigned long next = pmd_addr_end(addr, end);
@@ -366,7 +366,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
if (!ptl)
return 0;
- orig_pmd = *pmd;
+ orig_pmd = pmdp_get(pmd);
if (is_huge_zero_pmd(orig_pmd))
goto huge_unlock;
@@ -655,7 +655,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
int nr, max_nr;
next = pmd_addr_end(addr, end);
- if (pmd_trans_huge(*pmd))
+ if (pmd_trans_huge(pmdp_get(pmd)))
if (madvise_free_huge_pmd(tlb, vma, pmd, addr, next))
return 0;
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 7066fc84f351..305dbef3cc4d 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -422,9 +422,9 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
if (pud_devmap(*pud))
return PUD_SHIFT;
pmd = pmd_offset(pud, address);
- if (!pmd_present(*pmd))
+ if (!pmd_present(pmdp_get(pmd)))
return 0;
- if (pmd_devmap(*pmd))
+ if (pmd_devmap(pmdp_get(pmd)))
return PMD_SHIFT;
pte = pte_offset_map(pmd, address);
if (!pte)
@@ -775,7 +775,7 @@ static int check_hwpoisoned_entry(pte_t pte, unsigned long addr, short shift,
static int check_hwpoisoned_pmd_entry(pmd_t *pmdp, unsigned long addr,
struct hwpoison_walk *hwp)
{
- pmd_t pmd = *pmdp;
+ pmd_t pmd = pmdp_get(pmdp);
unsigned long pfn;
unsigned long hwpoison_vaddr;
diff --git a/mm/memory.c b/mm/memory.c
index 3c01d68065be..43953a6d350f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -189,7 +189,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member)
static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
unsigned long addr)
{
- pgtable_t token = pmd_pgtable(*pmd);
+ pgtable_t token = pmd_pgtable(pmdp_get(pmd));
pmd_clear(pmd);
pte_free_tlb(tlb, token, addr);
mm_dec_nr_ptes(tlb->mm);
@@ -421,7 +421,7 @@ void pmd_install(struct mm_struct *mm, pmd_t *pmd, pgtable_t *pte)
{
spinlock_t *ptl = pmd_lock(mm, pmd);
- if (likely(pmd_none(*pmd))) { /* Has another populated it ? */
+ if (likely(pmd_none(pmdp_get(pmd)))) { /* Has another populated it ? */
mm_inc_nr_ptes(mm);
/*
* Ensure all pte setup (eg. pte page lock and page clearing) are
@@ -462,7 +462,7 @@ int __pte_alloc_kernel(pmd_t *pmd)
return -ENOMEM;
spin_lock(&init_mm.page_table_lock);
- if (likely(pmd_none(*pmd))) { /* Has another populated it ? */
+ if (likely(pmd_none(pmdp_get(pmd)))) { /* Has another populated it ? */
smp_wmb(); /* See comment in pmd_install() */
pmd_populate_kernel(&init_mm, pmd, new);
new = NULL;
@@ -1710,7 +1710,8 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
pmd = pmd_offset(pud, addr);
do {
next = pmd_addr_end(addr, end);
- if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) {
+ if (is_swap_pmd(pmdp_get(pmd)) || pmd_trans_huge(pmdp_get(pmd)) ||
+ pmd_devmap(pmdp_get(pmd))) {
if (next - addr != HPAGE_PMD_SIZE)
__split_huge_pmd(vma, pmd, addr, false, NULL);
else if (zap_huge_pmd(tlb, vma, pmd, addr)) {
@@ -1720,7 +1721,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
/* fall through */
} else if (details && details->single_folio &&
folio_test_pmd_mappable(details->single_folio) &&
- next - addr == HPAGE_PMD_SIZE && pmd_none(*pmd)) {
+ next - addr == HPAGE_PMD_SIZE && pmd_none(pmdp_get(pmd))) {
spinlock_t *ptl = pmd_lock(tlb->mm, pmd);
/*
* Take and drop THP pmd lock so that we cannot return
@@ -1729,7 +1730,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
*/
spin_unlock(ptl);
}
- if (pmd_none(*pmd)) {
+ if (pmd_none(pmdp_get(pmd))) {
addr = next;
continue;
}
@@ -1975,7 +1976,7 @@ static pmd_t *walk_to_pmd(struct mm_struct *mm, unsigned long addr)
if (!pmd)
return NULL;
- VM_BUG_ON(pmd_trans_huge(*pmd));
+ VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
return pmd;
}
@@ -2577,7 +2578,7 @@ static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud,
pmd = pmd_alloc(mm, pud, addr);
if (!pmd)
return -ENOMEM;
- VM_BUG_ON(pmd_trans_huge(*pmd));
+ VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
do {
next = pmd_addr_end(addr, end);
err = remap_pte_range(mm, pmd, addr, next,
@@ -2829,11 +2830,11 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
}
do {
next = pmd_addr_end(addr, end);
- if (pmd_none(*pmd) && !create)
+ if (pmd_none(pmdp_get(pmd)) && !create)
continue;
- if (WARN_ON_ONCE(pmd_leaf(*pmd)))
+ if (WARN_ON_ONCE(pmd_leaf(pmdp_get(pmd))))
return -EINVAL;
- if (!pmd_none(*pmd) && WARN_ON_ONCE(pmd_bad(*pmd))) {
+ if (!pmd_none(pmdp_get(pmd)) && WARN_ON_ONCE(pmd_bad(pmdp_get(pmd)))) {
if (!create)
continue;
pmd_clear_bad(pmd);
@@ -6150,7 +6151,7 @@ int follow_pte(struct vm_area_struct *vma, unsigned long address,
goto out;
pmd = pmd_offset(pud, address);
- VM_BUG_ON(pmd_trans_huge(*pmd));
+ VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
ptep = pte_offset_map_lock(mm, pmd, address, ptlp);
if (!ptep)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index b858e22b259d..03f2df44b07f 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -505,11 +505,11 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
struct folio *folio;
struct queue_pages *qp = walk->private;
- if (unlikely(is_pmd_migration_entry(*pmd))) {
+ if (unlikely(is_pmd_migration_entry(pmdp_get(pmd)))) {
qp->nr_failed++;
return;
}
- folio = pmd_folio(*pmd);
+ folio = pmd_folio(pmdp_get(pmd));
if (is_huge_zero_folio(folio)) {
walk->action = ACTION_CONTINUE;
return;
diff --git a/mm/migrate.c b/mm/migrate.c
index 923ea80ba744..a1dd5c8f88dd 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -369,9 +369,9 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd)
spinlock_t *ptl;
ptl = pmd_lock(mm, pmd);
- if (!is_pmd_migration_entry(*pmd))
+ if (!is_pmd_migration_entry(pmdp_get(pmd)))
goto unlock;
- migration_entry_wait_on_locked(pmd_to_swp_entry(*pmd), ptl);
+ migration_entry_wait_on_locked(pmd_to_swp_entry(pmdp_get(pmd)), ptl);
return;
unlock:
spin_unlock(ptl);
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 6d66dc1c6ffa..3a08cef6cd39 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -67,19 +67,19 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
pte_t *ptep;
again:
- if (pmd_none(*pmdp))
+ if (pmd_none(pmdp_get(pmdp)))
return migrate_vma_collect_hole(start, end, -1, walk);
- if (pmd_trans_huge(*pmdp)) {
+ if (pmd_trans_huge(pmdp_get(pmdp))) {
struct folio *folio;
ptl = pmd_lock(mm, pmdp);
- if (unlikely(!pmd_trans_huge(*pmdp))) {
+ if (unlikely(!pmd_trans_huge(pmdp_get(pmdp)))) {
spin_unlock(ptl);
goto again;
}
- folio = pmd_folio(*pmdp);
+ folio = pmd_folio(pmdp_get(pmdp));
if (is_huge_zero_folio(folio)) {
spin_unlock(ptl);
split_huge_pmd(vma, pmdp, addr);
@@ -596,7 +596,7 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
pmdp = pmd_alloc(mm, pudp, addr);
if (!pmdp)
goto abort;
- if (pmd_trans_huge(*pmdp) || pmd_devmap(*pmdp))
+ if (pmd_trans_huge(pmdp_get(pmdp)) || pmd_devmap(pmdp_get(pmdp)))
goto abort;
if (pte_alloc(mm, pmdp))
goto abort;
diff --git a/mm/mlock.c b/mm/mlock.c
index e3e3dc2b2956..c3c479e9d0f8 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -363,11 +363,11 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
ptl = pmd_trans_huge_lock(pmd, vma);
if (ptl) {
- if (!pmd_present(*pmd))
+ if (!pmd_present(pmdp_get(pmd)))
goto out;
- if (is_huge_zero_pmd(*pmd))
+ if (is_huge_zero_pmd(pmdp_get(pmd)))
goto out;
- folio = pmd_folio(*pmd);
+ folio = pmd_folio(pmdp_get(pmd));
if (vma->vm_flags & VM_LOCKED)
mlock_folio(folio);
else
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 222ab434da54..121fb448b0db 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -381,7 +381,7 @@ static inline long change_pmd_range(struct mmu_gather *tlb,
break;
}
- if (pmd_none(*pmd))
+ if (pmd_none(pmdp_get(pmd)))
goto next;
/* invoke the mmu notifier if the pmd is populated */
diff --git a/mm/mremap.c b/mm/mremap.c
index e7ae140fc640..d42ac62bd34e 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -63,7 +63,7 @@ static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr)
return NULL;
pmd = pmd_offset(pud, addr);
- if (pmd_none(*pmd))
+ if (pmd_none(pmdp_get(pmd)))
return NULL;
return pmd;
@@ -97,7 +97,7 @@ static pmd_t *alloc_new_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
if (!pmd)
return NULL;
- VM_BUG_ON(pmd_trans_huge(*pmd));
+ VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
return pmd;
}
diff --git a/mm/page_table_check.c b/mm/page_table_check.c
index 509c6ef8de40..48a2cf56c80e 100644
--- a/mm/page_table_check.c
+++ b/mm/page_table_check.c
@@ -241,7 +241,7 @@ void __page_table_check_pmd_set(struct mm_struct *mm, pmd_t *pmdp, pmd_t pmd)
page_table_check_pmd_flags(pmd);
- __page_table_check_pmd_clear(mm, *pmdp);
+ __page_table_check_pmd_clear(mm, pmdp_get(pmdp));
if (pmd_user_accessible_page(pmd)) {
page_table_check_set(pmd_pfn(pmd), PMD_SIZE >> PAGE_SHIFT,
pmd_write(pmd));
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index ae2f08ce991b..c3019a160e77 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -86,7 +86,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
do {
again:
next = pmd_addr_end(addr, end);
- if (pmd_none(*pmd)) {
+ if (pmd_none(pmdp_get(pmd))) {
if (ops->pte_hole)
err = ops->pte_hole(addr, next, depth, walk);
if (err)
@@ -112,7 +112,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
* Check this here so we only break down trans_huge
* pages when we _need_ to
*/
- if ((!walk->vma && (pmd_leaf(*pmd) || !pmd_present(*pmd))) ||
+ if ((!walk->vma && (pmd_leaf(pmdp_get(pmd)) || !pmd_present(pmdp_get(pmd)))) ||
walk->action == ACTION_CONTINUE ||
!(ops->pte_entry))
continue;
diff --git a/mm/percpu.c b/mm/percpu.c
index 20d91af8c033..7ee77c0fd5e3 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -3208,7 +3208,7 @@ void __init __weak pcpu_populate_pte(unsigned long addr)
}
pmd = pmd_offset(pud, addr);
- if (!pmd_present(*pmd)) {
+ if (!pmd_present(pmdp_get(pmd))) {
pte_t *new;
new = memblock_alloc(PTE_TABLE_SIZE, PTE_TABLE_SIZE);
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index a78a4adf711a..a5045d0fc73e 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -51,7 +51,7 @@ void pud_clear_bad(pud_t *pud)
*/
void pmd_clear_bad(pmd_t *pmd)
{
- pmd_ERROR(*pmd);
+ pmd_ERROR(pmdp_get(pmd));
pmd_clear(pmd);
}
@@ -110,7 +110,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp,
pmd_t entry, int dirty)
{
- int changed = !pmd_same(*pmdp, entry);
+ int changed = !pmd_same(pmdp_get(pmdp), entry);
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
if (changed) {
set_pmd_at(vma->vm_mm, address, pmdp, entry);
@@ -139,8 +139,8 @@ pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address,
{
pmd_t pmd;
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
- VM_BUG_ON(pmd_present(*pmdp) && !pmd_trans_huge(*pmdp) &&
- !pmd_devmap(*pmdp));
+ VM_BUG_ON(pmd_present(pmdp_get(pmdp)) && !pmd_trans_huge(pmdp_get(pmdp)) &&
+ !pmd_devmap(pmdp_get(pmdp)));
pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
return pmd;
@@ -198,8 +198,8 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
pmd_t *pmdp)
{
- VM_WARN_ON_ONCE(!pmd_present(*pmdp));
- pmd_t old = pmdp_establish(vma, address, pmdp, pmd_mkinvalid(*pmdp));
+ VM_WARN_ON_ONCE(!pmd_present(pmdp_get(pmdp)));
+ pmd_t old = pmdp_establish(vma, address, pmdp, pmd_mkinvalid(pmdp_get(pmdp)));
flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
return old;
}
@@ -209,7 +209,7 @@ pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address,
pmd_t *pmdp)
{
- VM_WARN_ON_ONCE(!pmd_present(*pmdp));
+ VM_WARN_ON_ONCE(!pmd_present(pmdp_get(pmdp)));
return pmdp_invalidate(vma, address, pmdp);
}
#endif
@@ -225,7 +225,7 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
pmd_t pmd;
VM_BUG_ON(address & ~HPAGE_PMD_MASK);
- VM_BUG_ON(pmd_trans_huge(*pmdp));
+ VM_BUG_ON(pmd_trans_huge(pmdp_get(pmdp)));
pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
/* collapse entails shooting down ptes not pmd */
diff --git a/mm/ptdump.c b/mm/ptdump.c
index 106e1d66e9f9..e17588a32012 100644
--- a/mm/ptdump.c
+++ b/mm/ptdump.c
@@ -99,7 +99,7 @@ static int ptdump_pmd_entry(pmd_t *pmd, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
struct ptdump_state *st = walk->private;
- pmd_t val = READ_ONCE(*pmd);
+ pmd_t val = pmdp_get(pmd);
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
if (pmd_page(val) == virt_to_page(lm_alias(kasan_early_shadow_pte)))
diff --git a/mm/rmap.c b/mm/rmap.c
index 2490e727e2dc..ec668c48bccc 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1036,7 +1036,7 @@ static int page_vma_mkclean_one(struct page_vma_mapped_walk *pvmw)
pmd_t *pmd = pvmw->pmd;
pmd_t entry;
- if (!pmd_dirty(*pmd) && !pmd_write(*pmd))
+ if (!pmd_dirty(pmdp_get(pmd)) && !pmd_write(pmdp_get(pmd)))
continue;
flush_cache_range(vma, address,
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index edcc7a6b0f6f..c89706e107ce 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -187,7 +187,7 @@ static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node)
pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
{
pmd_t *pmd = pmd_offset(pud, addr);
- if (pmd_none(*pmd)) {
+ if (pmd_none(pmdp_get(pmd))) {
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
if (!p)
return NULL;
@@ -332,7 +332,7 @@ int __meminit vmemmap_populate_hugepages(unsigned long start, unsigned long end,
return -ENOMEM;
pmd = pmd_offset(pud, addr);
- if (pmd_none(READ_ONCE(*pmd))) {
+ if (pmd_none(pmdp_get(pmd))) {
void *p;
p = vmemmap_alloc_block_buf(PMD_SIZE, node, altmap);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index a0df1e2e155a..d27aa1ebaad6 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -150,7 +150,7 @@ static int vmap_try_huge_pmd(pmd_t *pmd, unsigned long addr, unsigned long end,
if (!IS_ALIGNED(phys_addr, PMD_SIZE))
return 0;
- if (pmd_present(*pmd) && !pmd_free_pte_page(pmd, addr))
+ if (pmd_present(pmdp_get(pmd)) && !pmd_free_pte_page(pmd, addr))
return 0;
return pmd_set_huge(pmd, phys_addr, prot);
@@ -371,7 +371,7 @@ static void vunmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
next = pmd_addr_end(addr, end);
cleared = pmd_clear_huge(pmd);
- if (cleared || pmd_bad(*pmd))
+ if (cleared || pmd_bad(pmdp_get(pmd)))
*mask |= PGTBL_PMD_MODIFIED;
if (cleared)
@@ -776,11 +776,11 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
return NULL;
pmd = pmd_offset(pud, addr);
- if (pmd_none(*pmd))
+ if (pmd_none(pmdp_get(pmd)))
return NULL;
- if (pmd_leaf(*pmd))
- return pmd_page(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
- if (WARN_ON_ONCE(pmd_bad(*pmd)))
+ if (pmd_leaf(pmdp_get(pmd)))
+ return pmd_page(pmdp_get(pmd)) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+ if (WARN_ON_ONCE(pmd_bad(pmdp_get(pmd))))
return NULL;
ptep = pte_offset_kernel(pmd, addr);
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/7] mm: Use pudp_get() for accessing PUD entries
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
` (3 preceding siblings ...)
2024-09-13 8:44 ` [PATCH 4/7] mm: Use pmdp_get() for accessing PMD entries Anshuman Khandual
@ 2024-09-13 8:44 ` Anshuman Khandual
2024-09-13 8:44 ` [PATCH 6/7] mm: Use p4dp_get() for accessing P4D entries Anshuman Khandual
2024-09-13 8:44 ` [PATCH 7/7] mm: Use pgdp_get() for accessing PGD entries Anshuman Khandual
6 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Dimitri Sivanich, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Jérôme Glisse, Muchun Song,
Andrey Ryabinin, Miaohe Lin, Naoya Horiguchi, Pasha Tatashin
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=a, Size: 17378 bytes --]
Convert PUD accesses via pudp_get() helper that defaults as READ_ONCE() but
also provides the platform an opportunity to override when required.
Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: "Jérôme Glisse" <jglisse@redhat.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-perf-users@vger.kernel.org
Cc: kasan-dev@googlegroups.com
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
drivers/misc/sgi-gru/grufault.c | 2 +-
include/linux/huge_mm.h | 2 +-
include/linux/mm.h | 2 +-
include/linux/pgtable.h | 10 +++++-----
kernel/events/core.c | 2 +-
mm/gup.c | 12 ++++++------
mm/hmm.c | 2 +-
mm/huge_memory.c | 16 ++++++++--------
mm/hugetlb.c | 6 +++---
mm/kasan/init.c | 10 +++++-----
mm/kasan/shadow.c | 4 ++--
mm/mapping_dirty_helpers.c | 2 +-
mm/memory-failure.c | 4 ++--
mm/memory.c | 10 +++++-----
mm/page_table_check.c | 2 +-
mm/page_vma_mapped.c | 2 +-
mm/pgalloc-track.h | 2 +-
mm/pgtable-generic.c | 2 +-
mm/ptdump.c | 4 ++--
19 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index f3d6249b7dfb..0a06ec92f090 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -220,7 +220,7 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
goto err;
pudp = pud_offset(p4dp, vaddr);
- if (unlikely(pud_none(*pudp)))
+ if (unlikely(pud_none(pudp_get(pudp))))
goto err;
pmdp = pmd_offset(pudp, vaddr);
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 351d6c72af9e..17ee222e4004 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -378,7 +378,7 @@ static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
static inline spinlock_t *pud_trans_huge_lock(pud_t *pud,
struct vm_area_struct *vma)
{
- if (pud_trans_huge(*pud) || pud_devmap(*pud))
+ if (pud_trans_huge(pudp_get(pud)) || pud_devmap(pudp_get(pud)))
return __pud_trans_huge_lock(pud, vma);
else
return NULL;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 258e49323306..1bb1599b5779 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2832,7 +2832,7 @@ static inline pud_t *pud_alloc(struct mm_struct *mm, p4d_t *p4d,
static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
{
- return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))?
+ return (unlikely(pud_none(pudp_get(pud))) && __pmd_alloc(mm, pud, address)) ?
NULL: pmd_offset(pud, address);
}
#endif /* CONFIG_MMU */
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 188a183205b3..b25a0a505ce6 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -611,7 +611,7 @@ static inline pud_t pudp_huge_get_and_clear(struct mm_struct *mm,
unsigned long address,
pud_t *pudp)
{
- pud_t pud = *pudp;
+ pud_t pud = pudp_get(pudp);
pud_clear(pudp);
page_table_check_pud_clear(mm, pud);
@@ -893,7 +893,7 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
static inline void pudp_set_wrprotect(struct mm_struct *mm,
unsigned long address, pud_t *pudp)
{
- pud_t old_pud = *pudp;
+ pud_t old_pud = pudp_get(pudp);
set_pud_at(mm, address, pudp, pud_wrprotect(old_pud));
}
@@ -1072,7 +1072,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
#define set_pud_safe(pudp, pud) \
({ \
- WARN_ON_ONCE(pud_present(*pudp) && !pud_same(*pudp, pud)); \
+ WARN_ON_ONCE(pud_present(pudp_get(pudp)) && !pud_same(pudp_get(pudp), pud)); \
set_pud(pudp, pud); \
})
@@ -1259,9 +1259,9 @@ static inline int p4d_none_or_clear_bad(p4d_t *p4d)
static inline int pud_none_or_clear_bad(pud_t *pud)
{
- if (pud_none(*pud))
+ if (pud_none(pudp_get(pud)))
return 1;
- if (unlikely(pud_bad(*pud))) {
+ if (unlikely(pud_bad(pudp_get(pud)))) {
pud_clear_bad(pud);
return 1;
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 8a6c6bbcd658..35e2f2789246 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7619,7 +7619,7 @@ static u64 perf_get_pgtable_size(struct mm_struct *mm, unsigned long addr)
return p4d_leaf_size(p4d);
pudp = pud_offset_lockless(p4dp, p4d, addr);
- pud = READ_ONCE(*pudp);
+ pud = pudp_get(pudp);
if (!pud_present(pud))
return 0;
diff --git a/mm/gup.c b/mm/gup.c
index aeeac0a54944..300fc7eb306c 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -606,7 +606,7 @@ static struct page *follow_huge_pud(struct vm_area_struct *vma,
{
struct mm_struct *mm = vma->vm_mm;
struct page *page;
- pud_t pud = *pudp;
+ pud_t pud = pudp_get(pudp);
unsigned long pfn = pud_pfn(pud);
int ret;
@@ -989,7 +989,7 @@ static struct page *follow_pud_mask(struct vm_area_struct *vma,
struct mm_struct *mm = vma->vm_mm;
pudp = pud_offset(p4dp, address);
- pud = READ_ONCE(*pudp);
+ pud = pudp_get(pudp);
if (!pud_present(pud))
return no_page_table(vma, flags, address);
if (pud_leaf(pud)) {
@@ -1117,7 +1117,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
if (p4d_none(*p4d))
return -EFAULT;
pud = pud_offset(p4d, address);
- if (pud_none(*pud))
+ if (pud_none(pudp_get(pud)))
return -EFAULT;
pmd = pmd_offset(pud, address);
if (!pmd_present(pmdp_get(pmd)))
@@ -3025,7 +3025,7 @@ static int gup_fast_devmap_pud_leaf(pud_t orig, pud_t *pudp, unsigned long addr,
if (!gup_fast_devmap_leaf(fault_pfn, addr, end, flags, pages, nr))
return 0;
- if (unlikely(pud_val(orig) != pud_val(*pudp))) {
+ if (unlikely(pud_val(orig) != pud_val(pudp_get(pudp)))) {
gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
return 0;
}
@@ -3118,7 +3118,7 @@ static int gup_fast_pud_leaf(pud_t orig, pud_t *pudp, unsigned long addr,
if (!folio)
return 0;
- if (unlikely(pud_val(orig) != pud_val(*pudp))) {
+ if (unlikely(pud_val(orig) != pud_val(pudp_get(pudp)))) {
gup_put_folio(folio, refs, flags);
return 0;
}
@@ -3219,7 +3219,7 @@ static int gup_fast_pud_range(p4d_t *p4dp, p4d_t p4d, unsigned long addr,
pudp = pud_offset_lockless(p4dp, p4d, addr);
do {
- pud_t pud = READ_ONCE(*pudp);
+ pud_t pud = pudp_get(pudp);
next = pud_addr_end(addr, end);
if (unlikely(!pud_present(pud)))
diff --git a/mm/hmm.c b/mm/hmm.c
index 7e0229ae4a5a..c1b093d670b8 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -423,7 +423,7 @@ static int hmm_vma_walk_pud(pud_t *pudp, unsigned long start, unsigned long end,
/* Normally we don't want to split the huge page */
walk->action = ACTION_CONTINUE;
- pud = READ_ONCE(*pudp);
+ pud = pudp_get(pudp);
if (!pud_present(pud)) {
spin_unlock(ptl);
return hmm_vma_walk_hole(start, end, -1, walk);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 3545142a5dc9..994babaca75f 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1247,13 +1247,13 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
spinlock_t *ptl;
ptl = pud_lock(mm, pud);
- if (!pud_none(*pud)) {
+ if (!pud_none(pudp_get(pud))) {
if (write) {
- if (pud_pfn(*pud) != pfn_t_to_pfn(pfn)) {
- WARN_ON_ONCE(!is_huge_zero_pud(*pud));
+ if (pud_pfn(pudp_get(pud)) != pfn_t_to_pfn(pfn)) {
+ WARN_ON_ONCE(!is_huge_zero_pud(pudp_get(pud)));
goto out_unlock;
}
- entry = pud_mkyoung(*pud);
+ entry = pud_mkyoung(pudp_get(pud));
entry = maybe_pud_mkwrite(pud_mkdirty(entry), vma);
if (pudp_set_access_flags(vma, addr, pud, entry, 1))
update_mmu_cache_pud(vma, addr, pud);
@@ -1475,7 +1475,7 @@ void touch_pud(struct vm_area_struct *vma, unsigned long addr,
{
pud_t _pud;
- _pud = pud_mkyoung(*pud);
+ _pud = pud_mkyoung(pudp_get(pud));
if (write)
_pud = pud_mkdirty(_pud);
if (pudp_set_access_flags(vma, addr & HPAGE_PUD_MASK,
@@ -2284,7 +2284,7 @@ spinlock_t *__pud_trans_huge_lock(pud_t *pud, struct vm_area_struct *vma)
spinlock_t *ptl;
ptl = pud_lock(vma->vm_mm, pud);
- if (likely(pud_trans_huge(*pud) || pud_devmap(*pud)))
+ if (likely(pud_trans_huge(pudp_get(pud)) || pud_devmap(pudp_get(pud))))
return ptl;
spin_unlock(ptl);
return NULL;
@@ -2318,7 +2318,7 @@ static void __split_huge_pud_locked(struct vm_area_struct *vma, pud_t *pud,
VM_BUG_ON(haddr & ~HPAGE_PUD_MASK);
VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PUD_SIZE, vma);
- VM_BUG_ON(!pud_trans_huge(*pud) && !pud_devmap(*pud));
+ VM_BUG_ON(!pud_trans_huge(pudp_get(pud)) && !pud_devmap(pudp_get(pud)));
count_vm_event(THP_SPLIT_PUD);
@@ -2336,7 +2336,7 @@ void __split_huge_pud(struct vm_area_struct *vma, pud_t *pud,
(address & HPAGE_PUD_MASK) + HPAGE_PUD_SIZE);
mmu_notifier_invalidate_range_start(&range);
ptl = pud_lock(vma->vm_mm, pud);
- if (unlikely(!pud_trans_huge(*pud) && !pud_devmap(*pud)))
+ if (unlikely(!pud_trans_huge(pudp_get(pud)) && !pud_devmap(pudp_get(pud))))
goto out;
__split_huge_pud_locked(vma, pud, range.start);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index aaf508be0a2b..a3820242b01e 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7328,7 +7328,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
goto out;
spin_lock(&mm->page_table_lock);
- if (pud_none(*pud)) {
+ if (pud_none(pudp_get(pud))) {
pud_populate(mm, pud,
(pmd_t *)((unsigned long)spte & PAGE_MASK));
mm_inc_nr_pmds(mm);
@@ -7417,7 +7417,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
pte = (pte_t *)pud;
} else {
BUG_ON(sz != PMD_SIZE);
- if (want_pmd_share(vma, addr) && pud_none(*pud))
+ if (want_pmd_share(vma, addr) && pud_none(pudp_get(pud)))
pte = huge_pmd_share(mm, vma, addr, pud);
else
pte = (pte_t *)pmd_alloc(mm, pud, addr);
@@ -7461,7 +7461,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
if (sz == PUD_SIZE)
/* must be pud huge, non-present or none */
return (pte_t *)pud;
- if (!pud_present(*pud))
+ if (!pud_present(pudp_get(pud)))
return NULL;
/* must have a valid entry and size to go further */
diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index 4418bcdcb2aa..f4cf519443e1 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -162,7 +162,7 @@ static int __ref zero_pud_populate(p4d_t *p4d, unsigned long addr,
continue;
}
- if (pud_none(*pud)) {
+ if (pud_none(pudp_get(pud))) {
pmd_t *p;
if (slab_is_available()) {
@@ -315,7 +315,7 @@ static void kasan_free_pmd(pmd_t *pmd_start, pud_t *pud)
return;
}
- pmd_free(&init_mm, (pmd_t *)page_to_virt(pud_page(*pud)));
+ pmd_free(&init_mm, (pmd_t *)page_to_virt(pud_page(pudp_get(pud))));
pud_clear(pud);
}
@@ -326,7 +326,7 @@ static void kasan_free_pud(pud_t *pud_start, p4d_t *p4d)
for (i = 0; i < PTRS_PER_PUD; i++) {
pud = pud_start + i;
- if (!pud_none(*pud))
+ if (!pud_none(pudp_get(pud)))
return;
}
@@ -407,10 +407,10 @@ static void kasan_remove_pud_table(pud_t *pud, unsigned long addr,
next = pud_addr_end(addr, end);
- if (!pud_present(*pud))
+ if (!pud_present(pudp_get(pud)))
continue;
- if (kasan_pmd_table(*pud)) {
+ if (kasan_pmd_table(pudp_get(pud))) {
if (IS_ALIGNED(addr, PUD_SIZE) &&
IS_ALIGNED(next, PUD_SIZE)) {
pud_clear(pud);
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index aec16a7236f7..dbd8164c75f1 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -197,9 +197,9 @@ static bool shadow_mapped(unsigned long addr)
if (p4d_none(*p4d))
return false;
pud = pud_offset(p4d, addr);
- if (pud_none(*pud))
+ if (pud_none(pudp_get(pud)))
return false;
- if (pud_leaf(*pud))
+ if (pud_leaf(pudp_get(pud)))
return true;
pmd = pmd_offset(pud, addr);
if (pmd_none(pmdp_get(pmd)))
diff --git a/mm/mapping_dirty_helpers.c b/mm/mapping_dirty_helpers.c
index 2f8829b3541a..c556cc4e3480 100644
--- a/mm/mapping_dirty_helpers.c
+++ b/mm/mapping_dirty_helpers.c
@@ -149,7 +149,7 @@ static int wp_clean_pud_entry(pud_t *pud, unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
- pud_t pudval = READ_ONCE(*pud);
+ pud_t pudval = pudp_get(pud);
/* Do not split a huge pud */
if (pud_trans_huge(pudval) || pud_devmap(pudval)) {
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 305dbef3cc4d..fbb63401fb51 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -417,9 +417,9 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
if (!p4d_present(*p4d))
return 0;
pud = pud_offset(p4d, address);
- if (!pud_present(*pud))
+ if (!pud_present(pudp_get(pud)))
return 0;
- if (pud_devmap(*pud))
+ if (pud_devmap(pudp_get(pud)))
return PUD_SHIFT;
pmd = pmd_offset(pud, address);
if (!pmd_present(pmdp_get(pmd)))
diff --git a/mm/memory.c b/mm/memory.c
index 43953a6d350f..af6c9346493c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1753,7 +1753,7 @@ static inline unsigned long zap_pud_range(struct mmu_gather *tlb,
pud = pud_offset(p4d, addr);
do {
next = pud_addr_end(addr, end);
- if (pud_trans_huge(*pud) || pud_devmap(*pud)) {
+ if (pud_trans_huge(pudp_get(pud)) || pud_devmap(pudp_get(pud))) {
if (next - addr != HPAGE_PUD_SIZE) {
mmap_assert_locked(tlb->mm);
split_huge_pud(vma, pud, addr);
@@ -2819,7 +2819,7 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
unsigned long next;
int err = 0;
- BUG_ON(pud_leaf(*pud));
+ BUG_ON(pud_leaf(pudp_get(pud)));
if (create) {
pmd = pmd_alloc_track(mm, pud, addr, mask);
@@ -2866,11 +2866,11 @@ static int apply_to_pud_range(struct mm_struct *mm, p4d_t *p4d,
}
do {
next = pud_addr_end(addr, end);
- if (pud_none(*pud) && !create)
+ if (pud_none(pudp_get(pud)) && !create)
continue;
- if (WARN_ON_ONCE(pud_leaf(*pud)))
+ if (WARN_ON_ONCE(pud_leaf(pudp_get(pud))))
return -EINVAL;
- if (!pud_none(*pud) && WARN_ON_ONCE(pud_bad(*pud))) {
+ if (!pud_none(pudp_get(pud)) && WARN_ON_ONCE(pud_bad(pudp_get(pud)))) {
if (!create)
continue;
pud_clear_bad(pud);
diff --git a/mm/page_table_check.c b/mm/page_table_check.c
index 48a2cf56c80e..2a22d098b0b1 100644
--- a/mm/page_table_check.c
+++ b/mm/page_table_check.c
@@ -254,7 +254,7 @@ void __page_table_check_pud_set(struct mm_struct *mm, pud_t *pudp, pud_t pud)
if (&init_mm == mm)
return;
- __page_table_check_pud_clear(mm, *pudp);
+ __page_table_check_pud_clear(mm, pudp_get(pudp));
if (pud_user_accessible_page(pud)) {
page_table_check_set(pud_pfn(pud), PUD_SIZE >> PAGE_SHIFT,
pud_write(pud));
diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
index ae5cc42aa208..511266307771 100644
--- a/mm/page_vma_mapped.c
+++ b/mm/page_vma_mapped.c
@@ -222,7 +222,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
continue;
}
pud = pud_offset(p4d, pvmw->address);
- if (!pud_present(*pud)) {
+ if (!pud_present(pudp_get(pud))) {
step_forward(pvmw, PUD_SIZE);
continue;
}
diff --git a/mm/pgalloc-track.h b/mm/pgalloc-track.h
index e9e879de8649..0f6b809431a3 100644
--- a/mm/pgalloc-track.h
+++ b/mm/pgalloc-track.h
@@ -33,7 +33,7 @@ static inline pmd_t *pmd_alloc_track(struct mm_struct *mm, pud_t *pud,
unsigned long address,
pgtbl_mod_mask *mod_mask)
{
- if (unlikely(pud_none(*pud))) {
+ if (unlikely(pud_none(pudp_get(pud)))) {
if (__pmd_alloc(mm, pud, address))
return NULL;
*mod_mask |= PGTBL_PUD_MODIFIED;
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index a5045d0fc73e..5bd02c6208e7 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -153,7 +153,7 @@ pud_t pudp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address,
pud_t pud;
VM_BUG_ON(address & ~HPAGE_PUD_MASK);
- VM_BUG_ON(!pud_trans_huge(*pudp) && !pud_devmap(*pudp));
+ VM_BUG_ON(!pud_trans_huge(pudp_get(pudp)) && !pud_devmap(pudp_get(pudp)));
pud = pudp_huge_get_and_clear(vma->vm_mm, address, pudp);
flush_pud_tlb_range(vma, address, address + HPAGE_PUD_SIZE);
return pud;
diff --git a/mm/ptdump.c b/mm/ptdump.c
index e17588a32012..32ae8e829329 100644
--- a/mm/ptdump.c
+++ b/mm/ptdump.c
@@ -30,7 +30,7 @@ static int ptdump_pgd_entry(pgd_t *pgd, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
struct ptdump_state *st = walk->private;
- pgd_t val = READ_ONCE(*pgd);
+ pgd_t val = pgdp_get(pgd);
#if CONFIG_PGTABLE_LEVELS > 4 && \
(defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS))
@@ -76,7 +76,7 @@ static int ptdump_pud_entry(pud_t *pud, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
struct ptdump_state *st = walk->private;
- pud_t val = READ_ONCE(*pud);
+ pud_t val = pudp_get(pud);
#if CONFIG_PGTABLE_LEVELS > 2 && \
(defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS))
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/7] mm: Use p4dp_get() for accessing P4D entries
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
` (4 preceding siblings ...)
2024-09-13 8:44 ` [PATCH 5/7] mm: Use pudp_get() for accessing PUD entries Anshuman Khandual
@ 2024-09-13 8:44 ` Anshuman Khandual
2024-09-13 8:44 ` [PATCH 7/7] mm: Use pgdp_get() for accessing PGD entries Anshuman Khandual
6 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Dimitri Sivanich, Alexander Viro, Muchun Song, Andrey Ryabinin,
Miaohe Lin, Dennis Zhou, Tejun Heo, Christoph Lameter,
Uladzislau Rezki, Christoph Hellwig
Convert P4D accesses via p4dp_get() helper that defaults as READ_ONCE() but
also provides the platform an opportunity to override when required.
Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
cc: Christoph Lameter <cl@linux.com>
Cc: Uladzislau Rezki <urezki@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-perf-users@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: kasan-dev@googlegroups.com
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
drivers/misc/sgi-gru/grufault.c | 2 +-
fs/userfaultfd.c | 4 ++--
include/linux/pgtable.h | 6 +++---
kernel/events/core.c | 2 +-
mm/gup.c | 6 +++---
mm/hugetlb.c | 2 +-
mm/kasan/init.c | 10 +++++-----
mm/kasan/shadow.c | 2 +-
mm/memory-failure.c | 2 +-
mm/memory.c | 14 +++++++-------
mm/page_vma_mapped.c | 2 +-
mm/pagewalk.c | 6 +++---
mm/percpu.c | 4 ++--
mm/pgalloc-track.h | 2 +-
mm/pgtable-generic.c | 4 ++--
mm/ptdump.c | 2 +-
mm/rmap.c | 4 ++--
mm/sparse-vmemmap.c | 4 ++--
mm/vmalloc.c | 24 ++++++++++++------------
mm/vmscan.c | 6 +++---
20 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 0a06ec92f090..cdca93398b44 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -216,7 +216,7 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
goto err;
p4dp = p4d_offset(pgdp, vaddr);
- if (unlikely(p4d_none(*p4dp)))
+ if (unlikely(p4d_none(p4dp_get(p4dp))))
goto err;
pudp = pud_offset(p4dp, vaddr);
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 27a3e9285fbf..4044e15cdfd9 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -307,10 +307,10 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
if (!pgd_present(*pgd))
goto out;
p4d = p4d_offset(pgd, address);
- if (!p4d_present(*p4d))
+ if (!p4d_present(p4dp_get(p4d)))
goto out;
pud = pud_offset(p4d, address);
- if (!pud_present(*pud))
+ if (!pud_present(pudp_get(pud)))
goto out;
pmd = pmd_offset(pud, address);
again:
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index b25a0a505ce6..b3e40f06c8c4 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1078,7 +1078,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
#define set_p4d_safe(p4dp, p4d) \
({ \
- WARN_ON_ONCE(p4d_present(*p4dp) && !p4d_same(*p4dp, p4d)); \
+ WARN_ON_ONCE(p4d_present(p4dp_get(p4dp)) && !p4d_same(p4dp_get(p4dp), p4d)); \
set_p4d(p4dp, p4d); \
})
@@ -1248,9 +1248,9 @@ static inline int pgd_none_or_clear_bad(pgd_t *pgd)
static inline int p4d_none_or_clear_bad(p4d_t *p4d)
{
- if (p4d_none(*p4d))
+ if (p4d_none(p4dp_get(p4d)))
return 1;
- if (unlikely(p4d_bad(*p4d))) {
+ if (unlikely(p4d_bad(p4dp_get(p4d)))) {
p4d_clear_bad(p4d);
return 1;
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 35e2f2789246..4e56a276ed25 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7611,7 +7611,7 @@ static u64 perf_get_pgtable_size(struct mm_struct *mm, unsigned long addr)
return pgd_leaf_size(pgd);
p4dp = p4d_offset_lockless(pgdp, pgd, addr);
- p4d = READ_ONCE(*p4dp);
+ p4d = p4dp_get(p4dp);
if (!p4d_present(p4d))
return 0;
diff --git a/mm/gup.c b/mm/gup.c
index 300fc7eb306c..3a97d0263052 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1014,7 +1014,7 @@ static struct page *follow_p4d_mask(struct vm_area_struct *vma,
p4d_t *p4dp, p4d;
p4dp = p4d_offset(pgdp, address);
- p4d = READ_ONCE(*p4dp);
+ p4d = p4dp_get(p4dp);
BUILD_BUG_ON(p4d_leaf(p4d));
if (!p4d_present(p4d) || p4d_bad(p4d))
@@ -1114,7 +1114,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
if (pgd_none(*pgd))
return -EFAULT;
p4d = p4d_offset(pgd, address);
- if (p4d_none(*p4d))
+ if (p4d_none(p4dp_get(p4d)))
return -EFAULT;
pud = pud_offset(p4d, address);
if (pud_none(pudp_get(pud)))
@@ -3245,7 +3245,7 @@ static int gup_fast_p4d_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr,
p4dp = p4d_offset_lockless(pgdp, pgd, addr);
do {
- p4d_t p4d = READ_ONCE(*p4dp);
+ p4d_t p4d = p4dp_get(p4dp);
next = p4d_addr_end(addr, end);
if (!p4d_present(p4d))
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index a3820242b01e..4fdb91c8cc2b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7454,7 +7454,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
if (!pgd_present(*pgd))
return NULL;
p4d = p4d_offset(pgd, addr);
- if (!p4d_present(*p4d))
+ if (!p4d_present(p4dp_get(p4d)))
return NULL;
pud = pud_offset(p4d, addr);
diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index f4cf519443e1..02af738fee5e 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -208,7 +208,7 @@ static int __ref zero_p4d_populate(pgd_t *pgd, unsigned long addr,
continue;
}
- if (p4d_none(*p4d)) {
+ if (p4d_none(p4dp_get(p4d))) {
pud_t *p;
if (slab_is_available()) {
@@ -330,7 +330,7 @@ static void kasan_free_pud(pud_t *pud_start, p4d_t *p4d)
return;
}
- pud_free(&init_mm, (pud_t *)page_to_virt(p4d_page(*p4d)));
+ pud_free(&init_mm, (pud_t *)page_to_virt(p4d_page(p4dp_get(p4d))));
p4d_clear(p4d);
}
@@ -341,7 +341,7 @@ static void kasan_free_p4d(p4d_t *p4d_start, pgd_t *pgd)
for (i = 0; i < PTRS_PER_P4D; i++) {
p4d = p4d_start + i;
- if (!p4d_none(*p4d))
+ if (!p4d_none(p4dp_get(p4d)))
return;
}
@@ -434,10 +434,10 @@ static void kasan_remove_p4d_table(p4d_t *p4d, unsigned long addr,
next = p4d_addr_end(addr, end);
- if (!p4d_present(*p4d))
+ if (!p4d_present(p4dp_get(p4d)))
continue;
- if (kasan_pud_table(*p4d)) {
+ if (kasan_pud_table(p4dp_get(p4d))) {
if (IS_ALIGNED(addr, P4D_SIZE) &&
IS_ALIGNED(next, P4D_SIZE)) {
p4d_clear(p4d);
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index dbd8164c75f1..52150cc5ae5f 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -194,7 +194,7 @@ static bool shadow_mapped(unsigned long addr)
if (pgd_none(*pgd))
return false;
p4d = p4d_offset(pgd, addr);
- if (p4d_none(*p4d))
+ if (p4d_none(p4dp_get(p4d)))
return false;
pud = pud_offset(p4d, addr);
if (pud_none(pudp_get(pud)))
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index fbb63401fb51..3d900cc039b3 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -414,7 +414,7 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
if (!pgd_present(*pgd))
return 0;
p4d = p4d_offset(pgd, address);
- if (!p4d_present(*p4d))
+ if (!p4d_present(p4dp_get(p4d)))
return 0;
pud = pud_offset(p4d, address);
if (!pud_present(pudp_get(pud)))
diff --git a/mm/memory.c b/mm/memory.c
index af6c9346493c..7e6bb051d187 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2902,11 +2902,11 @@ static int apply_to_p4d_range(struct mm_struct *mm, pgd_t *pgd,
}
do {
next = p4d_addr_end(addr, end);
- if (p4d_none(*p4d) && !create)
+ if (p4d_none(p4dp_get(p4d)) && !create)
continue;
- if (WARN_ON_ONCE(p4d_leaf(*p4d)))
+ if (WARN_ON_ONCE(p4d_leaf(p4dp_get(p4d))))
return -EINVAL;
- if (!p4d_none(*p4d) && WARN_ON_ONCE(p4d_bad(*p4d))) {
+ if (!p4d_none(p4dp_get(p4d)) && WARN_ON_ONCE(p4d_bad(p4dp_get(p4d)))) {
if (!create)
continue;
p4d_clear_bad(p4d);
@@ -6058,7 +6058,7 @@ int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address)
return -ENOMEM;
spin_lock(&mm->page_table_lock);
- if (!p4d_present(*p4d)) {
+ if (!p4d_present(p4dp_get(p4d))) {
mm_inc_nr_puds(mm);
smp_wmb(); /* See comment in pmd_install() */
p4d_populate(mm, p4d, new);
@@ -6082,7 +6082,7 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
return -ENOMEM;
ptl = pud_lock(mm, pud);
- if (!pud_present(*pud)) {
+ if (!pud_present(pudp_get(pud))) {
mm_inc_nr_pmds(mm);
smp_wmb(); /* See comment in pmd_install() */
pud_populate(mm, pud, new);
@@ -6143,11 +6143,11 @@ int follow_pte(struct vm_area_struct *vma, unsigned long address,
goto out;
p4d = p4d_offset(pgd, address);
- if (p4d_none(*p4d) || unlikely(p4d_bad(*p4d)))
+ if (p4d_none(p4dp_get(p4d)) || unlikely(p4d_bad(p4dp_get(p4d))))
goto out;
pud = pud_offset(p4d, address);
- if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+ if (pud_none(pudp_get(pud)) || unlikely(pud_bad(pudp_get(pud))))
goto out;
pmd = pmd_offset(pud, address);
diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
index 511266307771..a33f92db2666 100644
--- a/mm/page_vma_mapped.c
+++ b/mm/page_vma_mapped.c
@@ -217,7 +217,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
continue;
}
p4d = p4d_offset(pgd, pvmw->address);
- if (!p4d_present(*p4d)) {
+ if (!p4d_present(p4dp_get(p4d))) {
step_forward(pvmw, P4D_SIZE);
continue;
}
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index c3019a160e77..1d32c6da1a0d 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -145,7 +145,7 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
do {
again:
next = pud_addr_end(addr, end);
- if (pud_none(*pud)) {
+ if (pud_none(pudp_get(pud))) {
if (ops->pte_hole)
err = ops->pte_hole(addr, next, depth, walk);
if (err)
@@ -163,14 +163,14 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
if (walk->action == ACTION_AGAIN)
goto again;
- if ((!walk->vma && (pud_leaf(*pud) || !pud_present(*pud))) ||
+ if ((!walk->vma && (pud_leaf(pudp_get(pud)) || !pud_present(pudp_get(pud)))) ||
walk->action == ACTION_CONTINUE ||
!(ops->pmd_entry || ops->pte_entry))
continue;
if (walk->vma)
split_huge_pud(walk->vma, pud, addr);
- if (pud_none(*pud))
+ if (pud_none(pudp_get(pud)))
goto again;
err = walk_pmd_range(pud, addr, next, walk);
diff --git a/mm/percpu.c b/mm/percpu.c
index 7ee77c0fd5e3..58660e8eb892 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -3192,7 +3192,7 @@ void __init __weak pcpu_populate_pte(unsigned long addr)
}
p4d = p4d_offset(pgd, addr);
- if (p4d_none(*p4d)) {
+ if (p4d_none(p4dp_get(p4d))) {
pud = memblock_alloc(PUD_TABLE_SIZE, PUD_TABLE_SIZE);
if (!pud)
goto err_alloc;
@@ -3200,7 +3200,7 @@ void __init __weak pcpu_populate_pte(unsigned long addr)
}
pud = pud_offset(p4d, addr);
- if (pud_none(*pud)) {
+ if (pud_none(pudp_get(pud))) {
pmd = memblock_alloc(PMD_TABLE_SIZE, PMD_TABLE_SIZE);
if (!pmd)
goto err_alloc;
diff --git a/mm/pgalloc-track.h b/mm/pgalloc-track.h
index 0f6b809431a3..3db8ccbcb141 100644
--- a/mm/pgalloc-track.h
+++ b/mm/pgalloc-track.h
@@ -20,7 +20,7 @@ static inline pud_t *pud_alloc_track(struct mm_struct *mm, p4d_t *p4d,
unsigned long address,
pgtbl_mod_mask *mod_mask)
{
- if (unlikely(p4d_none(*p4d))) {
+ if (unlikely(p4d_none(p4dp_get(p4d)))) {
if (__pud_alloc(mm, p4d, address))
return NULL;
*mod_mask |= PGTBL_P4D_MODIFIED;
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index 5bd02c6208e7..7e0a4974b0fc 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -31,7 +31,7 @@ void pgd_clear_bad(pgd_t *pgd)
#ifndef __PAGETABLE_P4D_FOLDED
void p4d_clear_bad(p4d_t *p4d)
{
- p4d_ERROR(*p4d);
+ p4d_ERROR(p4dp_get(p4d));
p4d_clear(p4d);
}
#endif
@@ -39,7 +39,7 @@ void p4d_clear_bad(p4d_t *p4d)
#ifndef __PAGETABLE_PUD_FOLDED
void pud_clear_bad(pud_t *pud)
{
- pud_ERROR(*pud);
+ pud_ERROR(pudp_get(pud));
pud_clear(pud);
}
#endif
diff --git a/mm/ptdump.c b/mm/ptdump.c
index 32ae8e829329..2c40224b8ad0 100644
--- a/mm/ptdump.c
+++ b/mm/ptdump.c
@@ -53,7 +53,7 @@ static int ptdump_p4d_entry(p4d_t *p4d, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
struct ptdump_state *st = walk->private;
- p4d_t val = READ_ONCE(*p4d);
+ p4d_t val = p4dp_get(p4d);
#if CONFIG_PGTABLE_LEVELS > 3 && \
(defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS))
diff --git a/mm/rmap.c b/mm/rmap.c
index ec668c48bccc..829d0cf5e384 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -813,11 +813,11 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
goto out;
p4d = p4d_offset(pgd, address);
- if (!p4d_present(*p4d))
+ if (!p4d_present(p4dp_get(p4d)))
goto out;
pud = pud_offset(p4d, address);
- if (!pud_present(*pud))
+ if (!pud_present(pudp_get(pud)))
goto out;
pmd = pmd_offset(pud, address);
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index c89706e107ce..2bd1c95f107a 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -203,7 +203,7 @@ void __weak __meminit pmd_init(void *addr)
pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node)
{
pud_t *pud = pud_offset(p4d, addr);
- if (pud_none(*pud)) {
+ if (pud_none(pudp_get(pud))) {
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
if (!p)
return NULL;
@@ -220,7 +220,7 @@ void __weak __meminit pud_init(void *addr)
p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node)
{
p4d_t *p4d = p4d_offset(pgd, addr);
- if (p4d_none(*p4d)) {
+ if (p4d_none(p4dp_get(p4d))) {
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
if (!p)
return NULL;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d27aa1ebaad6..c67b067f4686 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -200,7 +200,7 @@ static int vmap_try_huge_pud(pud_t *pud, unsigned long addr, unsigned long end,
if (!IS_ALIGNED(phys_addr, PUD_SIZE))
return 0;
- if (pud_present(*pud) && !pud_free_pmd_page(pud, addr))
+ if (pud_present(pudp_get(pud)) && !pud_free_pmd_page(pud, addr))
return 0;
return pud_set_huge(pud, phys_addr, prot);
@@ -251,7 +251,7 @@ static int vmap_try_huge_p4d(p4d_t *p4d, unsigned long addr, unsigned long end,
if (!IS_ALIGNED(phys_addr, P4D_SIZE))
return 0;
- if (p4d_present(*p4d) && !p4d_free_pud_page(p4d, addr))
+ if (p4d_present(p4dp_get(p4d)) && !p4d_free_pud_page(p4d, addr))
return 0;
return p4d_set_huge(p4d, phys_addr, prot);
@@ -396,7 +396,7 @@ static void vunmap_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
next = pud_addr_end(addr, end);
cleared = pud_clear_huge(pud);
- if (cleared || pud_bad(*pud))
+ if (cleared || pud_bad(pudp_get(pud)))
*mask |= PGTBL_PUD_MODIFIED;
if (cleared)
@@ -418,7 +418,7 @@ static void vunmap_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
next = p4d_addr_end(addr, end);
p4d_clear_huge(p4d);
- if (p4d_bad(*p4d))
+ if (p4d_bad(p4dp_get(p4d)))
*mask |= PGTBL_P4D_MODIFIED;
if (p4d_none_or_clear_bad(p4d))
@@ -760,19 +760,19 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
return NULL;
p4d = p4d_offset(pgd, addr);
- if (p4d_none(*p4d))
+ if (p4d_none(p4dp_get(p4d)))
return NULL;
- if (p4d_leaf(*p4d))
- return p4d_page(*p4d) + ((addr & ~P4D_MASK) >> PAGE_SHIFT);
- if (WARN_ON_ONCE(p4d_bad(*p4d)))
+ if (p4d_leaf(p4dp_get(p4d)))
+ return p4d_page(p4dp_get(p4d)) + ((addr & ~P4D_MASK) >> PAGE_SHIFT);
+ if (WARN_ON_ONCE(p4d_bad(p4dp_get(p4d))))
return NULL;
pud = pud_offset(p4d, addr);
- if (pud_none(*pud))
+ if (pud_none(pudp_get(pud)))
return NULL;
- if (pud_leaf(*pud))
- return pud_page(*pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
- if (WARN_ON_ONCE(pud_bad(*pud)))
+ if (pud_leaf(pudp_get(pud)))
+ return pud_page(pudp_get(pud)) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
+ if (WARN_ON_ONCE(pud_bad(pudp_get(pud))))
return NULL;
pmd = pmd_offset(pud, addr);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index bd489c1af228..b16925b5f072 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3421,7 +3421,7 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area
DEFINE_MAX_SEQ(walk->lruvec);
int old_gen, new_gen = lru_gen_from_seq(max_seq);
- VM_WARN_ON_ONCE(pud_leaf(*pud));
+ VM_WARN_ON_ONCE(pud_leaf(pudp_get(pud)));
/* try to batch at most 1+MIN_LRU_BATCH+1 entries */
if (*first == -1) {
@@ -3501,7 +3501,7 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
struct lru_gen_mm_walk *walk = args->private;
struct lru_gen_mm_state *mm_state = get_mm_state(walk->lruvec);
- VM_WARN_ON_ONCE(pud_leaf(*pud));
+ VM_WARN_ON_ONCE(pud_leaf(pudp_get(pud)));
/*
* Finish an entire PMD in two passes: the first only reaches to PTE
@@ -3579,7 +3579,7 @@ static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
unsigned long next;
struct lru_gen_mm_walk *walk = args->private;
- VM_WARN_ON_ONCE(p4d_leaf(*p4d));
+ VM_WARN_ON_ONCE(p4d_leaf(p4dp_get(p4d)));
pud = pud_offset(p4d, start & P4D_MASK);
restart:
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 7/7] mm: Use pgdp_get() for accessing PGD entries
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
` (5 preceding siblings ...)
2024-09-13 8:44 ` [PATCH 6/7] mm: Use p4dp_get() for accessing P4D entries Anshuman Khandual
@ 2024-09-13 8:44 ` Anshuman Khandual
6 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-13 8:44 UTC (permalink / raw)
To: linux-mm
Cc: Anshuman Khandual, Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Dimitri Sivanich, Alexander Viro, Muchun Song, Andrey Ryabinin,
Miaohe Lin, Dennis Zhou, Tejun Heo, Christoph Lameter,
Uladzislau Rezki, Christoph Hellwig
Convert PGD accesses via pgdp_get() helper that defaults as READ_ONCE() but
also provides the platform an opportunity to override when required.
Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
cc: Christoph Lameter <cl@linux.com>
Cc: Uladzislau Rezki <urezki@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-perf-users@vger.kernel.org
Cc: kasan-dev@googlegroups.com
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
drivers/misc/sgi-gru/grufault.c | 2 +-
fs/userfaultfd.c | 2 +-
include/linux/mm.h | 2 +-
include/linux/pgtable.h | 6 +++---
kernel/events/core.c | 2 +-
mm/gup.c | 8 ++++----
mm/hugetlb.c | 2 +-
mm/kasan/init.c | 8 ++++----
mm/kasan/shadow.c | 2 +-
mm/memory-failure.c | 2 +-
mm/memory.c | 10 +++++-----
mm/page_vma_mapped.c | 2 +-
mm/percpu.c | 2 +-
mm/pgalloc-track.h | 2 +-
mm/pgtable-generic.c | 2 +-
mm/rmap.c | 2 +-
mm/sparse-vmemmap.c | 2 +-
mm/vmalloc.c | 10 +++++-----
18 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index cdca93398b44..2a8a154d8531 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -212,7 +212,7 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
pte_t pte;
pgdp = pgd_offset(vma->vm_mm, vaddr);
- if (unlikely(pgd_none(*pgdp)))
+ if (unlikely(pgd_none(pgdp_get(pgdp))))
goto err;
p4dp = p4d_offset(pgdp, vaddr);
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 4044e15cdfd9..6d33c7a9eb01 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -304,7 +304,7 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
assert_fault_locked(vmf);
pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
+ if (!pgd_present(pgdp_get(pgd)))
goto out;
p4d = p4d_offset(pgd, address);
if (!p4d_present(p4dp_get(p4d)))
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1bb1599b5779..1978a4b1fcf5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2819,7 +2819,7 @@ int __pte_alloc_kernel(pmd_t *pmd);
static inline p4d_t *p4d_alloc(struct mm_struct *mm, pgd_t *pgd,
unsigned long address)
{
- return (unlikely(pgd_none(*pgd)) && __p4d_alloc(mm, pgd, address)) ?
+ return (unlikely(pgd_none(pgdp_get(pgd))) && __p4d_alloc(mm, pgd, address)) ?
NULL : p4d_offset(pgd, address);
}
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index b3e40f06c8c4..19f6557b4bf5 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -1084,7 +1084,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
#define set_pgd_safe(pgdp, pgd) \
({ \
- WARN_ON_ONCE(pgd_present(*pgdp) && !pgd_same(*pgdp, pgd)); \
+ WARN_ON_ONCE(pgd_present(pgdp_get(pgdp)) && !pgd_same(pgdp_get(pgdp), pgd)); \
set_pgd(pgdp, pgd); \
})
@@ -1237,9 +1237,9 @@ void pmd_clear_bad(pmd_t *);
static inline int pgd_none_or_clear_bad(pgd_t *pgd)
{
- if (pgd_none(*pgd))
+ if (pgd_none(pgdp_get(pgd)))
return 1;
- if (unlikely(pgd_bad(*pgd))) {
+ if (unlikely(pgd_bad(pgdp_get(pgd)))) {
pgd_clear_bad(pgd);
return 1;
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 4e56a276ed25..1e3142211cce 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7603,7 +7603,7 @@ static u64 perf_get_pgtable_size(struct mm_struct *mm, unsigned long addr)
pte_t *ptep, pte;
pgdp = pgd_offset(mm, addr);
- pgd = READ_ONCE(*pgdp);
+ pgd = pgdp_get(pgdp);
if (pgd_none(pgd))
return 0;
diff --git a/mm/gup.c b/mm/gup.c
index 3a97d0263052..f43daab23979 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1060,7 +1060,7 @@ static struct page *follow_page_mask(struct vm_area_struct *vma,
ctx->page_mask = 0;
pgd = pgd_offset(mm, address);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+ if (pgd_none(pgdp_get(pgd)) || unlikely(pgd_bad(pgdp_get(pgd))))
page = no_page_table(vma, flags, address);
else
page = follow_p4d_mask(vma, address, pgd, flags, ctx);
@@ -1111,7 +1111,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
pgd = pgd_offset_k(address);
else
pgd = pgd_offset_gate(mm, address);
- if (pgd_none(*pgd))
+ if (pgd_none(pgdp_get(pgd)))
return -EFAULT;
p4d = p4d_offset(pgd, address);
if (p4d_none(p4dp_get(p4d)))
@@ -3158,7 +3158,7 @@ static int gup_fast_pgd_leaf(pgd_t orig, pgd_t *pgdp, unsigned long addr,
if (!folio)
return 0;
- if (unlikely(pgd_val(orig) != pgd_val(*pgdp))) {
+ if (unlikely(pgd_val(orig) != pgd_val(pgdp_get(pgdp)))) {
gup_put_folio(folio, refs, flags);
return 0;
}
@@ -3267,7 +3267,7 @@ static void gup_fast_pgd_range(unsigned long addr, unsigned long end,
pgdp = pgd_offset(current->mm, addr);
do {
- pgd_t pgd = READ_ONCE(*pgdp);
+ pgd_t pgd = pgdp_get(pgdp);
next = pgd_addr_end(addr, end);
if (pgd_none(pgd))
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 4fdb91c8cc2b..294d74b03d83 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7451,7 +7451,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
pmd_t *pmd;
pgd = pgd_offset(mm, addr);
- if (!pgd_present(*pgd))
+ if (!pgd_present(pgdp_get(pgd)))
return NULL;
p4d = p4d_offset(pgd, addr);
if (!p4d_present(p4dp_get(p4d)))
diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index 02af738fee5e..c2b307716551 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -271,7 +271,7 @@ int __ref kasan_populate_early_shadow(const void *shadow_start,
continue;
}
- if (pgd_none(*pgd)) {
+ if (pgd_none(pgdp_get(pgd))) {
p4d_t *p;
if (slab_is_available()) {
@@ -345,7 +345,7 @@ static void kasan_free_p4d(p4d_t *p4d_start, pgd_t *pgd)
return;
}
- p4d_free(&init_mm, (p4d_t *)page_to_virt(pgd_page(*pgd)));
+ p4d_free(&init_mm, (p4d_t *)page_to_virt(pgd_page(pgdp_get(pgd))));
pgd_clear(pgd);
}
@@ -468,10 +468,10 @@ void kasan_remove_zero_shadow(void *start, unsigned long size)
next = pgd_addr_end(addr, end);
pgd = pgd_offset_k(addr);
- if (!pgd_present(*pgd))
+ if (!pgd_present(pgdp_get(pgd)))
continue;
- if (kasan_p4d_table(*pgd)) {
+ if (kasan_p4d_table(pgdp_get(pgd))) {
if (IS_ALIGNED(addr, PGDIR_SIZE) &&
IS_ALIGNED(next, PGDIR_SIZE)) {
pgd_clear(pgd);
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 52150cc5ae5f..7f3c46237816 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -191,7 +191,7 @@ static bool shadow_mapped(unsigned long addr)
pmd_t *pmd;
pte_t *pte;
- if (pgd_none(*pgd))
+ if (pgd_none(pgdp_get(pgd)))
return false;
p4d = p4d_offset(pgd, addr);
if (p4d_none(p4dp_get(p4d)))
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 3d900cc039b3..c9397eab52bd 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -411,7 +411,7 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
VM_BUG_ON_VMA(address == -EFAULT, vma);
pgd = pgd_offset(vma->vm_mm, address);
- if (!pgd_present(*pgd))
+ if (!pgd_present(pgdp_get(pgd)))
return 0;
p4d = p4d_offset(pgd, address);
if (!p4d_present(p4dp_get(p4d)))
diff --git a/mm/memory.c b/mm/memory.c
index 7e6bb051d187..7765d30e669f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2936,11 +2936,11 @@ static int __apply_to_page_range(struct mm_struct *mm, unsigned long addr,
pgd = pgd_offset(mm, addr);
do {
next = pgd_addr_end(addr, end);
- if (pgd_none(*pgd) && !create)
+ if (pgd_none(pgdp_get(pgd)) && !create)
continue;
- if (WARN_ON_ONCE(pgd_leaf(*pgd)))
+ if (WARN_ON_ONCE(pgd_leaf(pgdp_get(pgd))))
return -EINVAL;
- if (!pgd_none(*pgd) && WARN_ON_ONCE(pgd_bad(*pgd))) {
+ if (!pgd_none(pgdp_get(pgd)) && WARN_ON_ONCE(pgd_bad(pgdp_get(pgd)))) {
if (!create)
continue;
pgd_clear_bad(pgd);
@@ -6035,7 +6035,7 @@ int __p4d_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
return -ENOMEM;
spin_lock(&mm->page_table_lock);
- if (pgd_present(*pgd)) { /* Another has populated it */
+ if (pgd_present(pgdp_get(pgd))) { /* Another has populated it */
p4d_free(mm, new);
} else {
smp_wmb(); /* See comment in pmd_install() */
@@ -6139,7 +6139,7 @@ int follow_pte(struct vm_area_struct *vma, unsigned long address,
goto out;
pgd = pgd_offset(mm, address);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+ if (pgd_none(pgdp_get(pgd)) || unlikely(pgd_bad(pgdp_get(pgd))))
goto out;
p4d = p4d_offset(pgd, address);
diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
index a33f92db2666..fb8b610f7378 100644
--- a/mm/page_vma_mapped.c
+++ b/mm/page_vma_mapped.c
@@ -212,7 +212,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
restart:
do {
pgd = pgd_offset(mm, pvmw->address);
- if (!pgd_present(*pgd)) {
+ if (!pgd_present(pgdp_get(pgd))) {
step_forward(pvmw, PGDIR_SIZE);
continue;
}
diff --git a/mm/percpu.c b/mm/percpu.c
index 58660e8eb892..70e68ab002e9 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -3184,7 +3184,7 @@ void __init __weak pcpu_populate_pte(unsigned long addr)
pud_t *pud;
pmd_t *pmd;
- if (pgd_none(*pgd)) {
+ if (pgd_none(pgdp_get(pgd))) {
p4d = memblock_alloc(P4D_TABLE_SIZE, P4D_TABLE_SIZE);
if (!p4d)
goto err_alloc;
diff --git a/mm/pgalloc-track.h b/mm/pgalloc-track.h
index 3db8ccbcb141..644f632c7cba 100644
--- a/mm/pgalloc-track.h
+++ b/mm/pgalloc-track.h
@@ -7,7 +7,7 @@ static inline p4d_t *p4d_alloc_track(struct mm_struct *mm, pgd_t *pgd,
unsigned long address,
pgtbl_mod_mask *mod_mask)
{
- if (unlikely(pgd_none(*pgd))) {
+ if (unlikely(pgd_none(pgdp_get(pgd)))) {
if (__p4d_alloc(mm, pgd, address))
return NULL;
*mod_mask |= PGTBL_PGD_MODIFIED;
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index 7e0a4974b0fc..b97eea347a36 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -24,7 +24,7 @@
void pgd_clear_bad(pgd_t *pgd)
{
- pgd_ERROR(*pgd);
+ pgd_ERROR(pgdp_get(pgd));
pgd_clear(pgd);
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 829d0cf5e384..7e2e977efaba 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -809,7 +809,7 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
pmd_t *pmd = NULL;
pgd = pgd_offset(mm, address);
- if (!pgd_present(*pgd))
+ if (!pgd_present(pgdp_get(pgd)))
goto out;
p4d = p4d_offset(pgd, address);
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 2bd1c95f107a..ffc78329a130 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -233,7 +233,7 @@ p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node)
pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)
{
pgd_t *pgd = pgd_offset_k(addr);
- if (pgd_none(*pgd)) {
+ if (pgd_none(pgdp_get(pgd))) {
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
if (!p)
return NULL;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index c67b067f4686..de7a6dd0ab21 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -450,7 +450,7 @@ void __vunmap_range_noflush(unsigned long start, unsigned long end)
pgd = pgd_offset_k(addr);
do {
next = pgd_addr_end(addr, end);
- if (pgd_bad(*pgd))
+ if (pgd_bad(pgdp_get(pgd)))
mask |= PGTBL_PGD_MODIFIED;
if (pgd_none_or_clear_bad(pgd))
continue;
@@ -582,7 +582,7 @@ static int vmap_small_pages_range_noflush(unsigned long addr, unsigned long end,
pgd = pgd_offset_k(addr);
do {
next = pgd_addr_end(addr, end);
- if (pgd_bad(*pgd))
+ if (pgd_bad(pgdp_get(pgd)))
mask |= PGTBL_PGD_MODIFIED;
err = vmap_pages_p4d_range(pgd, addr, next, prot, pages, &nr, &mask);
if (err)
@@ -752,11 +752,11 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
*/
VIRTUAL_BUG_ON(!is_vmalloc_or_module_addr(vmalloc_addr));
- if (pgd_none(*pgd))
+ if (pgd_none(pgdp_get(pgd)))
return NULL;
- if (WARN_ON_ONCE(pgd_leaf(*pgd)))
+ if (WARN_ON_ONCE(pgd_leaf(pgdp_get(pgd))))
return NULL; /* XXX: no allowance for huge pgd */
- if (WARN_ON_ONCE(pgd_bad(*pgd)))
+ if (WARN_ON_ONCE(pgd_bad(pgdp_get(pgd))))
return NULL;
p4d = p4d_offset(pgd, addr);
--
2.25.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 3/7] mm: Use ptep_get() for accessing PTE entries
2024-09-13 8:44 ` [PATCH 3/7] mm: Use ptep_get() for accessing PTE entries Anshuman Khandual
@ 2024-09-13 10:27 ` Ryan Roberts
2024-09-16 3:16 ` Anshuman Khandual
0 siblings, 1 reply; 14+ messages in thread
From: Ryan Roberts @ 2024-09-13 10:27 UTC (permalink / raw)
To: Anshuman Khandual, linux-mm
Cc: Andrew Morton, David Hildenbrand, Mike Rapoport (IBM),
Arnd Bergmann, x86, linux-m68k, linux-fsdevel, kasan-dev,
linux-kernel, linux-perf-users
On 13/09/2024 09:44, Anshuman Khandual wrote:
> Convert PTE accesses via ptep_get() helper that defaults as READ_ONCE() but
> also provides the platform an opportunity to override when required.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Ryan Roberts <ryan.roberts@arm.com>
> Cc: "Mike Rapoport (IBM)" <rppt@kernel.org>
> Cc: linux-mm@kvack.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> include/linux/pgtable.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 2a6a3cccfc36..05e6995c1b93 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -1060,7 +1060,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
> */
> #define set_pte_safe(ptep, pte) \
> ({ \
> - WARN_ON_ONCE(pte_present(*ptep) && !pte_same(*ptep, pte)); \
> + WARN_ON_ONCE(pte_present(ptep_get(ptep)) && !pte_same(ptep_get(ptep), pte)); \
Suggest reading once into a temporary so that the pte can't change between the 2
gets. In practice, it's not likely to be a huge problem for this instance since
its under the PTL so can only be racing with HW update of access and dirty. But
good practice IMHO:
pte_t __old = ptep_get(ptep); \
WARN_ON_ONCE(pte_present(__old) && !pte_same(__old, pte)); \
Thanks,
Ryan
> set_pte(ptep, pte); \
> })
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/7] mm: Use pmdp_get() for accessing PMD entries
2024-09-13 8:44 ` [PATCH 4/7] mm: Use pmdp_get() for accessing PMD entries Anshuman Khandual
@ 2024-09-13 10:38 ` Ryan Roberts
2024-09-16 6:15 ` Anshuman Khandual
0 siblings, 1 reply; 14+ messages in thread
From: Ryan Roberts @ 2024-09-13 10:38 UTC (permalink / raw)
To: Anshuman Khandual, linux-mm
Cc: Andrew Morton, David Hildenbrand, Mike Rapoport (IBM),
Arnd Bergmann, x86, linux-m68k, linux-fsdevel, kasan-dev,
linux-kernel, linux-perf-users, Dimitri Sivanich, Muchun Song,
Andrey Ryabinin, Miaohe Lin, Naoya Horiguchi, Pasha Tatashin,
Dennis Zhou, Tejun Heo, Christoph Lameter, Uladzislau Rezki,
Christoph Hellwig
On 13/09/2024 09:44, Anshuman Khandual wrote:
> Convert PMD accesses via pmdp_get() helper that defaults as READ_ONCE() but
> also provides the platform an opportunity to override when required.
>
> Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
> Cc: Muchun Song <muchun.song@linux.dev>
> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> Cc: Miaohe Lin <linmiaohe@huawei.com>
> Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
> Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
> Cc: Dennis Zhou <dennis@kernel.org>
> Cc: Tejun Heo <tj@kernel.org>
> Cc: Christoph Lameter <cl@linux.com>
> Cc: Uladzislau Rezki <urezki@gmail.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Ryan Roberts <ryan.roberts@arm.com>
> Cc: "Mike Rapoport (IBM)" <rppt@kernel.org>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-mm@kvack.org
> Cc: kasan-dev@googlegroups.com
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> drivers/misc/sgi-gru/grufault.c | 4 +--
> fs/proc/task_mmu.c | 26 +++++++-------
> include/linux/huge_mm.h | 3 +-
> include/linux/mm.h | 2 +-
> include/linux/pgtable.h | 14 ++++----
> mm/gup.c | 14 ++++----
> mm/huge_memory.c | 60 ++++++++++++++++-----------------
> mm/hugetlb_vmemmap.c | 4 +--
> mm/kasan/init.c | 10 +++---
> mm/kasan/shadow.c | 4 +--
> mm/khugepaged.c | 4 +--
> mm/madvise.c | 6 ++--
> mm/memory-failure.c | 6 ++--
> mm/memory.c | 25 +++++++-------
> mm/mempolicy.c | 4 +--
> mm/migrate.c | 4 +--
> mm/migrate_device.c | 10 +++---
> mm/mlock.c | 6 ++--
> mm/mprotect.c | 2 +-
> mm/mremap.c | 4 +--
> mm/page_table_check.c | 2 +-
> mm/pagewalk.c | 4 +--
> mm/percpu.c | 2 +-
> mm/pgtable-generic.c | 16 ++++-----
> mm/ptdump.c | 2 +-
> mm/rmap.c | 2 +-
> mm/sparse-vmemmap.c | 4 +--
> mm/vmalloc.c | 12 +++----
> 28 files changed, 129 insertions(+), 127 deletions(-)
>
> diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
> index 3557d78ee47a..f3d6249b7dfb 100644
> --- a/drivers/misc/sgi-gru/grufault.c
> +++ b/drivers/misc/sgi-gru/grufault.c
> @@ -224,10 +224,10 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
> goto err;
>
> pmdp = pmd_offset(pudp, vaddr);
> - if (unlikely(pmd_none(*pmdp)))
> + if (unlikely(pmd_none(pmdp_get(pmdp))))
> goto err;
> #ifdef CONFIG_X86_64
> - if (unlikely(pmd_leaf(*pmdp)))
> + if (unlikely(pmd_leaf(pmdp_get(pmdp))))
Just a general comment about multiple gets; before, the compiler most likely
turned multiple '*pmdp' dereferences into a single actual load. But READ_ONCE()
inside pmdp_get() ensures you get a load for every call to pmdp_get(). This has
2 potential problems:
- More loads could potentially regress speed in some hot paths
- In paths that don't hold an appropriate PTL the multiple loads could race
with a writer, meaning each load gets a different value. The intent of the code
is usually that each check is operating on the same value.
For the ptep_get() conversion, I solved this by reading into a temporary once
then using the temporary for the comparisons.
I'm not sure if these are real problems in practice, but seems safest to
continue to follow this established pattern?
Thanks,
Ryan
> pte = ptep_get((pte_t *)pmdp);
> else
> #endif
> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> index 5f171ad7b436..8bb90f877dc5 100644
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c
> @@ -862,11 +862,11 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
> bool present = false;
> struct folio *folio;
>
> - if (pmd_present(*pmd)) {
> - page = vm_normal_page_pmd(vma, addr, *pmd);
> + if (pmd_present(pmdp_get(pmd))) {
> + page = vm_normal_page_pmd(vma, addr, pmdp_get(pmd));
> present = true;
> - } else if (unlikely(thp_migration_supported() && is_swap_pmd(*pmd))) {
> - swp_entry_t entry = pmd_to_swp_entry(*pmd);
> + } else if (unlikely(thp_migration_supported() && is_swap_pmd(pmdp_get(pmd)))) {
> + swp_entry_t entry = pmd_to_swp_entry(pmdp_get(pmd));
>
> if (is_pfn_swap_entry(entry))
> page = pfn_swap_entry_to_page(entry);
> @@ -883,7 +883,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
> else
> mss->file_thp += HPAGE_PMD_SIZE;
>
> - smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd),
> + smaps_account(mss, page, true, pmd_young(pmdp_get(pmd)), pmd_dirty(pmdp_get(pmd)),
> locked, present);
> }
> #else
> @@ -1426,7 +1426,7 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma,
> static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma,
> unsigned long addr, pmd_t *pmdp)
> {
> - pmd_t old, pmd = *pmdp;
> + pmd_t old, pmd = pmdp_get(pmdp);
>
> if (pmd_present(pmd)) {
> /* See comment in change_huge_pmd() */
> @@ -1468,10 +1468,10 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
> goto out;
> }
>
> - if (!pmd_present(*pmd))
> + if (!pmd_present(pmdp_get(pmd)))
> goto out;
>
> - folio = pmd_folio(*pmd);
> + folio = pmd_folio(pmdp_get(pmd));
>
> /* Clear accessed and referenced bits. */
> pmdp_test_and_clear_young(vma, addr, pmd);
> @@ -1769,7 +1769,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
> if (ptl) {
> unsigned int idx = (addr & ~PMD_MASK) >> PAGE_SHIFT;
> u64 flags = 0, frame = 0;
> - pmd_t pmd = *pmdp;
> + pmd_t pmd = pmdp_get(pmdp);
> struct page *page = NULL;
> struct folio *folio = NULL;
>
> @@ -2189,7 +2189,7 @@ static unsigned long pagemap_thp_category(struct pagemap_scan_private *p,
> static void make_uffd_wp_pmd(struct vm_area_struct *vma,
> unsigned long addr, pmd_t *pmdp)
> {
> - pmd_t old, pmd = *pmdp;
> + pmd_t old, pmd = pmdp_get(pmdp);
>
> if (pmd_present(pmd)) {
> old = pmdp_invalidate_ad(vma, addr, pmdp);
> @@ -2416,7 +2416,7 @@ static int pagemap_scan_thp_entry(pmd_t *pmd, unsigned long start,
> return -ENOENT;
>
> categories = p->cur_vma_category |
> - pagemap_thp_category(p, vma, start, *pmd);
> + pagemap_thp_category(p, vma, start, pmdp_get(pmd));
>
> if (!pagemap_scan_is_interesting_page(categories, p))
> goto out_unlock;
> @@ -2947,9 +2947,9 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
> if (ptl) {
> struct page *page;
>
> - page = can_gather_numa_stats_pmd(*pmd, vma, addr);
> + page = can_gather_numa_stats_pmd(pmdp_get(pmd), vma, addr);
> if (page)
> - gather_stats(page, md, pmd_dirty(*pmd),
> + gather_stats(page, md, pmd_dirty(pmdp_get(pmd)),
> HPAGE_PMD_SIZE/PAGE_SIZE);
> spin_unlock(ptl);
> return 0;
> diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
> index e25d9ebfdf89..351d6c72af9e 100644
> --- a/include/linux/huge_mm.h
> +++ b/include/linux/huge_mm.h
> @@ -369,7 +369,8 @@ static inline int is_swap_pmd(pmd_t pmd)
> static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
> struct vm_area_struct *vma)
> {
> - if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd))
> + if (is_swap_pmd(pmdp_get(pmd)) || pmd_trans_huge(pmdp_get(pmd)) ||
> + pmd_devmap(pmdp_get(pmd)))
> return __pmd_trans_huge_lock(pmd, vma);
> else
> return NULL;
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 147073601716..258e49323306 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2921,7 +2921,7 @@ static inline spinlock_t *ptlock_ptr(struct ptdesc *ptdesc)
>
> static inline spinlock_t *pte_lockptr(struct mm_struct *mm, pmd_t *pmd)
> {
> - return ptlock_ptr(page_ptdesc(pmd_page(*pmd)));
> + return ptlock_ptr(page_ptdesc(pmd_page(pmdp_get(pmd))));
> }
>
> static inline spinlock_t *ptep_lockptr(struct mm_struct *mm, pte_t *pte)
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 05e6995c1b93..188a183205b3 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -367,7 +367,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
> unsigned long address,
> pmd_t *pmdp)
> {
> - pmd_t pmd = *pmdp;
> + pmd_t pmd = pmdp_get(pmdp);
> int r = 1;
> if (!pmd_young(pmd))
> r = 0;
> @@ -598,7 +598,7 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
> unsigned long address,
> pmd_t *pmdp)
> {
> - pmd_t pmd = *pmdp;
> + pmd_t pmd = pmdp_get(pmdp);
>
> pmd_clear(pmdp);
> page_table_check_pmd_clear(mm, pmd);
> @@ -876,7 +876,7 @@ static inline pte_t pte_sw_mkyoung(pte_t pte)
> static inline void pmdp_set_wrprotect(struct mm_struct *mm,
> unsigned long address, pmd_t *pmdp)
> {
> - pmd_t old_pmd = *pmdp;
> + pmd_t old_pmd = pmdp_get(pmdp);
> set_pmd_at(mm, address, pmdp, pmd_wrprotect(old_pmd));
> }
> #else
> @@ -945,7 +945,7 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
> static inline pmd_t generic_pmdp_establish(struct vm_area_struct *vma,
> unsigned long address, pmd_t *pmdp, pmd_t pmd)
> {
> - pmd_t old_pmd = *pmdp;
> + pmd_t old_pmd = pmdp_get(pmdp);
> set_pmd_at(vma->vm_mm, address, pmdp, pmd);
> return old_pmd;
> }
> @@ -1066,7 +1066,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
>
> #define set_pmd_safe(pmdp, pmd) \
> ({ \
> - WARN_ON_ONCE(pmd_present(*pmdp) && !pmd_same(*pmdp, pmd)); \
> + WARN_ON_ONCE(pmd_present(pmdp_get(pmdp)) && !pmd_same(pmdp_get(pmdp), pmd)); \
> set_pmd(pmdp, pmd); \
> })
>
> @@ -1270,9 +1270,9 @@ static inline int pud_none_or_clear_bad(pud_t *pud)
>
> static inline int pmd_none_or_clear_bad(pmd_t *pmd)
> {
> - if (pmd_none(*pmd))
> + if (pmd_none(pmdp_get(pmd)))
> return 1;
> - if (unlikely(pmd_bad(*pmd))) {
> + if (unlikely(pmd_bad(pmdp_get(pmd)))) {
> pmd_clear_bad(pmd);
> return 1;
> }
> diff --git a/mm/gup.c b/mm/gup.c
> index 54d0dc3831fb..aeeac0a54944 100644
> --- a/mm/gup.c
> +++ b/mm/gup.c
> @@ -699,7 +699,7 @@ static struct page *follow_huge_pmd(struct vm_area_struct *vma,
> struct follow_page_context *ctx)
> {
> struct mm_struct *mm = vma->vm_mm;
> - pmd_t pmdval = *pmd;
> + pmd_t pmdval = pmdp_get(pmd);
> struct page *page;
> int ret;
>
> @@ -714,7 +714,7 @@ static struct page *follow_huge_pmd(struct vm_area_struct *vma,
> if ((flags & FOLL_DUMP) && is_huge_zero_pmd(pmdval))
> return ERR_PTR(-EFAULT);
>
> - if (pmd_protnone(*pmd) && !gup_can_follow_protnone(vma, flags))
> + if (pmd_protnone(pmdp_get(pmd)) && !gup_can_follow_protnone(vma, flags))
> return NULL;
>
> if (!pmd_write(pmdval) && gup_must_unshare(vma, flags, page))
> @@ -957,7 +957,7 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma,
> return no_page_table(vma, flags, address);
>
> ptl = pmd_lock(mm, pmd);
> - pmdval = *pmd;
> + pmdval = pmdp_get(pmd);
> if (unlikely(!pmd_present(pmdval))) {
> spin_unlock(ptl);
> return no_page_table(vma, flags, address);
> @@ -1120,7 +1120,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
> if (pud_none(*pud))
> return -EFAULT;
> pmd = pmd_offset(pud, address);
> - if (!pmd_present(*pmd))
> + if (!pmd_present(pmdp_get(pmd)))
> return -EFAULT;
> pte = pte_offset_map(pmd, address);
> if (!pte)
> @@ -2898,7 +2898,7 @@ static int gup_fast_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
> if (!folio)
> goto pte_unmap;
>
> - if (unlikely(pmd_val(pmd) != pmd_val(*pmdp)) ||
> + if (unlikely(pmd_val(pmd) != pmd_val(pmdp_get(pmdp))) ||
> unlikely(pte_val(pte) != pte_val(ptep_get(ptep)))) {
> gup_put_folio(folio, 1, flags);
> goto pte_unmap;
> @@ -3007,7 +3007,7 @@ static int gup_fast_devmap_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
> if (!gup_fast_devmap_leaf(fault_pfn, addr, end, flags, pages, nr))
> return 0;
>
> - if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
> + if (unlikely(pmd_val(orig) != pmd_val(pmdp_get(pmdp)))) {
> gup_fast_undo_dev_pagemap(nr, nr_start, flags, pages);
> return 0;
> }
> @@ -3074,7 +3074,7 @@ static int gup_fast_pmd_leaf(pmd_t orig, pmd_t *pmdp, unsigned long addr,
> if (!folio)
> return 0;
>
> - if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
> + if (unlikely(pmd_val(orig) != pmd_val(pmdp_get(pmdp)))) {
> gup_put_folio(folio, refs, flags);
> return 0;
> }
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 67c86a5d64a6..3545142a5dc9 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -1065,7 +1065,7 @@ static void set_huge_zero_folio(pgtable_t pgtable, struct mm_struct *mm,
> struct folio *zero_folio)
> {
> pmd_t entry;
> - if (!pmd_none(*pmd))
> + if (!pmd_none(pmdp_get(pmd)))
> return;
> entry = mk_pmd(&zero_folio->page, vma->vm_page_prot);
> entry = pmd_mkhuge(entry);
> @@ -1148,13 +1148,13 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
> spinlock_t *ptl;
>
> ptl = pmd_lock(mm, pmd);
> - if (!pmd_none(*pmd)) {
> + if (!pmd_none(pmdp_get(pmd))) {
> if (write) {
> - if (pmd_pfn(*pmd) != pfn_t_to_pfn(pfn)) {
> - WARN_ON_ONCE(!is_huge_zero_pmd(*pmd));
> + if (pmd_pfn(pmdp_get(pmd)) != pfn_t_to_pfn(pfn)) {
> + WARN_ON_ONCE(!is_huge_zero_pmd(pmdp_get(pmd)));
> goto out_unlock;
> }
> - entry = pmd_mkyoung(*pmd);
> + entry = pmd_mkyoung(pmdp_get(pmd));
> entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
> if (pmdp_set_access_flags(vma, addr, pmd, entry, 1))
> update_mmu_cache_pmd(vma, addr, pmd);
> @@ -1318,7 +1318,7 @@ void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
> {
> pmd_t _pmd;
>
> - _pmd = pmd_mkyoung(*pmd);
> + _pmd = pmd_mkyoung(pmdp_get(pmd));
> if (write)
> _pmd = pmd_mkdirty(_pmd);
> if (pmdp_set_access_flags(vma, addr & HPAGE_PMD_MASK,
> @@ -1329,17 +1329,17 @@ void touch_pmd(struct vm_area_struct *vma, unsigned long addr,
> struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr,
> pmd_t *pmd, int flags, struct dev_pagemap **pgmap)
> {
> - unsigned long pfn = pmd_pfn(*pmd);
> + unsigned long pfn = pmd_pfn(pmdp_get(pmd));
> struct mm_struct *mm = vma->vm_mm;
> struct page *page;
> int ret;
>
> assert_spin_locked(pmd_lockptr(mm, pmd));
>
> - if (flags & FOLL_WRITE && !pmd_write(*pmd))
> + if (flags & FOLL_WRITE && !pmd_write(pmdp_get(pmd)))
> return NULL;
>
> - if (pmd_present(*pmd) && pmd_devmap(*pmd))
> + if (pmd_present(pmdp_get(pmd)) && pmd_devmap(pmdp_get(pmd)))
> /* pass */;
> else
> return NULL;
> @@ -1772,7 +1772,7 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
> if (!ptl)
> goto out_unlocked;
>
> - orig_pmd = *pmd;
> + orig_pmd = pmdp_get(pmd);
> if (is_huge_zero_pmd(orig_pmd))
> goto out;
>
> @@ -2006,12 +2006,12 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
> return 0;
>
> #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
> - if (is_swap_pmd(*pmd)) {
> - swp_entry_t entry = pmd_to_swp_entry(*pmd);
> + if (is_swap_pmd(pmdp_get(pmd))) {
> + swp_entry_t entry = pmd_to_swp_entry(pmdp_get(pmd));
> struct folio *folio = pfn_swap_entry_folio(entry);
> pmd_t newpmd;
>
> - VM_BUG_ON(!is_pmd_migration_entry(*pmd));
> + VM_BUG_ON(!is_pmd_migration_entry(pmdp_get(pmd)));
> if (is_writable_migration_entry(entry)) {
> /*
> * A protection check is difficult so
> @@ -2022,17 +2022,17 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
> else
> entry = make_readable_migration_entry(swp_offset(entry));
> newpmd = swp_entry_to_pmd(entry);
> - if (pmd_swp_soft_dirty(*pmd))
> + if (pmd_swp_soft_dirty(pmdp_get(pmd)))
> newpmd = pmd_swp_mksoft_dirty(newpmd);
> } else {
> - newpmd = *pmd;
> + newpmd = pmdp_get(pmd);
> }
>
> if (uffd_wp)
> newpmd = pmd_swp_mkuffd_wp(newpmd);
> else if (uffd_wp_resolve)
> newpmd = pmd_swp_clear_uffd_wp(newpmd);
> - if (!pmd_same(*pmd, newpmd))
> + if (!pmd_same(pmdp_get(pmd), newpmd))
> set_pmd_at(mm, addr, pmd, newpmd);
> goto unlock;
> }
> @@ -2046,13 +2046,13 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
> * data is likely to be read-cached on the local CPU and
> * local/remote hits to the zero page are not interesting.
> */
> - if (is_huge_zero_pmd(*pmd))
> + if (is_huge_zero_pmd(pmdp_get(pmd)))
> goto unlock;
>
> - if (pmd_protnone(*pmd))
> + if (pmd_protnone(pmdp_get(pmd)))
> goto unlock;
>
> - folio = pmd_folio(*pmd);
> + folio = pmd_folio(pmdp_get(pmd));
> toptier = node_is_toptier(folio_nid(folio));
> /*
> * Skip scanning top tier node if normal numa
> @@ -2266,8 +2266,8 @@ spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma)
> {
> spinlock_t *ptl;
> ptl = pmd_lock(vma->vm_mm, pmd);
> - if (likely(is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) ||
> - pmd_devmap(*pmd)))
> + if (likely(is_swap_pmd(pmdp_get(pmd)) || pmd_trans_huge(pmdp_get(pmd)) ||
> + pmd_devmap(pmdp_get(pmd))))
> return ptl;
> spin_unlock(ptl);
> return NULL;
> @@ -2404,8 +2404,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
> VM_BUG_ON(haddr & ~HPAGE_PMD_MASK);
> VM_BUG_ON_VMA(vma->vm_start > haddr, vma);
> VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PMD_SIZE, vma);
> - VM_BUG_ON(!is_pmd_migration_entry(*pmd) && !pmd_trans_huge(*pmd)
> - && !pmd_devmap(*pmd));
> + VM_BUG_ON(!is_pmd_migration_entry(pmdp_get(pmd)) && !pmd_trans_huge(pmdp_get(pmd))
> + && !pmd_devmap(pmdp_get(pmd)));
>
> count_vm_event(THP_SPLIT_PMD);
>
> @@ -2438,7 +2438,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
> return;
> }
>
> - if (is_huge_zero_pmd(*pmd)) {
> + if (is_huge_zero_pmd(pmdp_get(pmd))) {
> /*
> * FIXME: Do we want to invalidate secondary mmu by calling
> * mmu_notifier_arch_invalidate_secondary_tlbs() see comments below
> @@ -2451,11 +2451,11 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
> return __split_huge_zero_page_pmd(vma, haddr, pmd);
> }
>
> - pmd_migration = is_pmd_migration_entry(*pmd);
> + pmd_migration = is_pmd_migration_entry(pmdp_get(pmd));
> if (unlikely(pmd_migration)) {
> swp_entry_t entry;
>
> - old_pmd = *pmd;
> + old_pmd = pmdp_get(pmd);
> entry = pmd_to_swp_entry(old_pmd);
> page = pfn_swap_entry_to_page(entry);
> write = is_writable_migration_entry(entry);
> @@ -2620,9 +2620,9 @@ void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
> * require a folio to check the PMD against. Otherwise, there
> * is a risk of replacing the wrong folio.
> */
> - if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||
> - is_pmd_migration_entry(*pmd)) {
> - if (folio && folio != pmd_folio(*pmd))
> + if (pmd_trans_huge(pmdp_get(pmd)) || pmd_devmap(pmdp_get(pmd)) ||
> + is_pmd_migration_entry(pmdp_get(pmd))) {
> + if (folio && folio != pmd_folio(pmdp_get(pmd)))
> return;
> __split_huge_pmd_locked(vma, pmd, address, freeze);
> }
> @@ -2719,7 +2719,7 @@ static bool __discard_anon_folio_pmd_locked(struct vm_area_struct *vma,
> {
> struct mm_struct *mm = vma->vm_mm;
> int ref_count, map_count;
> - pmd_t orig_pmd = *pmdp;
> + pmd_t orig_pmd = pmdp_get(pmdp);
>
> if (folio_test_dirty(folio) || pmd_dirty(orig_pmd))
> return false;
> diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
> index 0c3f56b3578e..9deb82654d5b 100644
> --- a/mm/hugetlb_vmemmap.c
> +++ b/mm/hugetlb_vmemmap.c
> @@ -70,7 +70,7 @@ static int vmemmap_split_pmd(pmd_t *pmd, struct page *head, unsigned long start,
> }
>
> spin_lock(&init_mm.page_table_lock);
> - if (likely(pmd_leaf(*pmd))) {
> + if (likely(pmd_leaf(pmdp_get(pmd)))) {
> /*
> * Higher order allocations from buddy allocator must be able to
> * be treated as indepdenent small pages (as they can be freed
> @@ -104,7 +104,7 @@ static int vmemmap_pmd_entry(pmd_t *pmd, unsigned long addr,
> walk->action = ACTION_CONTINUE;
>
> spin_lock(&init_mm.page_table_lock);
> - head = pmd_leaf(*pmd) ? pmd_page(*pmd) : NULL;
> + head = pmd_leaf(pmdp_get(pmd)) ? pmd_page(pmdp_get(pmd)) : NULL;
> /*
> * Due to HugeTLB alignment requirements and the vmemmap
> * pages being at the start of the hotplugged memory
> diff --git a/mm/kasan/init.c b/mm/kasan/init.c
> index 89895f38f722..4418bcdcb2aa 100644
> --- a/mm/kasan/init.c
> +++ b/mm/kasan/init.c
> @@ -121,7 +121,7 @@ static int __ref zero_pmd_populate(pud_t *pud, unsigned long addr,
> continue;
> }
>
> - if (pmd_none(*pmd)) {
> + if (pmd_none(pmdp_get(pmd))) {
> pte_t *p;
>
> if (slab_is_available())
> @@ -300,7 +300,7 @@ static void kasan_free_pte(pte_t *pte_start, pmd_t *pmd)
> return;
> }
>
> - pte_free_kernel(&init_mm, (pte_t *)page_to_virt(pmd_page(*pmd)));
> + pte_free_kernel(&init_mm, (pte_t *)page_to_virt(pmd_page(pmdp_get(pmd))));
> pmd_clear(pmd);
> }
>
> @@ -311,7 +311,7 @@ static void kasan_free_pmd(pmd_t *pmd_start, pud_t *pud)
>
> for (i = 0; i < PTRS_PER_PMD; i++) {
> pmd = pmd_start + i;
> - if (!pmd_none(*pmd))
> + if (!pmd_none(pmdp_get(pmd)))
> return;
> }
>
> @@ -381,10 +381,10 @@ static void kasan_remove_pmd_table(pmd_t *pmd, unsigned long addr,
>
> next = pmd_addr_end(addr, end);
>
> - if (!pmd_present(*pmd))
> + if (!pmd_present(pmdp_get(pmd)))
> continue;
>
> - if (kasan_pte_table(*pmd)) {
> + if (kasan_pte_table(pmdp_get(pmd))) {
> if (IS_ALIGNED(addr, PMD_SIZE) &&
> IS_ALIGNED(next, PMD_SIZE)) {
> pmd_clear(pmd);
> diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
> index d6210ca48dda..aec16a7236f7 100644
> --- a/mm/kasan/shadow.c
> +++ b/mm/kasan/shadow.c
> @@ -202,9 +202,9 @@ static bool shadow_mapped(unsigned long addr)
> if (pud_leaf(*pud))
> return true;
> pmd = pmd_offset(pud, addr);
> - if (pmd_none(*pmd))
> + if (pmd_none(pmdp_get(pmd)))
> return false;
> - if (pmd_leaf(*pmd))
> + if (pmd_leaf(pmdp_get(pmd)))
> return true;
> pte = pte_offset_kernel(pmd, addr);
> return !pte_none(ptep_get(pte));
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index cdd1d8655a76..793da996313f 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -1192,7 +1192,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,
> if (pte)
> pte_unmap(pte);
> spin_lock(pmd_ptl);
> - BUG_ON(!pmd_none(*pmd));
> + BUG_ON(!pmd_none(pmdp_get(pmd)));
> /*
> * We can only use set_pmd_at when establishing
> * hugepmds and never for establishing regular pmds that
> @@ -1229,7 +1229,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,
> _pmd = maybe_pmd_mkwrite(pmd_mkdirty(_pmd), vma);
>
> spin_lock(pmd_ptl);
> - BUG_ON(!pmd_none(*pmd));
> + BUG_ON(!pmd_none(pmdp_get(pmd)));
> folio_add_new_anon_rmap(folio, vma, address, RMAP_EXCLUSIVE);
> folio_add_lru_vma(folio, vma);
> pgtable_trans_huge_deposit(mm, pmd, pgtable);
> diff --git a/mm/madvise.c b/mm/madvise.c
> index 89089d84f8df..382c55d2ec94 100644
> --- a/mm/madvise.c
> +++ b/mm/madvise.c
> @@ -357,7 +357,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
> !can_do_file_pageout(vma);
>
> #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> - if (pmd_trans_huge(*pmd)) {
> + if (pmd_trans_huge(pmdp_get(pmd))) {
> pmd_t orig_pmd;
> unsigned long next = pmd_addr_end(addr, end);
>
> @@ -366,7 +366,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
> if (!ptl)
> return 0;
>
> - orig_pmd = *pmd;
> + orig_pmd = pmdp_get(pmd);
> if (is_huge_zero_pmd(orig_pmd))
> goto huge_unlock;
>
> @@ -655,7 +655,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
> int nr, max_nr;
>
> next = pmd_addr_end(addr, end);
> - if (pmd_trans_huge(*pmd))
> + if (pmd_trans_huge(pmdp_get(pmd)))
> if (madvise_free_huge_pmd(tlb, vma, pmd, addr, next))
> return 0;
>
> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
> index 7066fc84f351..305dbef3cc4d 100644
> --- a/mm/memory-failure.c
> +++ b/mm/memory-failure.c
> @@ -422,9 +422,9 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
> if (pud_devmap(*pud))
> return PUD_SHIFT;
> pmd = pmd_offset(pud, address);
> - if (!pmd_present(*pmd))
> + if (!pmd_present(pmdp_get(pmd)))
> return 0;
> - if (pmd_devmap(*pmd))
> + if (pmd_devmap(pmdp_get(pmd)))
> return PMD_SHIFT;
> pte = pte_offset_map(pmd, address);
> if (!pte)
> @@ -775,7 +775,7 @@ static int check_hwpoisoned_entry(pte_t pte, unsigned long addr, short shift,
> static int check_hwpoisoned_pmd_entry(pmd_t *pmdp, unsigned long addr,
> struct hwpoison_walk *hwp)
> {
> - pmd_t pmd = *pmdp;
> + pmd_t pmd = pmdp_get(pmdp);
> unsigned long pfn;
> unsigned long hwpoison_vaddr;
>
> diff --git a/mm/memory.c b/mm/memory.c
> index 3c01d68065be..43953a6d350f 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -189,7 +189,7 @@ void mm_trace_rss_stat(struct mm_struct *mm, int member)
> static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
> unsigned long addr)
> {
> - pgtable_t token = pmd_pgtable(*pmd);
> + pgtable_t token = pmd_pgtable(pmdp_get(pmd));
> pmd_clear(pmd);
> pte_free_tlb(tlb, token, addr);
> mm_dec_nr_ptes(tlb->mm);
> @@ -421,7 +421,7 @@ void pmd_install(struct mm_struct *mm, pmd_t *pmd, pgtable_t *pte)
> {
> spinlock_t *ptl = pmd_lock(mm, pmd);
>
> - if (likely(pmd_none(*pmd))) { /* Has another populated it ? */
> + if (likely(pmd_none(pmdp_get(pmd)))) { /* Has another populated it ? */
> mm_inc_nr_ptes(mm);
> /*
> * Ensure all pte setup (eg. pte page lock and page clearing) are
> @@ -462,7 +462,7 @@ int __pte_alloc_kernel(pmd_t *pmd)
> return -ENOMEM;
>
> spin_lock(&init_mm.page_table_lock);
> - if (likely(pmd_none(*pmd))) { /* Has another populated it ? */
> + if (likely(pmd_none(pmdp_get(pmd)))) { /* Has another populated it ? */
> smp_wmb(); /* See comment in pmd_install() */
> pmd_populate_kernel(&init_mm, pmd, new);
> new = NULL;
> @@ -1710,7 +1710,8 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
> pmd = pmd_offset(pud, addr);
> do {
> next = pmd_addr_end(addr, end);
> - if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) {
> + if (is_swap_pmd(pmdp_get(pmd)) || pmd_trans_huge(pmdp_get(pmd)) ||
> + pmd_devmap(pmdp_get(pmd))) {
> if (next - addr != HPAGE_PMD_SIZE)
> __split_huge_pmd(vma, pmd, addr, false, NULL);
> else if (zap_huge_pmd(tlb, vma, pmd, addr)) {
> @@ -1720,7 +1721,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
> /* fall through */
> } else if (details && details->single_folio &&
> folio_test_pmd_mappable(details->single_folio) &&
> - next - addr == HPAGE_PMD_SIZE && pmd_none(*pmd)) {
> + next - addr == HPAGE_PMD_SIZE && pmd_none(pmdp_get(pmd))) {
> spinlock_t *ptl = pmd_lock(tlb->mm, pmd);
> /*
> * Take and drop THP pmd lock so that we cannot return
> @@ -1729,7 +1730,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
> */
> spin_unlock(ptl);
> }
> - if (pmd_none(*pmd)) {
> + if (pmd_none(pmdp_get(pmd))) {
> addr = next;
> continue;
> }
> @@ -1975,7 +1976,7 @@ static pmd_t *walk_to_pmd(struct mm_struct *mm, unsigned long addr)
> if (!pmd)
> return NULL;
>
> - VM_BUG_ON(pmd_trans_huge(*pmd));
> + VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
> return pmd;
> }
>
> @@ -2577,7 +2578,7 @@ static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud,
> pmd = pmd_alloc(mm, pud, addr);
> if (!pmd)
> return -ENOMEM;
> - VM_BUG_ON(pmd_trans_huge(*pmd));
> + VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
> do {
> next = pmd_addr_end(addr, end);
> err = remap_pte_range(mm, pmd, addr, next,
> @@ -2829,11 +2830,11 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
> }
> do {
> next = pmd_addr_end(addr, end);
> - if (pmd_none(*pmd) && !create)
> + if (pmd_none(pmdp_get(pmd)) && !create)
> continue;
> - if (WARN_ON_ONCE(pmd_leaf(*pmd)))
> + if (WARN_ON_ONCE(pmd_leaf(pmdp_get(pmd))))
> return -EINVAL;
> - if (!pmd_none(*pmd) && WARN_ON_ONCE(pmd_bad(*pmd))) {
> + if (!pmd_none(pmdp_get(pmd)) && WARN_ON_ONCE(pmd_bad(pmdp_get(pmd)))) {
> if (!create)
> continue;
> pmd_clear_bad(pmd);
> @@ -6150,7 +6151,7 @@ int follow_pte(struct vm_area_struct *vma, unsigned long address,
> goto out;
>
> pmd = pmd_offset(pud, address);
> - VM_BUG_ON(pmd_trans_huge(*pmd));
> + VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
>
> ptep = pte_offset_map_lock(mm, pmd, address, ptlp);
> if (!ptep)
> diff --git a/mm/mempolicy.c b/mm/mempolicy.c
> index b858e22b259d..03f2df44b07f 100644
> --- a/mm/mempolicy.c
> +++ b/mm/mempolicy.c
> @@ -505,11 +505,11 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
> struct folio *folio;
> struct queue_pages *qp = walk->private;
>
> - if (unlikely(is_pmd_migration_entry(*pmd))) {
> + if (unlikely(is_pmd_migration_entry(pmdp_get(pmd)))) {
> qp->nr_failed++;
> return;
> }
> - folio = pmd_folio(*pmd);
> + folio = pmd_folio(pmdp_get(pmd));
> if (is_huge_zero_folio(folio)) {
> walk->action = ACTION_CONTINUE;
> return;
> diff --git a/mm/migrate.c b/mm/migrate.c
> index 923ea80ba744..a1dd5c8f88dd 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -369,9 +369,9 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd)
> spinlock_t *ptl;
>
> ptl = pmd_lock(mm, pmd);
> - if (!is_pmd_migration_entry(*pmd))
> + if (!is_pmd_migration_entry(pmdp_get(pmd)))
> goto unlock;
> - migration_entry_wait_on_locked(pmd_to_swp_entry(*pmd), ptl);
> + migration_entry_wait_on_locked(pmd_to_swp_entry(pmdp_get(pmd)), ptl);
> return;
> unlock:
> spin_unlock(ptl);
> diff --git a/mm/migrate_device.c b/mm/migrate_device.c
> index 6d66dc1c6ffa..3a08cef6cd39 100644
> --- a/mm/migrate_device.c
> +++ b/mm/migrate_device.c
> @@ -67,19 +67,19 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
> pte_t *ptep;
>
> again:
> - if (pmd_none(*pmdp))
> + if (pmd_none(pmdp_get(pmdp)))
> return migrate_vma_collect_hole(start, end, -1, walk);
>
> - if (pmd_trans_huge(*pmdp)) {
> + if (pmd_trans_huge(pmdp_get(pmdp))) {
> struct folio *folio;
>
> ptl = pmd_lock(mm, pmdp);
> - if (unlikely(!pmd_trans_huge(*pmdp))) {
> + if (unlikely(!pmd_trans_huge(pmdp_get(pmdp)))) {
> spin_unlock(ptl);
> goto again;
> }
>
> - folio = pmd_folio(*pmdp);
> + folio = pmd_folio(pmdp_get(pmdp));
> if (is_huge_zero_folio(folio)) {
> spin_unlock(ptl);
> split_huge_pmd(vma, pmdp, addr);
> @@ -596,7 +596,7 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
> pmdp = pmd_alloc(mm, pudp, addr);
> if (!pmdp)
> goto abort;
> - if (pmd_trans_huge(*pmdp) || pmd_devmap(*pmdp))
> + if (pmd_trans_huge(pmdp_get(pmdp)) || pmd_devmap(pmdp_get(pmdp)))
> goto abort;
> if (pte_alloc(mm, pmdp))
> goto abort;
> diff --git a/mm/mlock.c b/mm/mlock.c
> index e3e3dc2b2956..c3c479e9d0f8 100644
> --- a/mm/mlock.c
> +++ b/mm/mlock.c
> @@ -363,11 +363,11 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
>
> ptl = pmd_trans_huge_lock(pmd, vma);
> if (ptl) {
> - if (!pmd_present(*pmd))
> + if (!pmd_present(pmdp_get(pmd)))
> goto out;
> - if (is_huge_zero_pmd(*pmd))
> + if (is_huge_zero_pmd(pmdp_get(pmd)))
> goto out;
> - folio = pmd_folio(*pmd);
> + folio = pmd_folio(pmdp_get(pmd));
> if (vma->vm_flags & VM_LOCKED)
> mlock_folio(folio);
> else
> diff --git a/mm/mprotect.c b/mm/mprotect.c
> index 222ab434da54..121fb448b0db 100644
> --- a/mm/mprotect.c
> +++ b/mm/mprotect.c
> @@ -381,7 +381,7 @@ static inline long change_pmd_range(struct mmu_gather *tlb,
> break;
> }
>
> - if (pmd_none(*pmd))
> + if (pmd_none(pmdp_get(pmd)))
> goto next;
>
> /* invoke the mmu notifier if the pmd is populated */
> diff --git a/mm/mremap.c b/mm/mremap.c
> index e7ae140fc640..d42ac62bd34e 100644
> --- a/mm/mremap.c
> +++ b/mm/mremap.c
> @@ -63,7 +63,7 @@ static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr)
> return NULL;
>
> pmd = pmd_offset(pud, addr);
> - if (pmd_none(*pmd))
> + if (pmd_none(pmdp_get(pmd)))
> return NULL;
>
> return pmd;
> @@ -97,7 +97,7 @@ static pmd_t *alloc_new_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
> if (!pmd)
> return NULL;
>
> - VM_BUG_ON(pmd_trans_huge(*pmd));
> + VM_BUG_ON(pmd_trans_huge(pmdp_get(pmd)));
>
> return pmd;
> }
> diff --git a/mm/page_table_check.c b/mm/page_table_check.c
> index 509c6ef8de40..48a2cf56c80e 100644
> --- a/mm/page_table_check.c
> +++ b/mm/page_table_check.c
> @@ -241,7 +241,7 @@ void __page_table_check_pmd_set(struct mm_struct *mm, pmd_t *pmdp, pmd_t pmd)
>
> page_table_check_pmd_flags(pmd);
>
> - __page_table_check_pmd_clear(mm, *pmdp);
> + __page_table_check_pmd_clear(mm, pmdp_get(pmdp));
> if (pmd_user_accessible_page(pmd)) {
> page_table_check_set(pmd_pfn(pmd), PMD_SIZE >> PAGE_SHIFT,
> pmd_write(pmd));
> diff --git a/mm/pagewalk.c b/mm/pagewalk.c
> index ae2f08ce991b..c3019a160e77 100644
> --- a/mm/pagewalk.c
> +++ b/mm/pagewalk.c
> @@ -86,7 +86,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
> do {
> again:
> next = pmd_addr_end(addr, end);
> - if (pmd_none(*pmd)) {
> + if (pmd_none(pmdp_get(pmd))) {
> if (ops->pte_hole)
> err = ops->pte_hole(addr, next, depth, walk);
> if (err)
> @@ -112,7 +112,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
> * Check this here so we only break down trans_huge
> * pages when we _need_ to
> */
> - if ((!walk->vma && (pmd_leaf(*pmd) || !pmd_present(*pmd))) ||
> + if ((!walk->vma && (pmd_leaf(pmdp_get(pmd)) || !pmd_present(pmdp_get(pmd)))) ||
> walk->action == ACTION_CONTINUE ||
> !(ops->pte_entry))
> continue;
> diff --git a/mm/percpu.c b/mm/percpu.c
> index 20d91af8c033..7ee77c0fd5e3 100644
> --- a/mm/percpu.c
> +++ b/mm/percpu.c
> @@ -3208,7 +3208,7 @@ void __init __weak pcpu_populate_pte(unsigned long addr)
> }
>
> pmd = pmd_offset(pud, addr);
> - if (!pmd_present(*pmd)) {
> + if (!pmd_present(pmdp_get(pmd))) {
> pte_t *new;
>
> new = memblock_alloc(PTE_TABLE_SIZE, PTE_TABLE_SIZE);
> diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
> index a78a4adf711a..a5045d0fc73e 100644
> --- a/mm/pgtable-generic.c
> +++ b/mm/pgtable-generic.c
> @@ -51,7 +51,7 @@ void pud_clear_bad(pud_t *pud)
> */
> void pmd_clear_bad(pmd_t *pmd)
> {
> - pmd_ERROR(*pmd);
> + pmd_ERROR(pmdp_get(pmd));
> pmd_clear(pmd);
> }
>
> @@ -110,7 +110,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma,
> unsigned long address, pmd_t *pmdp,
> pmd_t entry, int dirty)
> {
> - int changed = !pmd_same(*pmdp, entry);
> + int changed = !pmd_same(pmdp_get(pmdp), entry);
> VM_BUG_ON(address & ~HPAGE_PMD_MASK);
> if (changed) {
> set_pmd_at(vma->vm_mm, address, pmdp, entry);
> @@ -139,8 +139,8 @@ pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, unsigned long address,
> {
> pmd_t pmd;
> VM_BUG_ON(address & ~HPAGE_PMD_MASK);
> - VM_BUG_ON(pmd_present(*pmdp) && !pmd_trans_huge(*pmdp) &&
> - !pmd_devmap(*pmdp));
> + VM_BUG_ON(pmd_present(pmdp_get(pmdp)) && !pmd_trans_huge(pmdp_get(pmdp)) &&
> + !pmd_devmap(pmdp_get(pmdp)));
> pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
> flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
> return pmd;
> @@ -198,8 +198,8 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
> pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
> pmd_t *pmdp)
> {
> - VM_WARN_ON_ONCE(!pmd_present(*pmdp));
> - pmd_t old = pmdp_establish(vma, address, pmdp, pmd_mkinvalid(*pmdp));
> + VM_WARN_ON_ONCE(!pmd_present(pmdp_get(pmdp)));
> + pmd_t old = pmdp_establish(vma, address, pmdp, pmd_mkinvalid(pmdp_get(pmdp)));
> flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
> return old;
> }
> @@ -209,7 +209,7 @@ pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
> pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address,
> pmd_t *pmdp)
> {
> - VM_WARN_ON_ONCE(!pmd_present(*pmdp));
> + VM_WARN_ON_ONCE(!pmd_present(pmdp_get(pmdp)));
> return pmdp_invalidate(vma, address, pmdp);
> }
> #endif
> @@ -225,7 +225,7 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
> pmd_t pmd;
>
> VM_BUG_ON(address & ~HPAGE_PMD_MASK);
> - VM_BUG_ON(pmd_trans_huge(*pmdp));
> + VM_BUG_ON(pmd_trans_huge(pmdp_get(pmdp)));
> pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
>
> /* collapse entails shooting down ptes not pmd */
> diff --git a/mm/ptdump.c b/mm/ptdump.c
> index 106e1d66e9f9..e17588a32012 100644
> --- a/mm/ptdump.c
> +++ b/mm/ptdump.c
> @@ -99,7 +99,7 @@ static int ptdump_pmd_entry(pmd_t *pmd, unsigned long addr,
> unsigned long next, struct mm_walk *walk)
> {
> struct ptdump_state *st = walk->private;
> - pmd_t val = READ_ONCE(*pmd);
> + pmd_t val = pmdp_get(pmd);
>
> #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
> if (pmd_page(val) == virt_to_page(lm_alias(kasan_early_shadow_pte)))
> diff --git a/mm/rmap.c b/mm/rmap.c
> index 2490e727e2dc..ec668c48bccc 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
> @@ -1036,7 +1036,7 @@ static int page_vma_mkclean_one(struct page_vma_mapped_walk *pvmw)
> pmd_t *pmd = pvmw->pmd;
> pmd_t entry;
>
> - if (!pmd_dirty(*pmd) && !pmd_write(*pmd))
> + if (!pmd_dirty(pmdp_get(pmd)) && !pmd_write(pmdp_get(pmd)))
> continue;
>
> flush_cache_range(vma, address,
> diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
> index edcc7a6b0f6f..c89706e107ce 100644
> --- a/mm/sparse-vmemmap.c
> +++ b/mm/sparse-vmemmap.c
> @@ -187,7 +187,7 @@ static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node)
> pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
> {
> pmd_t *pmd = pmd_offset(pud, addr);
> - if (pmd_none(*pmd)) {
> + if (pmd_none(pmdp_get(pmd))) {
> void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
> if (!p)
> return NULL;
> @@ -332,7 +332,7 @@ int __meminit vmemmap_populate_hugepages(unsigned long start, unsigned long end,
> return -ENOMEM;
>
> pmd = pmd_offset(pud, addr);
> - if (pmd_none(READ_ONCE(*pmd))) {
> + if (pmd_none(pmdp_get(pmd))) {
> void *p;
>
> p = vmemmap_alloc_block_buf(PMD_SIZE, node, altmap);
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index a0df1e2e155a..d27aa1ebaad6 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -150,7 +150,7 @@ static int vmap_try_huge_pmd(pmd_t *pmd, unsigned long addr, unsigned long end,
> if (!IS_ALIGNED(phys_addr, PMD_SIZE))
> return 0;
>
> - if (pmd_present(*pmd) && !pmd_free_pte_page(pmd, addr))
> + if (pmd_present(pmdp_get(pmd)) && !pmd_free_pte_page(pmd, addr))
> return 0;
>
> return pmd_set_huge(pmd, phys_addr, prot);
> @@ -371,7 +371,7 @@ static void vunmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
> next = pmd_addr_end(addr, end);
>
> cleared = pmd_clear_huge(pmd);
> - if (cleared || pmd_bad(*pmd))
> + if (cleared || pmd_bad(pmdp_get(pmd)))
> *mask |= PGTBL_PMD_MODIFIED;
>
> if (cleared)
> @@ -776,11 +776,11 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
> return NULL;
>
> pmd = pmd_offset(pud, addr);
> - if (pmd_none(*pmd))
> + if (pmd_none(pmdp_get(pmd)))
> return NULL;
> - if (pmd_leaf(*pmd))
> - return pmd_page(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
> - if (WARN_ON_ONCE(pmd_bad(*pmd)))
> + if (pmd_leaf(pmdp_get(pmd)))
> + return pmd_page(pmdp_get(pmd)) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
> + if (WARN_ON_ONCE(pmd_bad(pmdp_get(pmd))))
> return NULL;
>
> ptep = pte_offset_kernel(pmd, addr);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/7] x86/mm: Drop page table entry address output from pxd_ERROR()
2024-09-13 8:44 ` [PATCH 2/7] x86/mm: Drop page table entry address output from pxd_ERROR() Anshuman Khandual
@ 2024-09-13 17:21 ` Dave Hansen
2024-09-16 2:54 ` Anshuman Khandual
0 siblings, 1 reply; 14+ messages in thread
From: Dave Hansen @ 2024-09-13 17:21 UTC (permalink / raw)
To: Anshuman Khandual, linux-mm
Cc: Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
On 9/13/24 01:44, Anshuman Khandual wrote:
> This drops page table entry address output from all pxd_ERROR() definitions
> which now matches with other architectures. This also prevents build issues
> while transitioning into pxdp_get() based page table entry accesses.
Could you be a _little_ more specific than "build issues"? Is it that
you want to do:
void pmd_clear_bad(pmd_t *pmd)
{
- pmd_ERROR(*pmd);
+ pmd_ERROR(pmdp_get(pmd));
pmd_clear(pmd);
}
But the pmd_ERROR() macro would expand that to:
&pmdp_get(pmd)
which is nonsense?
Having the PTEs' kernel addresses _is_ handy, but I guess they're
scrambled on most end users' systems now and anybody that's actively
debugging can just use a kprobe or something to dump the pmd_clear_bad()
argument directly.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/7] x86/mm: Drop page table entry address output from pxd_ERROR()
2024-09-13 17:21 ` Dave Hansen
@ 2024-09-16 2:54 ` Anshuman Khandual
0 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-16 2:54 UTC (permalink / raw)
To: Dave Hansen, linux-mm
Cc: Andrew Morton, David Hildenbrand, Ryan Roberts,
Mike Rapoport (IBM), Arnd Bergmann, x86, linux-m68k,
linux-fsdevel, kasan-dev, linux-kernel, linux-perf-users,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
On 9/13/24 22:51, Dave Hansen wrote:
> On 9/13/24 01:44, Anshuman Khandual wrote:
>> This drops page table entry address output from all pxd_ERROR() definitions
>> which now matches with other architectures. This also prevents build issues
>> while transitioning into pxdp_get() based page table entry accesses.
>
> Could you be a _little_ more specific than "build issues"? Is it that
> you want to do:
>
> void pmd_clear_bad(pmd_t *pmd)
> {
> - pmd_ERROR(*pmd);
> + pmd_ERROR(pmdp_get(pmd));
> pmd_clear(pmd);
> }
>
> But the pmd_ERROR() macro would expand that to:
>
> &pmdp_get(pmd)
>
> which is nonsense?
Yes, that's the one which fails the build with the following warning.
error: lvalue required as unary '&' operand
Will update the commit message with these details about the build problem.
>
> Having the PTEs' kernel addresses _is_ handy, but I guess they're
> scrambled on most end users' systems now and anybody that's actively
> debugging can just use a kprobe or something to dump the pmd_clear_bad()
> argument directly.
Right.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/7] mm: Use ptep_get() for accessing PTE entries
2024-09-13 10:27 ` Ryan Roberts
@ 2024-09-16 3:16 ` Anshuman Khandual
0 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-16 3:16 UTC (permalink / raw)
To: Ryan Roberts, linux-mm
Cc: Andrew Morton, David Hildenbrand, Mike Rapoport (IBM),
Arnd Bergmann, x86, linux-m68k, linux-fsdevel, kasan-dev,
linux-kernel, linux-perf-users
On 9/13/24 15:57, Ryan Roberts wrote:
> On 13/09/2024 09:44, Anshuman Khandual wrote:
>> Convert PTE accesses via ptep_get() helper that defaults as READ_ONCE() but
>> also provides the platform an opportunity to override when required.
>>
>> Cc: Andrew Morton <akpm@linux-foundation.org>
>> Cc: David Hildenbrand <david@redhat.com>
>> Cc: Ryan Roberts <ryan.roberts@arm.com>
>> Cc: "Mike Rapoport (IBM)" <rppt@kernel.org>
>> Cc: linux-mm@kvack.org
>> Cc: linux-kernel@vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> include/linux/pgtable.h | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>> index 2a6a3cccfc36..05e6995c1b93 100644
>> --- a/include/linux/pgtable.h
>> +++ b/include/linux/pgtable.h
>> @@ -1060,7 +1060,7 @@ static inline int pgd_same(pgd_t pgd_a, pgd_t pgd_b)
>> */
>> #define set_pte_safe(ptep, pte) \
>> ({ \
>> - WARN_ON_ONCE(pte_present(*ptep) && !pte_same(*ptep, pte)); \
>> + WARN_ON_ONCE(pte_present(ptep_get(ptep)) && !pte_same(ptep_get(ptep), pte)); \
>
> Suggest reading once into a temporary so that the pte can't change between the 2
> gets. In practice, it's not likely to be a huge problem for this instance since
> its under the PTL so can only be racing with HW update of access and dirty. But
> good practice IMHO:
>
> pte_t __old = ptep_get(ptep); \
> WARN_ON_ONCE(pte_present(__old) && !pte_same(__old, pte)); \
Sure, will change as suggested.
>
> Thanks,
> Ryan
>
>> set_pte(ptep, pte); \
>> })
>>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/7] mm: Use pmdp_get() for accessing PMD entries
2024-09-13 10:38 ` Ryan Roberts
@ 2024-09-16 6:15 ` Anshuman Khandual
0 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2024-09-16 6:15 UTC (permalink / raw)
To: Ryan Roberts, linux-mm
Cc: Andrew Morton, David Hildenbrand, Mike Rapoport (IBM),
Arnd Bergmann, x86, linux-m68k, linux-fsdevel, kasan-dev,
linux-kernel, linux-perf-users, Dimitri Sivanich, Muchun Song,
Andrey Ryabinin, Miaohe Lin, Naoya Horiguchi, Pasha Tatashin,
Dennis Zhou, Tejun Heo, Christoph Lameter, Uladzislau Rezki,
Christoph Hellwig
On 9/13/24 16:08, Ryan Roberts wrote:
> On 13/09/2024 09:44, Anshuman Khandual wrote:
>> Convert PMD accesses via pmdp_get() helper that defaults as READ_ONCE() but
>> also provides the platform an opportunity to override when required.
>>
>> Cc: Dimitri Sivanich <dimitri.sivanich@hpe.com>
>> Cc: Muchun Song <muchun.song@linux.dev>
>> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
>> Cc: Miaohe Lin <linmiaohe@huawei.com>
>> Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
>> Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
>> Cc: Dennis Zhou <dennis@kernel.org>
>> Cc: Tejun Heo <tj@kernel.org>
>> Cc: Christoph Lameter <cl@linux.com>
>> Cc: Uladzislau Rezki <urezki@gmail.com>
>> Cc: Christoph Hellwig <hch@infradead.org>
>> Cc: Andrew Morton <akpm@linux-foundation.org>
>> Cc: David Hildenbrand <david@redhat.com>
>> Cc: Ryan Roberts <ryan.roberts@arm.com>
>> Cc: "Mike Rapoport (IBM)" <rppt@kernel.org>
>> Cc: linux-kernel@vger.kernel.org
>> Cc: linux-fsdevel@vger.kernel.org
>> Cc: linux-mm@kvack.org
>> Cc: kasan-dev@googlegroups.com
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>> drivers/misc/sgi-gru/grufault.c | 4 +--
>> fs/proc/task_mmu.c | 26 +++++++-------
>> include/linux/huge_mm.h | 3 +-
>> include/linux/mm.h | 2 +-
>> include/linux/pgtable.h | 14 ++++----
>> mm/gup.c | 14 ++++----
>> mm/huge_memory.c | 60 ++++++++++++++++-----------------
>> mm/hugetlb_vmemmap.c | 4 +--
>> mm/kasan/init.c | 10 +++---
>> mm/kasan/shadow.c | 4 +--
>> mm/khugepaged.c | 4 +--
>> mm/madvise.c | 6 ++--
>> mm/memory-failure.c | 6 ++--
>> mm/memory.c | 25 +++++++-------
>> mm/mempolicy.c | 4 +--
>> mm/migrate.c | 4 +--
>> mm/migrate_device.c | 10 +++---
>> mm/mlock.c | 6 ++--
>> mm/mprotect.c | 2 +-
>> mm/mremap.c | 4 +--
>> mm/page_table_check.c | 2 +-
>> mm/pagewalk.c | 4 +--
>> mm/percpu.c | 2 +-
>> mm/pgtable-generic.c | 16 ++++-----
>> mm/ptdump.c | 2 +-
>> mm/rmap.c | 2 +-
>> mm/sparse-vmemmap.c | 4 +--
>> mm/vmalloc.c | 12 +++----
>> 28 files changed, 129 insertions(+), 127 deletions(-)
>>
>> diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
>> index 3557d78ee47a..f3d6249b7dfb 100644
>> --- a/drivers/misc/sgi-gru/grufault.c
>> +++ b/drivers/misc/sgi-gru/grufault.c
>> @@ -224,10 +224,10 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
>> goto err;
>>
>> pmdp = pmd_offset(pudp, vaddr);
>> - if (unlikely(pmd_none(*pmdp)))
>> + if (unlikely(pmd_none(pmdp_get(pmdp))))
>> goto err;
>> #ifdef CONFIG_X86_64
>> - if (unlikely(pmd_leaf(*pmdp)))
>> + if (unlikely(pmd_leaf(pmdp_get(pmdp))))
> Just a general comment about multiple gets; before, the compiler most likely
> turned multiple '*pmdp' dereferences into a single actual load. But READ_ONCE()
> inside pmdp_get() ensures you get a load for every call to pmdp_get(). This has
> 2 potential problems:
>
> - More loads could potentially regress speed in some hot paths
>
> - In paths that don't hold an appropriate PTL the multiple loads could race
> with a writer, meaning each load gets a different value. The intent of the code
> is usually that each check is operating on the same value.
Makes sense, above two concerns are potential problems I guess.
>
> For the ptep_get() conversion, I solved this by reading into a temporary once
> then using the temporary for the comparisons.
Alright.
>
> I'm not sure if these are real problems in practice, but seems safest to
> continue to follow this established pattern?
Yes, will make the necessary changes across the series which might create some
amount of code churn but seems like it would be worth. Planning to add old_pxd
local variables when required and load them from the address, as soon as 'pxd'
pointer becomes valid.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-09-16 6:15 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-13 8:44 [PATCH 0/7] mm: Use pxdp_get() for accessing page table entries Anshuman Khandual
2024-09-13 8:44 ` [PATCH 1/7] m68k/mm: Change pmd_val() Anshuman Khandual
2024-09-13 8:44 ` [PATCH 2/7] x86/mm: Drop page table entry address output from pxd_ERROR() Anshuman Khandual
2024-09-13 17:21 ` Dave Hansen
2024-09-16 2:54 ` Anshuman Khandual
2024-09-13 8:44 ` [PATCH 3/7] mm: Use ptep_get() for accessing PTE entries Anshuman Khandual
2024-09-13 10:27 ` Ryan Roberts
2024-09-16 3:16 ` Anshuman Khandual
2024-09-13 8:44 ` [PATCH 4/7] mm: Use pmdp_get() for accessing PMD entries Anshuman Khandual
2024-09-13 10:38 ` Ryan Roberts
2024-09-16 6:15 ` Anshuman Khandual
2024-09-13 8:44 ` [PATCH 5/7] mm: Use pudp_get() for accessing PUD entries Anshuman Khandual
2024-09-13 8:44 ` [PATCH 6/7] mm: Use p4dp_get() for accessing P4D entries Anshuman Khandual
2024-09-13 8:44 ` [PATCH 7/7] mm: Use pgdp_get() for accessing PGD entries Anshuman Khandual
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).