summaryrefslogtreecommitdiff
path: root/mm/hmm.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@mellanox.com>2020-03-02 15:26:44 -0400
committerJason Gunthorpe <jgg@mellanox.com>2020-03-26 14:33:37 -0300
commit05fc1df95e5dc09802813bab9c1e718f1e419d93 (patch)
treeadcaddd7bac8e2f5aa139d0075b096cbc2e4dfd1 /mm/hmm.c
parentdfdc22078f3f064d2659acdc42d886834f3a3863 (diff)
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. Fixes: 3afc423632a1 ("mm: pagewalk: add p4d_entry() and pgd_entry()") Cc: Steven Price <steven.price@arm.com> Reviewed-by: Ralph Campbell <rcampbell@nvidia.com> Reviewed-by: Steven Price <steven.price@arm.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'mm/hmm.c')
-rw-r--r--mm/hmm.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/mm/hmm.c b/mm/hmm.c
index 35f85424176d..0e7a57246f03 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -491,8 +491,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, -1, walk);
- goto out_unlock;
+ spin_unlock(ptl);
+ return hmm_vma_walk_hole(start, end, -1, walk);
}
if (pud_huge(pud) && pud_devmap(pud)) {
@@ -501,8 +501,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, -1, walk);
- goto out_unlock;
+ spin_unlock(ptl);
+ return hmm_vma_walk_hole(start, end, -1, walk);
}
i = (addr - range->start) >> PAGE_SHIFT;
@@ -513,9 +513,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);