From daadcbc8a27cc647259e7864f00b038c5705a2ef Mon Sep 17 00:00:00 2001 From: Sooyong Suk Date: Wed, 23 Jul 2025 13:06:46 +0900 Subject: [PATCH] ANDROID: mm: add vendor hook in free_unref_folios and free_unref_page A vendor hook to bypass free_one_page() via __free_pages_ok() was added via https://android-review.googlesource.com/c/kernel/common/+/3458032 for vendor modules to hook pages on certain conditions to use later instead of freeing pages directly. In kernel v6.12, for same purpose, free_unref_folios() and free_unref_page() path also needs same vendor hook to bypass free_one_page(). Bug: 410432482 Change-Id: I1863eb497eee796903b483a3a9f8808ab372b475 Signed-off-by: Sooyong Suk --- drivers/android/vendor_hooks.c | 2 ++ include/trace/hooks/mm.h | 6 ++++++ mm/page_alloc.c | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8ab75d4316e2..bd180cdeab90 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -454,6 +454,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_pageout_bypass); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_cold_or_pageout_abort); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages_prepare_bypass); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages_ok_bypass); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_page_bypass); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_folio_bypass); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_split_large_folio_bypass); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_should_be_protected); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_referenced_check_bypass); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index d5515ab486fc..dfd69fa48a3c 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -346,6 +346,12 @@ DECLARE_HOOK(android_vh_free_pages_ok_bypass, TP_PROTO(struct page *page, unsigned int order, int __bitwise flags, bool *skip_free_pages_ok), TP_ARGS(page, order, flags, skip_free_pages_ok)); +DECLARE_HOOK(android_vh_free_page_bypass, + TP_PROTO(struct page *page, unsigned int order, bool *skip_free_page), + TP_ARGS(page, order, skip_free_page)); +DECLARE_HOOK(android_vh_free_folio_bypass, + TP_PROTO(struct folio *folio, unsigned int order, bool *skip_free_folio), + TP_ARGS(folio, order, skip_free_folio)); DECLARE_HOOK(android_vh_free_pages_prepare_init, TP_PROTO(struct page *page, int nr_pages, bool *init), TP_ARGS(page, nr_pages, init)); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a996c6fb107c..d395554b7f70 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2797,6 +2797,7 @@ void free_unref_page(struct page *page, unsigned int order) unsigned long pfn = page_to_pfn(page); int migratetype; bool skip_free_unref_page = false; + bool skip_free_page = false; if (!pcp_allowed_order(order)) { __free_pages_ok(page, order, FPI_NONE); @@ -2806,6 +2807,9 @@ void free_unref_page(struct page *page, unsigned int order) if (!free_pages_prepare(page, order)) return; + trace_android_vh_free_page_bypass(page, order, &skip_free_page); + if (skip_free_page) + return; /* * We only track unmovable, reclaimable, movable and if restrict cma * fallback flag is set, CMA on pcp lists. @@ -2857,9 +2861,15 @@ void free_unref_folios(struct folio_batch *folios) struct folio *folio = folios->folios[i]; unsigned long pfn = folio_pfn(folio); unsigned int order = folio_order(folio); + bool skip_free_folio = false; if (!free_pages_prepare(&folio->page, order)) continue; + + trace_android_vh_free_folio_bypass(folio, order, + &skip_free_folio); + if (skip_free_folio) + continue; /* * Free orders not handled on the PCP directly to the * allocator.