From d4eef93a9dbf860c43e813be8412ceb01958fcd5 Mon Sep 17 00:00:00 2001 From: Bing Han Date: Mon, 30 May 2022 16:28:05 +0800 Subject: [PATCH] ANDROID: vendor_hooks: Add hooks to extend struct swap_slots_cache Three vendor hooks are provided to extend struct swap_slots_cache. The extended data are used to record the information of the specified reclaimed swap location: 1) android_vh_alloc_swap_slot_cache, replace the function alloc_swap_slot_cache adding allocation of the extension of struct swap_slots_cache; 2) android_vh_drain_slots_cache_cpu, replace the function drain_slots_cache_cpu adding the initialization of the extension of struct swap_slots_cache; 3) android_vh_get_swap_page, replace the function get_swap_page, according to the reclaimed location information of the page, get the the swap page from the specified swap location; Bug: 234214858 Signed-off-by: Bing Han Change-Id: I3bce6e8cf255df1d879b7c4022d54981cce7c273 --- drivers/android/vendor_hooks.c | 3 +++ include/trace/hooks/mm.h | 12 ++++++++++++ mm/swap_slots.c | 18 +++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 40c0a4d8c41a..1f30d49f345b 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -416,7 +416,10 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_referenced_one_end); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_pswpin); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_pswpout); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_count_swpout_vm_event); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_drain_slots_cache_cpu); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_swap_slot_cache); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_swap_slot); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_swap_page); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_isolated_for_reclaim); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_inactive_is_low); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_snapshot_refaults); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index faab6883a579..c6f0f726392c 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -33,6 +33,7 @@ struct readahead_control; #include #endif /* __GENKSYMS__ */ struct cma; +struct swap_slots_cache; DECLARE_RESTRICTED_HOOK(android_rvh_set_skip_swapcache_flags, TP_PROTO(gfp_t *flags), @@ -176,9 +177,20 @@ DECLARE_HOOK(android_vh_count_pswpout, DECLARE_HOOK(android_vh_count_swpout_vm_event, TP_PROTO(struct swap_info_struct *sis, struct page *page, bool *skip), TP_ARGS(sis, page, skip)); +DECLARE_HOOK(android_vh_drain_slots_cache_cpu, + TP_PROTO(struct swap_slots_cache *cache, unsigned int type, + bool free_slots, bool *skip), + TP_ARGS(cache, type, free_slots, skip)); +DECLARE_HOOK(android_vh_alloc_swap_slot_cache, + TP_PROTO(struct swap_slots_cache *cache, int *ret, bool *skip), + TP_ARGS(cache, ret, skip)); DECLARE_HOOK(android_vh_free_swap_slot, TP_PROTO(swp_entry_t entry, struct swap_slots_cache *cache, bool *skip), TP_ARGS(entry, cache, skip)); +DECLARE_HOOK(android_vh_get_swap_page, + TP_PROTO(struct page *page, swp_entry_t *entry, + struct swap_slots_cache *cache, bool *found), + TP_ARGS(page, entry, cache, found)); DECLARE_HOOK(android_vh_page_isolated_for_reclaim, TP_PROTO(struct mm_struct *mm, struct page *page), TP_ARGS(mm, page)); diff --git a/mm/swap_slots.c b/mm/swap_slots.c index 25b5f0c6d44b..eee97a5f445b 100644 --- a/mm/swap_slots.c +++ b/mm/swap_slots.c @@ -33,6 +33,7 @@ #include #include #include +#include static DEFINE_PER_CPU(struct swap_slots_cache, swp_slots); static bool swap_slot_cache_active; @@ -115,12 +116,18 @@ static int alloc_swap_slot_cache(unsigned int cpu) { struct swap_slots_cache *cache; swp_entry_t *slots, *slots_ret; + bool skip = false; + int ret = 0; /* * Do allocation outside swap_slots_cache_mutex * as kvzalloc could trigger reclaim and get_swap_page, * which can lock swap_slots_cache_mutex. */ + trace_android_vh_alloc_swap_slot_cache(&per_cpu(swp_slots, cpu), + &ret, &skip); + if (skip) + return ret; slots = kvcalloc(SWAP_SLOTS_CACHE_SIZE, sizeof(swp_entry_t), GFP_KERNEL); if (!slots) @@ -171,8 +178,13 @@ static void drain_slots_cache_cpu(unsigned int cpu, unsigned int type, { struct swap_slots_cache *cache; swp_entry_t *slots = NULL; + bool skip = false; cache = &per_cpu(swp_slots, cpu); + trace_android_vh_drain_slots_cache_cpu(cache, type, + free_slots, &skip); + if (skip) + return; if ((type & SLOTS_CACHE) && cache->slots) { mutex_lock(&cache->alloc_lock); swapcache_free_entries(cache->slots + cache->cur, cache->nr); @@ -311,9 +323,13 @@ swp_entry_t get_swap_page(struct page *page) { swp_entry_t entry; struct swap_slots_cache *cache; - + bool found = false; entry.val = 0; + trace_android_vh_get_swap_page(page, &entry, raw_cpu_ptr(&swp_slots), &found); + if (found) + goto out; + if (PageTransHuge(page)) { if (IS_ENABLED(CONFIG_THP_SWAP)) get_swap_pages(1, &entry, HPAGE_PMD_NR);