Don't fetch the pte value using lockless page table walk. Instead use the value 
from the
caller. hash_preload is called with ptl lock held. So it is safe to use the
pte_t address directly.

Signed-off-by: Aneesh Kumar K.V <aneesh.ku...@linux.ibm.com>
---
 arch/powerpc/mm/book3s64/hash_utils.c | 27 +++++----------------------
 1 file changed, 5 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/hash_utils.c 
b/arch/powerpc/mm/book3s64/hash_utils.c
index 525eac4ee2c2..3d727f73a8db 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1546,14 +1546,11 @@ static bool should_hash_preload(struct mm_struct *mm, 
unsigned long ea)
 }
 #endif
 
-static void hash_preload(struct mm_struct *mm, unsigned long ea,
+static void hash_preload(struct mm_struct *mm, pte_t *ptep, unsigned long ea,
                         bool is_exec, unsigned long trap)
 {
-       int hugepage_shift;
        unsigned long vsid;
        pgd_t *pgdir;
-       pte_t *ptep;
-       unsigned long flags;
        int rc, ssize, update_flags = 0;
        unsigned long access = _PAGE_PRESENT | _PAGE_READ | (is_exec ? 
_PAGE_EXEC : 0);
 
@@ -1575,30 +1572,18 @@ static void hash_preload(struct mm_struct *mm, unsigned 
long ea,
        vsid = get_user_vsid(&mm->context, ea, ssize);
        if (!vsid)
                return;
-       /*
-        * Hash doesn't like irqs. Walking linux page table with irq disabled
-        * saves us from holding multiple locks.
-        */
-       local_irq_save(flags);
 
-       /*
-        * THP pages use update_mmu_cache_pmd. We don't do
-        * hash preload there. Hence can ignore THP here
-        */
-       ptep = find_current_mm_pte(pgdir, ea, NULL, &hugepage_shift);
-       if (!ptep)
-               goto out_exit;
-
-       WARN_ON(hugepage_shift);
 #ifdef CONFIG_PPC_64K_PAGES
        /* If either H_PAGE_4K_PFN or cache inhibited is set (and we are on
         * a 64K kernel), then we don't preload, hash_page() will take
         * care of it once we actually try to access the page.
         * That way we don't have to duplicate all of the logic for segment
         * page size demotion here
+        * Called with  PTL held, hence can be sure the value won't change in
+        * between.
         */
        if ((pte_val(*ptep) & H_PAGE_4K_PFN) || pte_ci(*ptep))
-               goto out_exit;
+               return;
 #endif /* CONFIG_PPC_64K_PAGES */
 
        /* Is that local to this CPU ? */
@@ -1623,8 +1608,6 @@ static void hash_preload(struct mm_struct *mm, unsigned 
long ea,
                                   mm_ctx_user_psize(&mm->context),
                                   mm_ctx_user_psize(&mm->context),
                                   pte_val(*ptep));
-out_exit:
-       local_irq_restore(flags);
 }
 
 /*
@@ -1675,7 +1658,7 @@ void update_mmu_cache(struct vm_area_struct *vma, 
unsigned long address,
                return;
        }
 
-       hash_preload(vma->vm_mm, address, is_exec, trap);
+       hash_preload(vma->vm_mm, ptep, address, is_exec, trap);
 }
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-- 
2.26.2

Reply via email to