Merge tag 'thermal-5.17-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafae...
[linux-2.6-microblaze.git] / mm / huge_memory.c
index e548334..406a3c2 100644 (file)
@@ -1322,7 +1322,7 @@ vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf)
         * We can only reuse the page if nobody else maps the huge page or it's
         * part.
         */
-       if (reuse_swap_page(page, NULL)) {
+       if (reuse_swap_page(page)) {
                pmd_t entry;
                entry = pmd_mkyoung(orig_pmd);
                entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
@@ -2542,38 +2542,28 @@ int total_mapcount(struct page *page)
  * need full accuracy to avoid breaking page pinning, because
  * page_trans_huge_mapcount() is slower than page_mapcount().
  */
-int page_trans_huge_mapcount(struct page *page, int *total_mapcount)
+int page_trans_huge_mapcount(struct page *page)
 {
-       int i, ret, _total_mapcount, mapcount;
+       int i, ret;
 
        /* hugetlbfs shouldn't call it */
        VM_BUG_ON_PAGE(PageHuge(page), page);
 
-       if (likely(!PageTransCompound(page))) {
-               mapcount = atomic_read(&page->_mapcount) + 1;
-               if (total_mapcount)
-                       *total_mapcount = mapcount;
-               return mapcount;
-       }
+       if (likely(!PageTransCompound(page)))
+               return atomic_read(&page->_mapcount) + 1;
 
        page = compound_head(page);
 
-       _total_mapcount = ret = 0;
+       ret = 0;
        for (i = 0; i < thp_nr_pages(page); i++) {
-               mapcount = atomic_read(&page[i]._mapcount) + 1;
+               int mapcount = atomic_read(&page[i]._mapcount) + 1;
                ret = max(ret, mapcount);
-               _total_mapcount += mapcount;
        }
-       if (PageDoubleMap(page)) {
+
+       if (PageDoubleMap(page))
                ret -= 1;
-               _total_mapcount -= thp_nr_pages(page);
-       }
-       mapcount = compound_mapcount(page);
-       ret += mapcount;
-       _total_mapcount += mapcount;
-       if (total_mapcount)
-               *total_mapcount = _total_mapcount;
-       return ret;
+
+       return ret + compound_mapcount(page);
 }
 
 /* Racy check whether the huge page can be split */
@@ -2614,6 +2604,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
 {
        struct page *head = compound_head(page);
        struct deferred_split *ds_queue = get_deferred_split_queue(head);
+       XA_STATE(xas, &head->mapping->i_pages, head->index);
        struct anon_vma *anon_vma = NULL;
        struct address_space *mapping = NULL;
        int extra_pins, ret;
@@ -2652,6 +2643,13 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
                        goto out;
                }
 
+               xas_split_alloc(&xas, head, compound_order(head),
+                               mapping_gfp_mask(mapping) & GFP_RECLAIM_MASK);
+               if (xas_error(&xas)) {
+                       ret = xas_error(&xas);
+                       goto out;
+               }
+
                anon_vma = NULL;
                i_mmap_lock_read(mapping);
 
@@ -2681,13 +2679,12 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
        /* block interrupt reentry in xa_lock and spinlock */
        local_irq_disable();
        if (mapping) {
-               XA_STATE(xas, &mapping->i_pages, page_index(head));
-
                /*
                 * Check if the head page is present in page cache.
                 * We assume all tail are present too, if head is there.
                 */
-               xa_lock(&mapping->i_pages);
+               xas_lock(&xas);
+               xas_reset(&xas);
                if (xas_load(&xas) != head)
                        goto fail;
        }
@@ -2703,6 +2700,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
                if (mapping) {
                        int nr = thp_nr_pages(head);
 
+                       xas_split(&xas, head, thp_order(head));
                        if (PageSwapBacked(head)) {
                                __mod_lruvec_page_state(head, NR_SHMEM_THPS,
                                                        -nr);
@@ -2719,7 +2717,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list)
                spin_unlock(&ds_queue->split_queue_lock);
 fail:
                if (mapping)
-                       xa_unlock(&mapping->i_pages);
+                       xas_unlock(&xas);
                local_irq_enable();
                remap_page(head, thp_nr_pages(head));
                ret = -EBUSY;
@@ -2733,6 +2731,8 @@ out_unlock:
        if (mapping)
                i_mmap_unlock_read(mapping);
 out:
+       /* Free any memory we didn't use */
+       xas_nomem(&xas, 0);
        count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED);
        return ret;
 }