]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
page cache: Convert find_get_pages_range to XArray
authorMatthew Wilcox <willy@infradead.org>
Wed, 16 May 2018 21:38:56 +0000 (17:38 -0400)
committerMatthew Wilcox <willy@infradead.org>
Sun, 21 Oct 2018 14:46:34 +0000 (10:46 -0400)
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>
mm/filemap.c

index 4707156b9fbd81f474f4e76c6de6b593ad5a9027..b72c39fe61c24a652b4b70ff1defaa48ddd4c958 100644 (file)
@@ -1650,64 +1650,50 @@ unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start,
                              pgoff_t end, unsigned int nr_pages,
                              struct page **pages)
 {
-       struct radix_tree_iter iter;
-       void **slot;
+       XA_STATE(xas, &mapping->i_pages, *start);
+       struct page *page;
        unsigned ret = 0;
 
        if (unlikely(!nr_pages))
                return 0;
 
        rcu_read_lock();
-       radix_tree_for_each_slot(slot, &mapping->i_pages, &iter, *start) {
-               struct page *head, *page;
-
-               if (iter.index > end)
-                       break;
-repeat:
-               page = radix_tree_deref_slot(slot);
-               if (unlikely(!page))
+       xas_for_each(&xas, page, end) {
+               struct page *head;
+               if (xas_retry(&xas, page))
                        continue;
-
-               if (radix_tree_exception(page)) {
-                       if (radix_tree_deref_retry(page)) {
-                               slot = radix_tree_iter_retry(&iter);
-                               continue;
-                       }
-                       /*
-                        * A shadow entry of a recently evicted page,
-                        * or a swap entry from shmem/tmpfs.  Skip
-                        * over it.
-                        */
+               /* Skip over shadow, swap and DAX entries */
+               if (xa_is_value(page))
                        continue;
-               }
 
                head = compound_head(page);
                if (!page_cache_get_speculative(head))
-                       goto repeat;
+                       goto retry;
 
                /* The page was split under us? */
-               if (compound_head(page) != head) {
-                       put_page(head);
-                       goto repeat;
-               }
+               if (compound_head(page) != head)
+                       goto put_page;
 
                /* Has the page moved? */
-               if (unlikely(page != *slot)) {
-                       put_page(head);
-                       goto repeat;
-               }
+               if (unlikely(page != xas_reload(&xas)))
+                       goto put_page;
 
                pages[ret] = page;
                if (++ret == nr_pages) {
-                       *start = pages[ret - 1]->index + 1;
+                       *start = page->index + 1;
                        goto out;
                }
+               continue;
+put_page:
+               put_page(head);
+retry:
+               xas_reset(&xas);
        }
 
        /*
         * We come here when there is no page beyond @end. We take care to not
         * overflow the index @start as it confuses some of the callers. This
-        * breaks the iteration when there is page at index -1 but that is
+        * breaks the iteration when there is page at index -1 but that is
         * already broken anyway.
         */
        if (end == (pgoff_t)-1)