diff options
-rw-r--r-- | include/linux/pagemap.h | 13 | ||||
-rw-r--r-- | mm/filemap.c | 146 | ||||
-rw-r--r-- | mm/huge_memory.c | 3 | ||||
-rw-r--r-- | mm/khugepaged.c | 4 | ||||
-rw-r--r-- | mm/memfd.c | 2 | ||||
-rw-r--r-- | mm/migrate.c | 2 | ||||
-rw-r--r-- | mm/shmem.c | 2 | ||||
-rw-r--r-- | mm/swap_state.c | 4 |
8 files changed, 94 insertions, 82 deletions
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 9ec3544baee2..fe0b29bf2df7 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -333,19 +333,6 @@ static inline struct page *grab_cache_page_nowait(struct address_space *mapping, | |||
333 | mapping_gfp_mask(mapping)); | 333 | mapping_gfp_mask(mapping)); |
334 | } | 334 | } |
335 | 335 | ||
336 | static inline struct page *find_subpage(struct page *page, pgoff_t offset) | ||
337 | { | ||
338 | unsigned long mask; | ||
339 | |||
340 | if (PageHuge(page)) | ||
341 | return page; | ||
342 | |||
343 | VM_BUG_ON_PAGE(PageTail(page), page); | ||
344 | |||
345 | mask = (1UL << compound_order(page)) - 1; | ||
346 | return page + (offset & mask); | ||
347 | } | ||
348 | |||
349 | struct page *find_get_entry(struct address_space *mapping, pgoff_t offset); | 336 | struct page *find_get_entry(struct address_space *mapping, pgoff_t offset); |
350 | struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset); | 337 | struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset); |
351 | unsigned find_get_entries(struct address_space *mapping, pgoff_t start, | 338 | unsigned find_get_entries(struct address_space *mapping, pgoff_t start, |
diff --git a/mm/filemap.c b/mm/filemap.c index df2006ba0cfa..6dd9a2274c80 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -281,11 +281,11 @@ EXPORT_SYMBOL(delete_from_page_cache); | |||
281 | * @pvec: pagevec with pages to delete | 281 | * @pvec: pagevec with pages to delete |
282 | * | 282 | * |
283 | * The function walks over mapping->i_pages and removes pages passed in @pvec | 283 | * The function walks over mapping->i_pages and removes pages passed in @pvec |
284 | * from the mapping. The function expects @pvec to be sorted by page index | 284 | * from the mapping. The function expects @pvec to be sorted by page index. |
285 | * and is optimised for it to be dense. | ||
286 | * It tolerates holes in @pvec (mapping entries at those indices are not | 285 | * It tolerates holes in @pvec (mapping entries at those indices are not |
287 | * modified). The function expects only THP head pages to be present in the | 286 | * modified). The function expects only THP head pages to be present in the |
288 | * @pvec. | 287 | * @pvec and takes care to delete all corresponding tail pages from the |
288 | * mapping as well. | ||
289 | * | 289 | * |
290 | * The function expects the i_pages lock to be held. | 290 | * The function expects the i_pages lock to be held. |
291 | */ | 291 | */ |
@@ -294,44 +294,40 @@ static void page_cache_delete_batch(struct address_space *mapping, | |||
294 | { | 294 | { |
295 | XA_STATE(xas, &mapping->i_pages, pvec->pages[0]->index); | 295 | XA_STATE(xas, &mapping->i_pages, pvec->pages[0]->index); |
296 | int total_pages = 0; | 296 | int total_pages = 0; |
297 | int i = 0; | 297 | int i = 0, tail_pages = 0; |
298 | struct page *page; | 298 | struct page *page; |
299 | 299 | ||
300 | mapping_set_update(&xas, mapping); | 300 | mapping_set_update(&xas, mapping); |
301 | xas_for_each(&xas, page, ULONG_MAX) { | 301 | xas_for_each(&xas, page, ULONG_MAX) { |
302 | if (i >= pagevec_count(pvec)) | 302 | if (i >= pagevec_count(pvec) && !tail_pages) |
303 | break; | 303 | break; |
304 | |||
305 | /* A swap/dax/shadow entry got inserted? Skip it. */ | ||
306 | if (xa_is_value(page)) | 304 | if (xa_is_value(page)) |
307 | continue; | 305 | continue; |
308 | /* | 306 | if (!tail_pages) { |
309 | * A page got inserted in our range? Skip it. We have our | 307 | /* |
310 | * pages locked so they are protected from being removed. | 308 | * Some page got inserted in our range? Skip it. We |
311 | * If we see a page whose index is higher than ours, it | 309 | * have our pages locked so they are protected from |
312 | * means our page has been removed, which shouldn't be | 310 | * being removed. |
313 | * possible because we're holding the PageLock. | 311 | */ |
314 | */ | 312 | if (page != pvec->pages[i]) { |
315 | if (page != pvec->pages[i]) { | 313 | VM_BUG_ON_PAGE(page->index > |
316 | VM_BUG_ON_PAGE(page->index > pvec->pages[i]->index, | 314 | pvec->pages[i]->index, page); |
317 | page); | 315 | continue; |
318 | continue; | 316 | } |
319 | } | 317 | WARN_ON_ONCE(!PageLocked(page)); |
320 | 318 | if (PageTransHuge(page) && !PageHuge(page)) | |
321 | WARN_ON_ONCE(!PageLocked(page)); | 319 | tail_pages = HPAGE_PMD_NR - 1; |
322 | |||
323 | if (page->index == xas.xa_index) | ||
324 | page->mapping = NULL; | 320 | page->mapping = NULL; |
325 | /* Leave page->index set: truncation lookup relies on it */ | 321 | /* |
326 | 322 | * Leave page->index set: truncation lookup relies | |
327 | /* | 323 | * upon it |
328 | * Move to the next page in the vector if this is a regular | 324 | */ |
329 | * page or the index is of the last sub-page of this compound | ||
330 | * page. | ||
331 | */ | ||
332 | if (page->index + (1UL << compound_order(page)) - 1 == | ||
333 | xas.xa_index) | ||
334 | i++; | 325 | i++; |
326 | } else { | ||
327 | VM_BUG_ON_PAGE(page->index + HPAGE_PMD_NR - tail_pages | ||
328 | != pvec->pages[i]->index, page); | ||
329 | tail_pages--; | ||
330 | } | ||
335 | xas_store(&xas, NULL); | 331 | xas_store(&xas, NULL); |
336 | total_pages++; | 332 | total_pages++; |
337 | } | 333 | } |
@@ -1498,7 +1494,7 @@ EXPORT_SYMBOL(page_cache_prev_miss); | |||
1498 | struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) | 1494 | struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) |
1499 | { | 1495 | { |
1500 | XA_STATE(xas, &mapping->i_pages, offset); | 1496 | XA_STATE(xas, &mapping->i_pages, offset); |
1501 | struct page *page; | 1497 | struct page *head, *page; |
1502 | 1498 | ||
1503 | rcu_read_lock(); | 1499 | rcu_read_lock(); |
1504 | repeat: | 1500 | repeat: |
@@ -1513,19 +1509,25 @@ repeat: | |||
1513 | if (!page || xa_is_value(page)) | 1509 | if (!page || xa_is_value(page)) |
1514 | goto out; | 1510 | goto out; |
1515 | 1511 | ||
1516 | if (!page_cache_get_speculative(page)) | 1512 | head = compound_head(page); |
1513 | if (!page_cache_get_speculative(head)) | ||
1514 | goto repeat; | ||
1515 | |||
1516 | /* The page was split under us? */ | ||
1517 | if (compound_head(page) != head) { | ||
1518 | put_page(head); | ||
1517 | goto repeat; | 1519 | goto repeat; |
1520 | } | ||
1518 | 1521 | ||
1519 | /* | 1522 | /* |
1520 | * Has the page moved or been split? | 1523 | * Has the page moved? |
1521 | * This is part of the lockless pagecache protocol. See | 1524 | * This is part of the lockless pagecache protocol. See |
1522 | * include/linux/pagemap.h for details. | 1525 | * include/linux/pagemap.h for details. |
1523 | */ | 1526 | */ |
1524 | if (unlikely(page != xas_reload(&xas))) { | 1527 | if (unlikely(page != xas_reload(&xas))) { |
1525 | put_page(page); | 1528 | put_page(head); |
1526 | goto repeat; | 1529 | goto repeat; |
1527 | } | 1530 | } |
1528 | page = find_subpage(page, offset); | ||
1529 | out: | 1531 | out: |
1530 | rcu_read_unlock(); | 1532 | rcu_read_unlock(); |
1531 | 1533 | ||
@@ -1707,6 +1709,7 @@ unsigned find_get_entries(struct address_space *mapping, | |||
1707 | 1709 | ||
1708 | rcu_read_lock(); | 1710 | rcu_read_lock(); |
1709 | xas_for_each(&xas, page, ULONG_MAX) { | 1711 | xas_for_each(&xas, page, ULONG_MAX) { |
1712 | struct page *head; | ||
1710 | if (xas_retry(&xas, page)) | 1713 | if (xas_retry(&xas, page)) |
1711 | continue; | 1714 | continue; |
1712 | /* | 1715 | /* |
@@ -1717,13 +1720,17 @@ unsigned find_get_entries(struct address_space *mapping, | |||
1717 | if (xa_is_value(page)) | 1720 | if (xa_is_value(page)) |
1718 | goto export; | 1721 | goto export; |
1719 | 1722 | ||
1720 | if (!page_cache_get_speculative(page)) | 1723 | head = compound_head(page); |
1724 | if (!page_cache_get_speculative(head)) | ||
1721 | goto retry; | 1725 | goto retry; |
1722 | 1726 | ||
1723 | /* Has the page moved or been split? */ | 1727 | /* The page was split under us? */ |
1728 | if (compound_head(page) != head) | ||
1729 | goto put_page; | ||
1730 | |||
1731 | /* Has the page moved? */ | ||
1724 | if (unlikely(page != xas_reload(&xas))) | 1732 | if (unlikely(page != xas_reload(&xas))) |
1725 | goto put_page; | 1733 | goto put_page; |
1726 | page = find_subpage(page, xas.xa_index); | ||
1727 | 1734 | ||
1728 | export: | 1735 | export: |
1729 | indices[ret] = xas.xa_index; | 1736 | indices[ret] = xas.xa_index; |
@@ -1732,7 +1739,7 @@ export: | |||
1732 | break; | 1739 | break; |
1733 | continue; | 1740 | continue; |
1734 | put_page: | 1741 | put_page: |
1735 | put_page(page); | 1742 | put_page(head); |
1736 | retry: | 1743 | retry: |
1737 | xas_reset(&xas); | 1744 | xas_reset(&xas); |
1738 | } | 1745 | } |
@@ -1774,27 +1781,33 @@ unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start, | |||
1774 | 1781 | ||
1775 | rcu_read_lock(); | 1782 | rcu_read_lock(); |
1776 | xas_for_each(&xas, page, end) { | 1783 | xas_for_each(&xas, page, end) { |
1784 | struct page *head; | ||
1777 | if (xas_retry(&xas, page)) | 1785 | if (xas_retry(&xas, page)) |
1778 | continue; | 1786 | continue; |
1779 | /* Skip over shadow, swap and DAX entries */ | 1787 | /* Skip over shadow, swap and DAX entries */ |
1780 | if (xa_is_value(page)) | 1788 | if (xa_is_value(page)) |
1781 | continue; | 1789 | continue; |
1782 | 1790 | ||
1783 | if (!page_cache_get_speculative(page)) | 1791 | head = compound_head(page); |
1792 | if (!page_cache_get_speculative(head)) | ||
1784 | goto retry; | 1793 | goto retry; |
1785 | 1794 | ||
1786 | /* Has the page moved or been split? */ | 1795 | /* The page was split under us? */ |
1796 | if (compound_head(page) != head) | ||
1797 | goto put_page; | ||
1798 | |||
1799 | /* Has the page moved? */ | ||
1787 | if (unlikely(page != xas_reload(&xas))) | 1800 | if (unlikely(page != xas_reload(&xas))) |
1788 | goto put_page; | 1801 | goto put_page; |
1789 | 1802 | ||
1790 | pages[ret] = find_subpage(page, xas.xa_index); | 1803 | pages[ret] = page; |
1791 | if (++ret == nr_pages) { | 1804 | if (++ret == nr_pages) { |
1792 | *start = xas.xa_index + 1; | 1805 | *start = xas.xa_index + 1; |
1793 | goto out; | 1806 | goto out; |
1794 | } | 1807 | } |
1795 | continue; | 1808 | continue; |
1796 | put_page: | 1809 | put_page: |
1797 | put_page(page); | 1810 | put_page(head); |
1798 | retry: | 1811 | retry: |
1799 | xas_reset(&xas); | 1812 | xas_reset(&xas); |
1800 | } | 1813 | } |
@@ -1839,6 +1852,7 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, | |||
1839 | 1852 | ||
1840 | rcu_read_lock(); | 1853 | rcu_read_lock(); |
1841 | for (page = xas_load(&xas); page; page = xas_next(&xas)) { | 1854 | for (page = xas_load(&xas); page; page = xas_next(&xas)) { |
1855 | struct page *head; | ||
1842 | if (xas_retry(&xas, page)) | 1856 | if (xas_retry(&xas, page)) |
1843 | continue; | 1857 | continue; |
1844 | /* | 1858 | /* |
@@ -1848,19 +1862,24 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, | |||
1848 | if (xa_is_value(page)) | 1862 | if (xa_is_value(page)) |
1849 | break; | 1863 | break; |
1850 | 1864 | ||
1851 | if (!page_cache_get_speculative(page)) | 1865 | head = compound_head(page); |
1866 | if (!page_cache_get_speculative(head)) | ||
1852 | goto retry; | 1867 | goto retry; |
1853 | 1868 | ||
1854 | /* Has the page moved or been split? */ | 1869 | /* The page was split under us? */ |
1870 | if (compound_head(page) != head) | ||
1871 | goto put_page; | ||
1872 | |||
1873 | /* Has the page moved? */ | ||
1855 | if (unlikely(page != xas_reload(&xas))) | 1874 | if (unlikely(page != xas_reload(&xas))) |
1856 | goto put_page; | 1875 | goto put_page; |
1857 | 1876 | ||
1858 | pages[ret] = find_subpage(page, xas.xa_index); | 1877 | pages[ret] = page; |
1859 | if (++ret == nr_pages) | 1878 | if (++ret == nr_pages) |
1860 | break; | 1879 | break; |
1861 | continue; | 1880 | continue; |
1862 | put_page: | 1881 | put_page: |
1863 | put_page(page); | 1882 | put_page(head); |
1864 | retry: | 1883 | retry: |
1865 | xas_reset(&xas); | 1884 | xas_reset(&xas); |
1866 | } | 1885 | } |
@@ -1896,6 +1915,7 @@ unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index, | |||
1896 | 1915 | ||
1897 | rcu_read_lock(); | 1916 | rcu_read_lock(); |
1898 | xas_for_each_marked(&xas, page, end, tag) { | 1917 | xas_for_each_marked(&xas, page, end, tag) { |
1918 | struct page *head; | ||
1899 | if (xas_retry(&xas, page)) | 1919 | if (xas_retry(&xas, page)) |
1900 | continue; | 1920 | continue; |
1901 | /* | 1921 | /* |
@@ -1906,21 +1926,26 @@ unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index, | |||
1906 | if (xa_is_value(page)) | 1926 | if (xa_is_value(page)) |
1907 | continue; | 1927 | continue; |
1908 | 1928 | ||
1909 | if (!page_cache_get_speculative(page)) | 1929 | head = compound_head(page); |
1930 | if (!page_cache_get_speculative(head)) | ||
1910 | goto retry; | 1931 | goto retry; |
1911 | 1932 | ||
1912 | /* Has the page moved or been split? */ | 1933 | /* The page was split under us? */ |
1934 | if (compound_head(page) != head) | ||
1935 | goto put_page; | ||
1936 | |||
1937 | /* Has the page moved? */ | ||
1913 | if (unlikely(page != xas_reload(&xas))) | 1938 | if (unlikely(page != xas_reload(&xas))) |
1914 | goto put_page; | 1939 | goto put_page; |
1915 | 1940 | ||
1916 | pages[ret] = find_subpage(page, xas.xa_index); | 1941 | pages[ret] = page; |
1917 | if (++ret == nr_pages) { | 1942 | if (++ret == nr_pages) { |
1918 | *index = xas.xa_index + 1; | 1943 | *index = xas.xa_index + 1; |
1919 | goto out; | 1944 | goto out; |
1920 | } | 1945 | } |
1921 | continue; | 1946 | continue; |
1922 | put_page: | 1947 | put_page: |
1923 | put_page(page); | 1948 | put_page(head); |
1924 | retry: | 1949 | retry: |
1925 | xas_reset(&xas); | 1950 | xas_reset(&xas); |
1926 | } | 1951 | } |
@@ -2603,7 +2628,7 @@ void filemap_map_pages(struct vm_fault *vmf, | |||
2603 | pgoff_t last_pgoff = start_pgoff; | 2628 | pgoff_t last_pgoff = start_pgoff; |
2604 | unsigned long max_idx; | 2629 | unsigned long max_idx; |
2605 | XA_STATE(xas, &mapping->i_pages, start_pgoff); | 2630 | XA_STATE(xas, &mapping->i_pages, start_pgoff); |
2606 | struct page *page; | 2631 | struct page *head, *page; |
2607 | 2632 | ||
2608 | rcu_read_lock(); | 2633 | rcu_read_lock(); |
2609 | xas_for_each(&xas, page, end_pgoff) { | 2634 | xas_for_each(&xas, page, end_pgoff) { |
@@ -2612,19 +2637,24 @@ void filemap_map_pages(struct vm_fault *vmf, | |||
2612 | if (xa_is_value(page)) | 2637 | if (xa_is_value(page)) |
2613 | goto next; | 2638 | goto next; |
2614 | 2639 | ||
2640 | head = compound_head(page); | ||
2641 | |||
2615 | /* | 2642 | /* |
2616 | * Check for a locked page first, as a speculative | 2643 | * Check for a locked page first, as a speculative |
2617 | * reference may adversely influence page migration. | 2644 | * reference may adversely influence page migration. |
2618 | */ | 2645 | */ |
2619 | if (PageLocked(page)) | 2646 | if (PageLocked(head)) |
2620 | goto next; | 2647 | goto next; |
2621 | if (!page_cache_get_speculative(page)) | 2648 | if (!page_cache_get_speculative(head)) |
2622 | goto next; | 2649 | goto next; |
2623 | 2650 | ||
2624 | /* Has the page moved or been split? */ | 2651 | /* The page was split under us? */ |
2652 | if (compound_head(page) != head) | ||
2653 | goto skip; | ||
2654 | |||
2655 | /* Has the page moved? */ | ||
2625 | if (unlikely(page != xas_reload(&xas))) | 2656 | if (unlikely(page != xas_reload(&xas))) |
2626 | goto skip; | 2657 | goto skip; |
2627 | page = find_subpage(page, xas.xa_index); | ||
2628 | 2658 | ||
2629 | if (!PageUptodate(page) || | 2659 | if (!PageUptodate(page) || |
2630 | PageReadahead(page) || | 2660 | PageReadahead(page) || |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index bb8b617e34ed..885642c82aaa 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -2496,9 +2496,6 @@ static void __split_huge_page(struct page *page, struct list_head *list, | |||
2496 | if (IS_ENABLED(CONFIG_SHMEM) && PageSwapBacked(head)) | 2496 | if (IS_ENABLED(CONFIG_SHMEM) && PageSwapBacked(head)) |
2497 | shmem_uncharge(head->mapping->host, 1); | 2497 | shmem_uncharge(head->mapping->host, 1); |
2498 | put_page(head + i); | 2498 | put_page(head + i); |
2499 | } else if (!PageAnon(page)) { | ||
2500 | __xa_store(&head->mapping->i_pages, head[i].index, | ||
2501 | head + i, 0); | ||
2502 | } | 2499 | } |
2503 | } | 2500 | } |
2504 | 2501 | ||
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 0f7419938008..eaaa21b23215 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c | |||
@@ -1378,7 +1378,7 @@ static void collapse_shmem(struct mm_struct *mm, | |||
1378 | result = SCAN_FAIL; | 1378 | result = SCAN_FAIL; |
1379 | goto xa_locked; | 1379 | goto xa_locked; |
1380 | } | 1380 | } |
1381 | xas_store(&xas, new_page); | 1381 | xas_store(&xas, new_page + (index % HPAGE_PMD_NR)); |
1382 | nr_none++; | 1382 | nr_none++; |
1383 | continue; | 1383 | continue; |
1384 | } | 1384 | } |
@@ -1454,7 +1454,7 @@ static void collapse_shmem(struct mm_struct *mm, | |||
1454 | list_add_tail(&page->lru, &pagelist); | 1454 | list_add_tail(&page->lru, &pagelist); |
1455 | 1455 | ||
1456 | /* Finally, replace with the new page. */ | 1456 | /* Finally, replace with the new page. */ |
1457 | xas_store(&xas, new_page); | 1457 | xas_store(&xas, new_page + (index % HPAGE_PMD_NR)); |
1458 | continue; | 1458 | continue; |
1459 | out_unlock: | 1459 | out_unlock: |
1460 | unlock_page(page); | 1460 | unlock_page(page); |
diff --git a/mm/memfd.c b/mm/memfd.c index 2647c898990c..650e65a46b9c 100644 --- a/mm/memfd.c +++ b/mm/memfd.c | |||
@@ -39,7 +39,6 @@ static void memfd_tag_pins(struct xa_state *xas) | |||
39 | xas_for_each(xas, page, ULONG_MAX) { | 39 | xas_for_each(xas, page, ULONG_MAX) { |
40 | if (xa_is_value(page)) | 40 | if (xa_is_value(page)) |
41 | continue; | 41 | continue; |
42 | page = find_subpage(page, xas->xa_index); | ||
43 | if (page_count(page) - page_mapcount(page) > 1) | 42 | if (page_count(page) - page_mapcount(page) > 1) |
44 | xas_set_mark(xas, MEMFD_TAG_PINNED); | 43 | xas_set_mark(xas, MEMFD_TAG_PINNED); |
45 | 44 | ||
@@ -89,7 +88,6 @@ static int memfd_wait_for_pins(struct address_space *mapping) | |||
89 | bool clear = true; | 88 | bool clear = true; |
90 | if (xa_is_value(page)) | 89 | if (xa_is_value(page)) |
91 | continue; | 90 | continue; |
92 | page = find_subpage(page, xas.xa_index); | ||
93 | if (page_count(page) - page_mapcount(page) != 1) { | 91 | if (page_count(page) - page_mapcount(page) != 1) { |
94 | /* | 92 | /* |
95 | * On the last scan, we clean up all those tags | 93 | * On the last scan, we clean up all those tags |
diff --git a/mm/migrate.c b/mm/migrate.c index f2ecc2855a12..e9594bc0d406 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -463,7 +463,7 @@ int migrate_page_move_mapping(struct address_space *mapping, | |||
463 | 463 | ||
464 | for (i = 1; i < HPAGE_PMD_NR; i++) { | 464 | for (i = 1; i < HPAGE_PMD_NR; i++) { |
465 | xas_next(&xas); | 465 | xas_next(&xas); |
466 | xas_store(&xas, newpage); | 466 | xas_store(&xas, newpage + i); |
467 | } | 467 | } |
468 | } | 468 | } |
469 | 469 | ||
diff --git a/mm/shmem.c b/mm/shmem.c index 1bb3b8dc8bb2..f4dce9c8670d 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -614,7 +614,7 @@ static int shmem_add_to_page_cache(struct page *page, | |||
614 | if (xas_error(&xas)) | 614 | if (xas_error(&xas)) |
615 | goto unlock; | 615 | goto unlock; |
616 | next: | 616 | next: |
617 | xas_store(&xas, page); | 617 | xas_store(&xas, page + i); |
618 | if (++i < nr) { | 618 | if (++i < nr) { |
619 | xas_next(&xas); | 619 | xas_next(&xas); |
620 | goto next; | 620 | goto next; |
diff --git a/mm/swap_state.c b/mm/swap_state.c index eb714165afd2..85245fdec8d9 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c | |||
@@ -132,7 +132,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp) | |||
132 | for (i = 0; i < nr; i++) { | 132 | for (i = 0; i < nr; i++) { |
133 | VM_BUG_ON_PAGE(xas.xa_index != idx + i, page); | 133 | VM_BUG_ON_PAGE(xas.xa_index != idx + i, page); |
134 | set_page_private(page + i, entry.val + i); | 134 | set_page_private(page + i, entry.val + i); |
135 | xas_store(&xas, page); | 135 | xas_store(&xas, page + i); |
136 | xas_next(&xas); | 136 | xas_next(&xas); |
137 | } | 137 | } |
138 | address_space->nrpages += nr; | 138 | address_space->nrpages += nr; |
@@ -167,7 +167,7 @@ void __delete_from_swap_cache(struct page *page, swp_entry_t entry) | |||
167 | 167 | ||
168 | for (i = 0; i < nr; i++) { | 168 | for (i = 0; i < nr; i++) { |
169 | void *entry = xas_store(&xas, NULL); | 169 | void *entry = xas_store(&xas, NULL); |
170 | VM_BUG_ON_PAGE(entry != page, entry); | 170 | VM_BUG_ON_PAGE(entry != page + i, entry); |
171 | set_page_private(page + i, 0); | 171 | set_page_private(page + i, 0); |
172 | xas_next(&xas); | 172 | xas_next(&xas); |
173 | } | 173 | } |