diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 146 |
1 files changed, 88 insertions, 58 deletions
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) || |