Loading mm/filemap.c +23 −28 Original line number Original line Diff line number Diff line Loading @@ -1578,53 +1578,48 @@ unsigned find_get_entries(struct address_space *mapping, pgoff_t start, unsigned int nr_entries, pgoff_t start, unsigned int nr_entries, struct page **entries, pgoff_t *indices) struct page **entries, pgoff_t *indices) { { void **slot; XA_STATE(xas, &mapping->i_pages, start); struct page *page; unsigned int ret = 0; unsigned int ret = 0; struct radix_tree_iter iter; if (!nr_entries) if (!nr_entries) return 0; return 0; rcu_read_lock(); rcu_read_lock(); radix_tree_for_each_slot(slot, &mapping->i_pages, &iter, start) { xas_for_each(&xas, page, ULONG_MAX) { struct page *head, *page; struct page *head; repeat: if (xas_retry(&xas, page)) page = radix_tree_deref_slot(slot); if (unlikely(!page)) continue; if (radix_tree_exception(page)) { if (radix_tree_deref_retry(page)) { slot = radix_tree_iter_retry(&iter); continue; continue; } /* /* * A shadow entry of a recently evicted page, a swap * A shadow entry of a recently evicted page, a swap * entry from shmem/tmpfs or a DAX entry. Return it * entry from shmem/tmpfs or a DAX entry. Return it * without attempting to raise page count. * without attempting to raise page count. */ */ if (xa_is_value(page)) goto export; goto export; } head = compound_head(page); head = compound_head(page); if (!page_cache_get_speculative(head)) if (!page_cache_get_speculative(head)) goto repeat; goto retry; /* The page was split under us? */ /* The page was split under us? */ if (compound_head(page) != head) { if (compound_head(page) != head) put_page(head); goto put_page; goto repeat; } /* Has the page moved? */ /* Has the page moved? */ if (unlikely(page != *slot)) { if (unlikely(page != xas_reload(&xas))) put_page(head); goto put_page; goto repeat; } export: export: indices[ret] = iter.index; indices[ret] = xas.xa_index; entries[ret] = page; entries[ret] = page; if (++ret == nr_entries) if (++ret == nr_entries) break; break; continue; put_page: put_page(head); retry: xas_reset(&xas); } } rcu_read_unlock(); rcu_read_unlock(); return ret; return ret; Loading Loading
mm/filemap.c +23 −28 Original line number Original line Diff line number Diff line Loading @@ -1578,53 +1578,48 @@ unsigned find_get_entries(struct address_space *mapping, pgoff_t start, unsigned int nr_entries, pgoff_t start, unsigned int nr_entries, struct page **entries, pgoff_t *indices) struct page **entries, pgoff_t *indices) { { void **slot; XA_STATE(xas, &mapping->i_pages, start); struct page *page; unsigned int ret = 0; unsigned int ret = 0; struct radix_tree_iter iter; if (!nr_entries) if (!nr_entries) return 0; return 0; rcu_read_lock(); rcu_read_lock(); radix_tree_for_each_slot(slot, &mapping->i_pages, &iter, start) { xas_for_each(&xas, page, ULONG_MAX) { struct page *head, *page; struct page *head; repeat: if (xas_retry(&xas, page)) page = radix_tree_deref_slot(slot); if (unlikely(!page)) continue; if (radix_tree_exception(page)) { if (radix_tree_deref_retry(page)) { slot = radix_tree_iter_retry(&iter); continue; continue; } /* /* * A shadow entry of a recently evicted page, a swap * A shadow entry of a recently evicted page, a swap * entry from shmem/tmpfs or a DAX entry. Return it * entry from shmem/tmpfs or a DAX entry. Return it * without attempting to raise page count. * without attempting to raise page count. */ */ if (xa_is_value(page)) goto export; goto export; } head = compound_head(page); head = compound_head(page); if (!page_cache_get_speculative(head)) if (!page_cache_get_speculative(head)) goto repeat; goto retry; /* The page was split under us? */ /* The page was split under us? */ if (compound_head(page) != head) { if (compound_head(page) != head) put_page(head); goto put_page; goto repeat; } /* Has the page moved? */ /* Has the page moved? */ if (unlikely(page != *slot)) { if (unlikely(page != xas_reload(&xas))) put_page(head); goto put_page; goto repeat; } export: export: indices[ret] = iter.index; indices[ret] = xas.xa_index; entries[ret] = page; entries[ret] = page; if (++ret == nr_entries) if (++ret == nr_entries) break; break; continue; put_page: put_page(head); retry: xas_reset(&xas); } } rcu_read_unlock(); rcu_read_unlock(); return ret; return ret; Loading