thp: bail out gup_fast on splitting pmd
Force gup_fast to take the slow path and block if the pmd is splitting, not only if it's none. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: Rik van Riel <riel@redhat.com> Acked-by: Mel Gorman <mel@csn.ul.ie> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
db3eb96f4e
commit
64cc6ae001
1 changed files with 12 additions and 1 deletions
|
@ -160,7 +160,18 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
|
|||
pmd_t pmd = *pmdp;
|
||||
|
||||
next = pmd_addr_end(addr, end);
|
||||
if (pmd_none(pmd))
|
||||
/*
|
||||
* The pmd_trans_splitting() check below explains why
|
||||
* pmdp_splitting_flush has to flush the tlb, to stop
|
||||
* this gup-fast code from running while we set the
|
||||
* splitting bit in the pmd. Returning zero will take
|
||||
* the slow path that will call wait_split_huge_page()
|
||||
* if the pmd is still in splitting state. gup-fast
|
||||
* can't because it has irq disabled and
|
||||
* wait_split_huge_page() would never return as the
|
||||
* tlb flush IPI wouldn't run.
|
||||
*/
|
||||
if (pmd_none(pmd) || pmd_trans_splitting(pmd))
|
||||
return 0;
|
||||
if (unlikely(pmd_large(pmd))) {
|
||||
if (!gup_huge_pmd(pmd, addr, next, write, pages, nr))
|
||||
|
|
Loading…
Reference in a new issue