mirror of https://gitee.com/openkylin/linux.git
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: 3afc423632
("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>
This commit is contained in:
parent
dfdc22078f
commit
05fc1df95e
14
mm/hmm.c
14
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);
|
pud = READ_ONCE(*pudp);
|
||||||
if (pud_none(pud)) {
|
if (pud_none(pud)) {
|
||||||
ret = hmm_vma_walk_hole(start, end, -1, walk);
|
spin_unlock(ptl);
|
||||||
goto out_unlock;
|
return hmm_vma_walk_hole(start, end, -1, walk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pud_huge(pud) && pud_devmap(pud)) {
|
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;
|
bool fault, write_fault;
|
||||||
|
|
||||||
if (!pud_present(pud)) {
|
if (!pud_present(pud)) {
|
||||||
ret = hmm_vma_walk_hole(start, end, -1, walk);
|
spin_unlock(ptl);
|
||||||
goto out_unlock;
|
return hmm_vma_walk_hole(start, end, -1, walk);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = (addr - range->start) >> PAGE_SHIFT;
|
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,
|
hmm_range_need_fault(hmm_vma_walk, pfns, npages,
|
||||||
cpu_flags, &fault, &write_fault);
|
cpu_flags, &fault, &write_fault);
|
||||||
if (fault || write_fault) {
|
if (fault || write_fault) {
|
||||||
ret = hmm_vma_walk_hole_(addr, end, fault,
|
spin_unlock(ptl);
|
||||||
write_fault, walk);
|
return hmm_vma_walk_hole_(addr, end, fault, write_fault,
|
||||||
goto out_unlock;
|
walk);
|
||||||
}
|
}
|
||||||
|
|
||||||
pfn = pud_pfn(pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
|
pfn = pud_pfn(pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
|
||||||
|
|
Loading…
Reference in New Issue