Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

page cache: Convert find_get_entries_tag to XArray

Slightly shorter and simpler code.

Signed-off-by: Matthew Wilcox <willy@infradead.org>

+25 -31
+1 -1
include/linux/pagemap.h
··· 373 373 nr_pages, pages); 374 374 } 375 375 unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, 376 - int tag, unsigned int nr_entries, 376 + xa_mark_t tag, unsigned int nr_entries, 377 377 struct page **entries, pgoff_t *indices); 378 378 379 379 struct page *grab_cache_page_write_begin(struct address_space *mapping,
+24 -30
mm/filemap.c
··· 1866 1866 * @tag. 1867 1867 */ 1868 1868 unsigned 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 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 1874 unsigned int ret = 0; 1874 - struct radix_tree_iter iter; 1875 1875 1876 1876 if (!nr_entries) 1877 1877 return 0; 1878 1878 1879 1879 rcu_read_lock(); 1880 - radix_tree_for_each_tagged(slot, &mapping->i_pages, &iter, start, tag) { 1881 - struct page *head, *page; 1882 - repeat: 1883 - page = radix_tree_deref_slot(slot); 1884 - if (unlikely(!page)) 1880 + xas_for_each_marked(&xas, page, ULONG_MAX, tag) { 1881 + struct page *head; 1882 + if (xas_retry(&xas, page)) 1885 1883 continue; 1886 - if (radix_tree_exception(page)) { 1887 - if (radix_tree_deref_retry(page)) { 1888 - slot = radix_tree_iter_retry(&iter); 1889 - continue; 1890 - } 1891 - 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 - */ 1884 + /* 1885 + * A shadow entry of a recently evicted page, a swap 1886 + * entry from shmem/tmpfs or a DAX entry. Return it 1887 + * without attempting to raise page count. 1888 + */ 1889 + if (xa_is_value(page)) 1897 1890 goto export; 1898 - } 1899 1891 1900 1892 head = compound_head(page); 1901 1893 if (!page_cache_get_speculative(head)) 1902 - goto repeat; 1894 + goto retry; 1903 1895 1904 1896 /* The page was split under us? */ 1905 - if (compound_head(page) != head) { 1906 - put_page(head); 1907 - goto repeat; 1908 - } 1897 + if (compound_head(page) != head) 1898 + goto put_page; 1909 1899 1910 1900 /* Has the page moved? */ 1911 - if (unlikely(page != *slot)) { 1912 - put_page(head); 1913 - goto repeat; 1914 - } 1901 + if (unlikely(page != xas_reload(&xas))) 1902 + goto put_page; 1903 + 1915 1904 export: 1916 - indices[ret] = iter.index; 1905 + indices[ret] = xas.xa_index; 1917 1906 entries[ret] = page; 1918 1907 if (++ret == nr_entries) 1919 1908 break; 1909 + continue; 1910 + put_page: 1911 + put_page(head); 1912 + retry: 1913 + xas_reset(&xas); 1920 1914 } 1921 1915 rcu_read_unlock(); 1922 1916 return ret;