nr_nodes--)
 
 #ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
-static void destroy_compound_gigantic_page(struct page *page,
-                                       unsigned int order)
+static void __destroy_compound_gigantic_page(struct page *page,
+                                       unsigned int order, bool demote)
 {
        int i;
        int nr_pages = 1 << order;
        for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
                p->mapping = NULL;
                clear_compound_head(p);
-               set_page_refcounted(p);
+               if (!demote)
+                       set_page_refcounted(p);
        }
 
        set_compound_order(page, 0);
        __ClearPageHead(page);
 }
 
+static void destroy_compound_gigantic_page(struct page *page,
+                                       unsigned int order)
+{
+       __destroy_compound_gigantic_page(page, order, false);
+}
+
 static void free_gigantic_page(struct page *page, unsigned int order)
 {
        /*
 
 /*
  * Remove hugetlb page from lists, and update dtor so that page appears
- * as just a compound page.  A reference is held on the page.
+ * as just a compound page.
+ *
+ * A reference is held on the page, except in the case of demote.
  *
  * Must be called with hugetlb lock held.
  */
-static void remove_hugetlb_page(struct hstate *h, struct page *page,
-                                                       bool adjust_surplus)
+static void __remove_hugetlb_page(struct hstate *h, struct page *page,
+                                                       bool adjust_surplus,
+                                                       bool demote)
 {
        int nid = page_to_nid(page);
 
         *
         * This handles the case where more than one ref is held when and
         * after update_and_free_page is called.
+        *
+        * In the case of demote we do not ref count the page as it will soon
+        * be turned into a page of smaller size.
         */
-       set_page_refcounted(page);
+       if (!demote)
+               set_page_refcounted(page);
        if (hstate_is_gigantic(h))
                set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
        else
        h->nr_huge_pages_node[nid]--;
 }
 
+static void remove_hugetlb_page(struct hstate *h, struct page *page,
+                                                       bool adjust_surplus)
+{
+       __remove_hugetlb_page(h, page, adjust_surplus, false);
+}
+
 static void add_hugetlb_page(struct hstate *h, struct page *page,
                             bool adjust_surplus)
 {
        spin_unlock_irq(&hugetlb_lock);
 }
 
-static bool prep_compound_gigantic_page(struct page *page, unsigned int order)
+static bool __prep_compound_gigantic_page(struct page *page, unsigned int order,
+                                                               bool demote)
 {
        int i, j;
        int nr_pages = 1 << order;
                 * the set of pages can not be converted to a gigantic page.
                 * The caller who allocated the pages should then discard the
                 * pages using the appropriate free interface.
+                *
+                * In the case of demote, the ref count will be zero.
                 */
-               if (!page_ref_freeze(p, 1)) {
-                       pr_warn("HugeTLB page can not be used due to unexpected inflated ref count\n");
-                       goto out_error;
+               if (!demote) {
+                       if (!page_ref_freeze(p, 1)) {
+                               pr_warn("HugeTLB page can not be used due to unexpected inflated ref count\n");
+                               goto out_error;
+                       }
+               } else {
+                       VM_BUG_ON_PAGE(page_count(p), p);
                }
                set_page_count(p, 0);
                set_compound_head(p, page);
        return false;
 }
 
+static bool prep_compound_gigantic_page(struct page *page, unsigned int order)
+{
+       return __prep_compound_gigantic_page(page, order, false);
+}
+
 /*
  * PageHuge() only returns true for hugetlbfs pages, but not for normal or
  * transparent huge pages.  See the PageTransHuge() documentation for more