From e56f8712cffc38406771a6a0c658ed4227559265 Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Thu, 23 Jun 2022 15:15:46 +0800 Subject: [PATCH] ANDROID: vendor_hooks: protect multi-mapcount pages in kernel Support two hooks as follows to protect multi-mapcount pages in kernel: - trace_android_vh_page_should_be_protect - trace_android_vh_mapped_page_try_sorthead Bug: 236578020 Signed-off-by: Peifeng Li Change-Id: I688aceabf17d9de2feac7c3ad7144d307de6ef29 --- drivers/android/vendor_hooks.c | 2 ++ include/trace/hooks/mm.h | 6 ++++++ mm/swap.c | 1 + mm/vmscan.c | 13 +++++++++++++ 4 files changed, 22 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index ae0a674fe6f7..d7fab5cb876d 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -398,6 +398,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmap_region); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_update_page_mapcount); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_add_page_to_lrulist); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_del_page_from_lrulist); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_should_be_protected); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mark_page_accessed); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_unmap_one); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_id_remove); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_css_offline); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 68d792378b50..495f66d0f926 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -169,6 +169,12 @@ DECLARE_HOOK(android_vh_show_mapcount_pages, DECLARE_HOOK(android_vh_do_traversal_lruvec, TP_PROTO(struct lruvec *lruvec), TP_ARGS(lruvec)); +DECLARE_HOOK(android_vh_page_should_be_protected, + TP_PROTO(struct page *page, bool *should_protect), + TP_ARGS(page, should_protect)); +DECLARE_HOOK(android_vh_mark_page_accessed, + TP_PROTO(struct page *page), + TP_ARGS(page)); DECLARE_HOOK(android_vh_cma_drain_all_pages_bypass, TP_PROTO(unsigned int migratetype, bool *bypass), TP_ARGS(migratetype, bypass)); diff --git a/mm/swap.c b/mm/swap.c index abf445bd7721..16b2bc48211e 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -437,6 +437,7 @@ void mark_page_accessed(struct page *page) { page = compound_head(page); + trace_android_vh_mark_page_accessed(page); if (!PageReferenced(page)) { SetPageReferenced(page); } else if (PageUnevictable(page)) { diff --git a/mm/vmscan.c b/mm/vmscan.c index fef55a9ed60f..22ab1afed87f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1020,6 +1020,11 @@ static enum page_references page_check_references(struct page *page, { int referenced_ptes, referenced_page; unsigned long vm_flags; + bool should_protect = false; + + trace_android_vh_page_should_be_protected(page, &should_protect); + if (unlikely(should_protect)) + return PAGEREF_ACTIVATE; referenced_ptes = page_referenced(page, 1, sc->target_mem_cgroup, &vm_flags); @@ -2057,6 +2062,7 @@ static void shrink_active_list(unsigned long nr_to_scan, int file = is_file_lru(lru); struct pglist_data *pgdat = lruvec_pgdat(lruvec); bool bypass = false; + bool should_protect = false; lru_add_drain(); @@ -2091,6 +2097,13 @@ static void shrink_active_list(unsigned long nr_to_scan, } } + trace_android_vh_page_should_be_protected(page, &should_protect); + if (unlikely(should_protect)) { + nr_rotated += thp_nr_pages(page); + list_add(&page->lru, &l_active); + continue; + } + trace_android_vh_page_referenced_check_bypass(page, nr_to_scan, lru, &bypass); if (bypass) goto skip_page_referenced;