From dc85bb804da5aebcb2ab41cc7cd0cf42b36c02a8 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Thu, 13 Jan 2011 15:46:42 -0800 Subject: [PATCH] --- yaml --- r: 230760 b: refs/heads/master c: 64cc6ae001d70bc59e5f854e6b5678f59110df16 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/x86/mm/gup.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index f99250bb7a40..a53261fdc3cf 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: db3eb96f4e6281b84dd33c8980dacc27f2efe177 +refs/heads/master: 64cc6ae001d70bc59e5f854e6b5678f59110df16 diff --git a/trunk/arch/x86/mm/gup.c b/trunk/arch/x86/mm/gup.c index 06f56fcf9a77..269aa53932e0 100644 --- a/trunk/arch/x86/mm/gup.c +++ b/trunk/arch/x86/mm/gup.c @@ -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))