All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: linux-mm@kvack.org, linux-fsdevel@vger.kernel.org
Cc: Kent Overstreet <kent.overstreet@gmail.com>,
	David Howells <dhowells@redhat.com>
Subject: [RFC] find_get_heads_contig
Date: Wed, 21 Oct 2020 02:26:30 +0100	[thread overview]
Message-ID: <20201021012630.GG20115@casper.infradead.org> (raw)

I was going to convert find_get_pages_contig() to only return head pages,
but I want to change the API to take a pagevec like the other find_*
functions have or will have.  And it'd be nice if the name of the function
reminded callers that it only returns head pages.  So comments on this?

diff --git a/mm/filemap.c b/mm/filemap.c
index 31ba06409dfa..b7dd2523fe79 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2093,6 +2093,58 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index,
 }
 EXPORT_SYMBOL(find_get_pages_contig);
 
+/**
+ * find_get_heads_contig - Return head pages for a contiguous byte range.
+ * @mapping: The address_space to search.
+ * @start: The starting page index.
+ * @end: The final page index (inclusive).
+ * @pvec: Where the resulting pages are placed.
+ *
+ * find_get_heads_contig() will return a batch of head pages from
+ * @mapping.  Pages are returned with an incremented refcount.  Only the
+ * head page of a THP is returned.  In contrast to find_get_entries(),
+ * pages which are partially outside the range are returned.  The head
+ * pages have ascending indices.  The indices may not be consecutive,
+ * but the bytes represented by the pages are contiguous.  If there is
+ * no page at @start, no pages will be returned.
+ *
+ * Return: The number of pages which were found.
+ */
+unsigned find_get_heads_contig(struct address_space *mapping, pgoff_t start,
+		pgoff_t end, struct pagevec *pvec)
+{
+	XA_STATE(xas, &mapping->i_pages, start);
+	struct page *page;
+
+	rcu_read_lock();
+	for (page = xas_load(&xas); page; page = xas_next(&xas)) {
+		if (xas.xa_index > end)
+			break;
+		if (xas_retry(&xas, page) || xa_is_sibling(page))
+			continue;
+		if (xa_is_value(page))
+			break;
+
+		if (!page_cache_get_speculative(page))
+			goto retry;
+
+		/* Has the page moved or been split? */
+		if (unlikely(page != xas_reload(&xas)))
+			goto put_page;
+
+		if (!pagevec_add(pvec, page))
+			break;
+		continue;
+put_page:
+		put_page(page);
+retry:
+		xas_reset(&xas);
+	}
+	rcu_read_unlock();
+	return pagevec_count(pvec);
+}
+EXPORT_SYMBOL(find_get_heads_contig);
+
 /**
  * find_get_pages_range_tag - Find and return head pages matching @tag.
  * @mapping:	the address_space to search

             reply	other threads:[~2020-10-21  1:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-21  1:26 Matthew Wilcox [this message]
2020-10-21  4:19 ` [RFC] find_get_heads_contig Kent Overstreet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201021012630.GG20115@casper.infradead.org \
    --to=willy@infradead.org \
    --cc=dhowells@redhat.com \
    --cc=kent.overstreet@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.