Message ID | 20250318161823.4005529-2-tabba@google.com |
---|---|
State | New |
Headers | show |
Series | [v7,1/9] mm: Consolidate freeing of typed folios on final folio_put() | expand |
On 18.03.25 17:18, Fuad Tabba wrote: > Some folio types, such as hugetlb, handle freeing their own > folios. Moreover, guest_memfd will require being notified once a > folio's reference count reaches 0 to facilitate shared to private > folio conversion, without the folio actually being freed at that > point. > > As a first step towards that, this patch consolidates freeing > folios that have a type. The first user is hugetlb folios. Later > in this patch series, guest_memfd will become the second user of > this. > > Suggested-by: David Hildenbrand <david@redhat.com> > Acked-by: Vlastimil Babka <vbabka@suse.cz> > Acked-by: David Hildenbrand <david@redhat.com> > Signed-off-by: Fuad Tabba <tabba@google.com> > --- As discussed in the last upstream meeting, we should focus on using the folio_put() hook only for the post-truncate case where required (e.g., re-assemble hugetlb). For shared->private conversion doing it synchronously (unmap, try freezing refcount) and failing if impossible to signal user space to retry is a better first approach. So this patch will be dropped from your series for now, correct?
Hi David, On Mon, 14 Apr 2025 at 11:00, David Hildenbrand <david@redhat.com> wrote: > > On 18.03.25 17:18, Fuad Tabba wrote: > > Some folio types, such as hugetlb, handle freeing their own > > folios. Moreover, guest_memfd will require being notified once a > > folio's reference count reaches 0 to facilitate shared to private > > folio conversion, without the folio actually being freed at that > > point. > > > > As a first step towards that, this patch consolidates freeing > > folios that have a type. The first user is hugetlb folios. Later > > in this patch series, guest_memfd will become the second user of > > this. > > > > Suggested-by: David Hildenbrand <david@redhat.com> > > Acked-by: Vlastimil Babka <vbabka@suse.cz> > > Acked-by: David Hildenbrand <david@redhat.com> > > Signed-off-by: Fuad Tabba <tabba@google.com> > > --- > > As discussed in the last upstream meeting, we should focus on using the > folio_put() hook only for the post-truncate case where required (e.g., > re-assemble hugetlb). > > For shared->private conversion doing it synchronously (unmap, try > freezing refcount) and failing if impossible to signal user space to > retry is a better first approach. > > So this patch will be dropped from your series for now, correct? Yes it will. Thanks, /fuad > -- > Cheers, > > David / dhildenb >
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 36d283552f80..6dc2494bd002 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -953,6 +953,21 @@ static inline bool page_has_type(const struct page *page) return page_mapcount_is_type(data_race(page->page_type)); } +static inline int page_get_type(const struct page *page) +{ + return page->page_type >> 24; +} + +static inline bool folio_has_type(const struct folio *folio) +{ + return page_has_type(&folio->page); +} + +static inline int folio_get_type(const struct folio *folio) +{ + return page_get_type(&folio->page); +} + #define FOLIO_TYPE_OPS(lname, fname) \ static __always_inline bool folio_test_##fname(const struct folio *folio) \ { \ diff --git a/mm/swap.c b/mm/swap.c index fc8281ef4241..47bc1bb919cc 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -94,6 +94,19 @@ static void page_cache_release(struct folio *folio) unlock_page_lruvec_irqrestore(lruvec, flags); } +static void free_typed_folio(struct folio *folio) +{ + switch (folio_get_type(folio)) { +#ifdef CONFIG_HUGETLBFS + case PGTY_hugetlb: + free_huge_folio(folio); + return; +#endif + default: + WARN_ON_ONCE(1); + } +} + void __folio_put(struct folio *folio) { if (unlikely(folio_is_zone_device(folio))) { @@ -101,8 +114,8 @@ void __folio_put(struct folio *folio) return; } - if (folio_test_hugetlb(folio)) { - free_huge_folio(folio); + if (unlikely(folio_has_type(folio))) { + free_typed_folio(folio); return; } @@ -966,13 +979,13 @@ void folios_put_refs(struct folio_batch *folios, unsigned int *refs) if (!folio_ref_sub_and_test(folio, nr_refs)) continue; - /* hugetlb has its own memcg */ - if (folio_test_hugetlb(folio)) { + if (unlikely(folio_has_type(folio))) { + /* typed folios have their own memcg, if any */ if (lruvec) { unlock_page_lruvec_irqrestore(lruvec, flags); lruvec = NULL; } - free_huge_folio(folio); + free_typed_folio(folio); continue; } folio_unqueue_deferred_split(folio);