Skip to content

Commit b68b10b

Browse files
committed
Merge tag 'folio-5.17a' of git://git.infradead.org/users/willy/pagecache
Pull more folio updates from Matthew Wilcox: "Three small folio patches. One bug fix, one patch pulled forward from the patches destined for 5.18 and then a patch to make use of that functionality" * tag 'folio-5.17a' of git://git.infradead.org/users/willy/pagecache: filemap: Use folio_put_refs() in filemap_free_folio() mm: Add folio_put_refs() pagevec: Initialise folio_batch->percpu_pvec_drained
2 parents 369af20 + 3abb28e commit b68b10b

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

include/linux/mm.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,26 @@ static inline void folio_put(struct folio *folio)
11991199
__put_page(&folio->page);
12001200
}
12011201

1202+
/**
1203+
* folio_put_refs - Reduce the reference count on a folio.
1204+
* @folio: The folio.
1205+
* @refs: The amount to subtract from the folio's reference count.
1206+
*
1207+
* If the folio's reference count reaches zero, the memory will be
1208+
* released back to the page allocator and may be used by another
1209+
* allocation immediately. Do not access the memory or the struct folio
1210+
* after calling folio_put_refs() unless you can be sure that these weren't
1211+
* the last references.
1212+
*
1213+
* Context: May be called in process or interrupt context, but not in NMI
1214+
* context. May be called while holding a spinlock.
1215+
*/
1216+
static inline void folio_put_refs(struct folio *folio, int refs)
1217+
{
1218+
if (folio_ref_sub_and_test(folio, refs))
1219+
__put_page(&folio->page);
1220+
}
1221+
12021222
static inline void put_page(struct page *page)
12031223
{
12041224
struct folio *folio = page_folio(page);

include/linux/pagevec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ static_assert(offsetof(struct pagevec, pages) ==
111111
static inline void folio_batch_init(struct folio_batch *fbatch)
112112
{
113113
fbatch->nr = 0;
114+
fbatch->percpu_pvec_drained = false;
114115
}
115116

116117
static inline unsigned int folio_batch_count(struct folio_batch *fbatch)

mm/filemap.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,17 +231,15 @@ void __filemap_remove_folio(struct folio *folio, void *shadow)
231231
void filemap_free_folio(struct address_space *mapping, struct folio *folio)
232232
{
233233
void (*freepage)(struct page *);
234+
int refs = 1;
234235

235236
freepage = mapping->a_ops->freepage;
236237
if (freepage)
237238
freepage(&folio->page);
238239

239-
if (folio_test_large(folio) && !folio_test_hugetlb(folio)) {
240-
folio_ref_sub(folio, folio_nr_pages(folio));
241-
VM_BUG_ON_FOLIO(folio_ref_count(folio) <= 0, folio);
242-
} else {
243-
folio_put(folio);
244-
}
240+
if (folio_test_large(folio) && !folio_test_hugetlb(folio))
241+
refs = folio_nr_pages(folio);
242+
folio_put_refs(folio, refs);
245243
}
246244

247245
/**

0 commit comments

Comments
 (0)