nr_pages = 1 << compound_order(page);
  
        if (!get_page_unless_zero(page)) {
+               /*
+                * Since HWPoisoned hugepage should have non-zero refcount,
+                * race between memory failure and unpoison seems to happen.
+                * In such case unpoison fails and memory failure runs
+                * to the end.
+                */
+               if (PageHuge(page)) {
+                       pr_debug("MCE: Memory failure is now running on free hugepage %#lx\n", pfn);
+                       return 0;
+               }
                if (TestClearPageHWPoison(p))
                        atomic_long_sub(nr_pages, &mce_bad_pages);
 -              pr_debug("MCE: Software-unpoisoned free page %#lx\n", pfn);
 +              pr_info("MCE: Software-unpoisoned free page %#lx\n", pfn);
                return 0;
        }
  
         * the free buddy page pool.
         */
        if (TestClearPageHWPoison(page)) {
 -              pr_debug("MCE: Software-unpoisoned page %#lx\n", pfn);
 +              pr_info("MCE: Software-unpoisoned page %#lx\n", pfn);
                atomic_long_sub(nr_pages, &mce_bad_pages);
                freeit = 1;
+               if (PageHuge(page))
+                       clear_page_hwpoison_huge_page(page);
        }
-       if (PageHuge(p))
-               clear_page_hwpoison_huge_page(page);
        unlock_page(page);
  
        put_page(page);
         * was free.
         */
        set_migratetype_isolate(p);
+       /*
+        * When the target page is a free hugepage, just remove it
+        * from free hugepage list.
+        */
        if (!get_page_unless_zero(compound_head(p))) {
-               if (is_free_buddy_page(p)) {
+               if (PageHuge(p)) {
 -                      pr_debug("get_any_page: %#lx free huge page\n", pfn);
++                      pr_info("get_any_page: %#lx free huge page\n", pfn);
+                       ret = dequeue_hwpoisoned_huge_page(compound_head(p));
+               } else if (is_free_buddy_page(p)) {
 -                      pr_debug("get_any_page: %#lx free buddy page\n", pfn);
 +                      pr_info("get_any_page: %#lx free buddy page\n", pfn);
                        /* Set hwpoison bit while page is still isolated */
                        SetPageHWPoison(p);
                        ret = 0;