• W
    mm/hwpoison: fix race against poison thp · 0cea3fdc
    Wanpeng Li 提交于
    There is a race between hwpoison page and unpoison page, memory_failure
    set the page hwpoison and increase num_poisoned_pages without hold page
    lock, and one page count will be accounted against thp for
    num_poisoned_pages.  However, unpoison can occur before memory_failure
    hold page lock and split transparent hugepage, unpoison will decrease
    num_poisoned_pages by 1 << compound_order since memory_failure has not yet
    split transparent hugepage with page lock held.  That means we account one
    page for hwpoison and 1 << compound_order for unpoison.  This patch fix it
    by inserting a PageTransHuge check before doing TestClearPageHWPoison,
    unpoison failed without clearing PageHWPoison and decreasing
    num_poisoned_pages.
    
                A                                                 	B
        	memory_failue
            TestSetPageHWPoison(p);
            if (PageHuge(p))
                nr_pages = 1 << compound_order(hpage);
            else
                nr_pages = 1;
            atomic_long_add(nr_pages, &num_poisoned_pages);
                                                                unpoison_memory
    	                                                        nr_pages = 1<< compound_trans_order(page);
                                                                if(TestClearPageHWPoison(p))
                                                                atomic_long_sub(nr_pages, &num_poisoned_pages);
            lock page
            if (!PageHWPoison(p))
            	unlock page and return
            hwpoison_user_mappings
            if (PageTransHuge(hpage))
            	split_huge_page(hpage);
    Signed-off-by: NWanpeng Li <liwanp@linux.vnet.ibm.com>
    Suggested-by: NNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
    Cc: Andi Kleen <andi@firstfloor.org>
    Cc: Tony Luck <tony.luck@intel.com>
    Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    0cea3fdc
memory-failure.c 45.6 KB