aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2018-05-16 18:12:54 -0400
committerMatthew Wilcox <willy@infradead.org>2018-10-21 10:46:35 -0400
commita6906972fe67fb6f73ba04088f7897227fd1cd8f (patch)
treeae5e24910060321dcdbbae7c1096596f9baaa5c8 /mm/filemap.c
parent3ece58a270cd1e5026282abe778bd50db7a11d08 (diff)
page cache; Convert find_get_pages_range_tag to XArray
The 'end' parameter of the xas_for_each iterator avoids a useless iteration at the end of the range. Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c68
1 files changed, 26 insertions, 42 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 089b67598100..0df28aa6411c 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1789,74 +1789,58 @@ EXPORT_SYMBOL(find_get_pages_contig);
1789 * @tag. We update @index to index the next page for the traversal. 1789 * @tag. We update @index to index the next page for the traversal.
1790 */ 1790 */
1791unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index, 1791unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
1792 pgoff_t end, int tag, unsigned int nr_pages, 1792 pgoff_t end, xa_mark_t tag, unsigned int nr_pages,
1793 struct page **pages) 1793 struct page **pages)
1794{ 1794{
1795 struct radix_tree_iter iter; 1795 XA_STATE(xas, &mapping->i_pages, *index);
1796 void **slot; 1796 struct page *page;
1797 unsigned ret = 0; 1797 unsigned ret = 0;
1798 1798
1799 if (unlikely(!nr_pages)) 1799 if (unlikely(!nr_pages))
1800 return 0; 1800 return 0;
1801 1801
1802 rcu_read_lock(); 1802 rcu_read_lock();
1803 radix_tree_for_each_tagged(slot, &mapping->i_pages, &iter, *index, tag) { 1803 xas_for_each_marked(&xas, page, end, tag) {
1804 struct page *head, *page; 1804 struct page *head;
1805 1805 if (xas_retry(&xas, page))
1806 if (iter.index > end)
1807 break;
1808repeat:
1809 page = radix_tree_deref_slot(slot);
1810 if (unlikely(!page))
1811 continue; 1806 continue;
1812 1807 /*
1813 if (radix_tree_exception(page)) { 1808 * Shadow entries should never be tagged, but this iteration
1814 if (radix_tree_deref_retry(page)) { 1809 * is lockless so there is a window for page reclaim to evict
1815 slot = radix_tree_iter_retry(&iter); 1810 * a page we saw tagged. Skip over it.
1816 continue; 1811 */
1817 } 1812 if (xa_is_value(page))
1818 /*
1819 * A shadow entry of a recently evicted page.
1820 *
1821 * Those entries should never be tagged, but
1822 * this tree walk is lockless and the tags are
1823 * looked up in bulk, one radix tree node at a
1824 * time, so there is a sizable window for page
1825 * reclaim to evict a page we saw tagged.
1826 *
1827 * Skip over it.
1828 */
1829 continue; 1813 continue;
1830 }
1831 1814
1832 head = compound_head(page); 1815 head = compound_head(page);
1833 if (!page_cache_get_speculative(head)) 1816 if (!page_cache_get_speculative(head))
1834 goto repeat; 1817 goto retry;
1835 1818
1836 /* The page was split under us? */ 1819 /* The page was split under us? */
1837 if (compound_head(page) != head) { 1820 if (compound_head(page) != head)
1838 put_page(head); 1821 goto put_page;
1839 goto repeat;
1840 }
1841 1822
1842 /* Has the page moved? */ 1823 /* Has the page moved? */
1843 if (unlikely(page != *slot)) { 1824 if (unlikely(page != xas_reload(&xas)))
1844 put_page(head); 1825 goto put_page;
1845 goto repeat;
1846 }
1847 1826
1848 pages[ret] = page; 1827 pages[ret] = page;
1849 if (++ret == nr_pages) { 1828 if (++ret == nr_pages) {
1850 *index = pages[ret - 1]->index + 1; 1829 *index = page->index + 1;
1851 goto out; 1830 goto out;
1852 } 1831 }
1832 continue;
1833put_page:
1834 put_page(head);
1835retry:
1836 xas_reset(&xas);
1853 } 1837 }
1854 1838
1855 /* 1839 /*
1856 * We come here when we got at @end. We take care to not overflow the 1840 * We come here when we got to @end. We take care to not overflow the
1857 * index @index as it confuses some of the callers. This breaks the 1841 * index @index as it confuses some of the callers. This breaks the
1858 * iteration when there is page at index -1 but that is already broken 1842 * iteration when there is a page at index -1 but that is already
1859 * anyway. 1843 * broken anyway.
1860 */ 1844 */
1861 if (end == (pgoff_t)-1) 1845 if (end == (pgoff_t)-1)
1862 *index = (pgoff_t)-1; 1846 *index = (pgoff_t)-1;