diff mbox series

[v14,081/138] mm: Add folio_evictable()

Message ID 20210715033704.692967-82-willy@infradead.org (mailing list archive)
State New, archived
Headers show
Series Memory folios | expand

Commit Message

Matthew Wilcox July 15, 2021, 3:36 a.m. UTC
This is the folio equivalent of page_evictable().  Unfortunately, it's
different from !folio_test_unevictable(), but I think it's used in places
where you have to be a VM expert and can reasonably be expected to know
the difference.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
 mm/internal.h | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

Comments

David Howells Aug. 10, 2021, 9:41 p.m. UTC | #1
Matthew Wilcox (Oracle) <willy@infradead.org> wrote:

> This is the folio equivalent of page_evictable().  Unfortunately, it's
> different from !folio_test_unevictable(), but I think it's used in places
> where you have to be a VM expert and can reasonably be expected to know
> the difference.

It would be useful to say how it is different.  I'm guessing it's because a
page is always entirely mlocked or not, but a folio might be partially
mlocked?

David
Vlastimil Babka Aug. 12, 2021, 5:17 p.m. UTC | #2
On 7/15/21 5:36 AM, Matthew Wilcox (Oracle) wrote:
> This is the folio equivalent of page_evictable().  Unfortunately, it's
> different from !folio_test_unevictable(), but I think it's used in places
> where you have to be a VM expert and can reasonably be expected to know
> the difference.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> Reviewed-by: Christoph Hellwig <hch@lst.de>

Acked-by: Vlastimil Babka <vbabka@suse.cz>
Matthew Wilcox Aug. 16, 2021, 12:43 a.m. UTC | #3
On Tue, Aug 10, 2021 at 10:41:30PM +0100, David Howells wrote:
> Matthew Wilcox (Oracle) <willy@infradead.org> wrote:
> 
> > This is the folio equivalent of page_evictable().  Unfortunately, it's
> > different from !folio_test_unevictable(), but I think it's used in places
> > where you have to be a VM expert and can reasonably be expected to know
> > the difference.
> 
> It would be useful to say how it is different.  I'm guessing it's because a
> page is always entirely mlocked or not, but a folio might be partially
> mlocked?

folio_test_unevictable() checks the unevictable page flag.
folio_evictable() tests whether the folio is evictable (is any page
in the folio part of an mlocked VMA, or has the filesystem marked
the inode as being unevictable (eg is it ramfs).

It does end up looking a bit weird though.

                if (page_evictable(page) && PageUnevictable(page)) {
                        del_page_from_lru_list(page, lruvec);
                        ClearPageUnevictable(page);
                        add_page_to_lru_list(page, lruvec);

but it's all mm-internal, not exposed to filesystems.
diff mbox series

Patch

diff --git a/mm/internal.h b/mm/internal.h
index 08e8a28994d1..0910efec5821 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -72,17 +72,28 @@  unsigned find_lock_entries(struct address_space *mapping, pgoff_t start,
 		pgoff_t end, struct pagevec *pvec, pgoff_t *indices);
 
 /**
- * page_evictable - test whether a page is evictable
- * @page: the page to test
+ * folio_evictable - Test whether a folio is evictable.
+ * @folio: The folio to test.
  *
- * Test whether page is evictable--i.e., should be placed on active/inactive
- * lists vs unevictable list.
- *
- * Reasons page might not be evictable:
- * (1) page's mapping marked unevictable
- * (2) page is part of an mlocked VMA
+ * Test whether @folio is evictable -- i.e., should be placed on
+ * active/inactive lists vs unevictable list.
  *
+ * Reasons folio might not be evictable:
+ * 1. folio's mapping marked unevictable
+ * 2. One of the pages in the folio is part of an mlocked VMA
  */
+static inline bool folio_evictable(struct folio *folio)
+{
+	bool ret;
+
+	/* Prevent address_space of inode and swap cache from being freed */
+	rcu_read_lock();
+	ret = !mapping_unevictable(folio_mapping(folio)) &&
+			!folio_test_mlocked(folio);
+	rcu_read_unlock();
+	return ret;
+}
+
 static inline bool page_evictable(struct page *page)
 {
 	bool ret;