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

page cache: Convert find_get_pages_range 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>

+19 -33
+19 -33
mm/filemap.c
··· 1650 1650 pgoff_t end, unsigned int nr_pages, 1651 1651 struct page **pages) 1652 1652 { 1653 - struct radix_tree_iter iter; 1654 - void **slot; 1653 + XA_STATE(xas, &mapping->i_pages, *start); 1654 + struct page *page; 1655 1655 unsigned ret = 0; 1656 1656 1657 1657 if (unlikely(!nr_pages)) 1658 1658 return 0; 1659 1659 1660 1660 rcu_read_lock(); 1661 - radix_tree_for_each_slot(slot, &mapping->i_pages, &iter, *start) { 1662 - struct page *head, *page; 1663 - 1664 - if (iter.index > end) 1665 - break; 1666 - repeat: 1667 - page = radix_tree_deref_slot(slot); 1668 - if (unlikely(!page)) 1661 + xas_for_each(&xas, page, end) { 1662 + struct page *head; 1663 + if (xas_retry(&xas, page)) 1669 1664 continue; 1670 - 1671 - if (radix_tree_exception(page)) { 1672 - if (radix_tree_deref_retry(page)) { 1673 - slot = radix_tree_iter_retry(&iter); 1674 - continue; 1675 - } 1676 - /* 1677 - * A shadow entry of a recently evicted page, 1678 - * or a swap entry from shmem/tmpfs. Skip 1679 - * over it. 1680 - */ 1665 + /* Skip over shadow, swap and DAX entries */ 1666 + if (xa_is_value(page)) 1681 1667 continue; 1682 - } 1683 1668 1684 1669 head = compound_head(page); 1685 1670 if (!page_cache_get_speculative(head)) 1686 - goto repeat; 1671 + goto retry; 1687 1672 1688 1673 /* The page was split under us? */ 1689 - if (compound_head(page) != head) { 1690 - put_page(head); 1691 - goto repeat; 1692 - } 1674 + if (compound_head(page) != head) 1675 + goto put_page; 1693 1676 1694 1677 /* Has the page moved? */ 1695 - if (unlikely(page != *slot)) { 1696 - put_page(head); 1697 - goto repeat; 1698 - } 1678 + if (unlikely(page != xas_reload(&xas))) 1679 + goto put_page; 1699 1680 1700 1681 pages[ret] = page; 1701 1682 if (++ret == nr_pages) { 1702 - *start = pages[ret - 1]->index + 1; 1683 + *start = page->index + 1; 1703 1684 goto out; 1704 1685 } 1686 + continue; 1687 + put_page: 1688 + put_page(head); 1689 + retry: 1690 + xas_reset(&xas); 1705 1691 } 1706 1692 1707 1693 /* 1708 1694 * We come here when there is no page beyond @end. We take care to not 1709 1695 * overflow the index @start as it confuses some of the callers. This 1710 - * breaks the iteration when there is page at index -1 but that is 1696 + * breaks the iteration when there is a page at index -1 but that is 1711 1697 * already broken anyway. 1712 1698 */ 1713 1699 if (end == (pgoff_t)-1)