From 87ee083dbc70a1e4ba5a4f1b3b0593eadf8bf229 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Mon, 2 Mar 2020 15:26:44 -0400 Subject: [PATCH] BACKPORT: mm/hmm: do not call hmm_vma_walk_hole() while holding a spinlock This eventually calls into handle_mm_fault() which is a sleeping function. Release the lock first. hmm_vma_walk_hole() does not touch the contents of the PUD, so it does not need the lock. Moto-CRs-Fixed:(CR) Link: https://lore.kernel.org/r/20200311183506.3997-4-jgg@ziepe.ca/ Fixes: 3afc423632a1 ("mm: pagewalk: add p4d_entry() and pgd_entry()") Cc: Steven Price Reviewed-by: Ralph Campbell Reviewed-by: Steven Price Reviewed-by: Christoph Hellwig Change-Id: I4dd851a2fcf242877ae7acd082f3521e7202d258 Signed-off-by: Jason Gunthorpe (cherry picked from commit 05fc1df95e5dc09802813bab9c1e718f1e419d93) Bug: 261052246 Signed-off-by: Kalesh Singh Reviewed-on: https://gerrit.mot.com/2491784 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Xiangpo Zhao Submit-Approved: Jira Key --- mm/hmm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mm/hmm.c b/mm/hmm.c index 231de978d647..795faf021085 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -671,8 +671,8 @@ static int hmm_vma_walk_pud(pud_t *pudp, unsigned long start, unsigned long end, pud = READ_ONCE(*pudp); if (pud_none(pud)) { - ret = hmm_vma_walk_hole(start, end, walk); - goto out_unlock; + spin_unlock(ptl); + return hmm_vma_walk_hole(start, end, walk); } if (pud_huge(pud) && pud_devmap(pud)) { @@ -681,8 +681,8 @@ static int hmm_vma_walk_pud(pud_t *pudp, unsigned long start, unsigned long end, bool fault, write_fault; if (!pud_present(pud)) { - ret = hmm_vma_walk_hole(start, end, walk); - goto out_unlock; + spin_unlock(ptl); + return hmm_vma_walk_hole(start, end, walk); } i = (addr - range->start) >> PAGE_SHIFT; @@ -693,9 +693,9 @@ static int hmm_vma_walk_pud(pud_t *pudp, unsigned long start, unsigned long end, hmm_range_need_fault(hmm_vma_walk, pfns, npages, cpu_flags, &fault, &write_fault); if (fault || write_fault) { - ret = hmm_vma_walk_hole_(addr, end, fault, - write_fault, walk); - goto out_unlock; + spin_unlock(ptl); + return hmm_vma_walk_hole_(addr, end, fault, write_fault, + walk); } pfn = pud_pfn(pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);