aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@infradead.org>2018-05-16 23:56:04 -0400
committerMatthew Wilcox <willy@infradead.org>2018-10-21 10:46:35 -0400
commitc1901cd33cf407d77a181f8dd4ffff98041ef480 (patch)
tree4a7b69052ae6e402db04c329a6087b819b703fbb /mm/filemap.c
parenta6906972fe67fb6f73ba04088f7897227fd1cd8f (diff)
page cache: Convert find_get_entries_tag to XArray
Slightly shorter and simpler code. Signed-off-by: Matthew Wilcox <willy@infradead.org>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 0df28aa6411c..35ae011971e1 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1866,57 +1866,51 @@ EXPORT_SYMBOL(find_get_pages_range_tag);
1866 * @tag. 1866 * @tag.
1867 */ 1867 */
1868unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, 1868unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
1869 int tag, unsigned int nr_entries, 1869 xa_mark_t tag, unsigned int nr_entries,
1870 struct page **entries, pgoff_t *indices) 1870 struct page **entries, pgoff_t *indices)
1871{ 1871{
1872 void **slot; 1872 XA_STATE(xas, &mapping->i_pages, start);
1873 struct page *page;
1873 unsigned int ret = 0; 1874 unsigned int ret = 0;
1874 struct radix_tree_iter iter;
1875 1875
1876 if (!nr_entries) 1876 if (!nr_entries)
1877 return 0; 1877 return 0;
1878 1878
1879 rcu_read_lock(); 1879 rcu_read_lock();
1880 radix_tree_for_each_tagged(slot, &mapping->i_pages, &iter, start, tag) { 1880 xas_for_each_marked(&xas, page, ULONG_MAX, tag) {
1881 struct page *head, *page; 1881 struct page *head;
1882repeat: 1882 if (xas_retry(&xas, page))
1883 page = radix_tree_deref_slot(slot);
1884 if (unlikely(!page))
1885 continue; 1883 continue;
1886 if (radix_tree_exception(page)) { 1884 /*
1887 if (radix_tree_deref_retry(page)) { 1885 * A shadow entry of a recently evicted page, a swap
1888 slot = radix_tree_iter_retry(&iter); 1886 * entry from shmem/tmpfs or a DAX entry. Return it
1889 continue; 1887 * without attempting to raise page count.
1890 } 1888 */
1891 1889 if (xa_is_value(page))
1892 /*
1893 * A shadow entry of a recently evicted page, a swap
1894 * entry from shmem/tmpfs or a DAX entry. Return it
1895 * without attempting to raise page count.
1896 */
1897 goto export; 1890 goto export;
1898 }
1899 1891
1900 head = compound_head(page); 1892 head = compound_head(page);
1901 if (!page_cache_get_speculative(head)) 1893 if (!page_cache_get_speculative(head))
1902 goto repeat; 1894 goto retry;
1903 1895
1904 /* The page was split under us? */ 1896 /* The page was split under us? */
1905 if (compound_head(page) != head) { 1897 if (compound_head(page) != head)
1906 put_page(head); 1898 goto put_page;
1907 goto repeat;
1908 }
1909 1899
1910 /* Has the page moved? */ 1900 /* Has the page moved? */
1911 if (unlikely(page != *slot)) { 1901 if (unlikely(page != xas_reload(&xas)))
1912 put_page(head); 1902 goto put_page;
1913 goto repeat; 1903
1914 }
1915export: 1904export:
1916 indices[ret] = iter.index; 1905 indices[ret] = xas.xa_index;
1917 entries[ret] = page; 1906 entries[ret] = page;
1918 if (++ret == nr_entries) 1907 if (++ret == nr_entries)
1919 break; 1908 break;
1909 continue;
1910put_page:
1911 put_page(head);
1912retry:
1913 xas_reset(&xas);
1920 } 1914 }
1921 rcu_read_unlock(); 1915 rcu_read_unlock();
1922 return ret; 1916 return ret;