diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8472847cbedd..82af4b916234 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -599,3 +599,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_suitable_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_wmark_ok); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_zone_max_order); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_zone_pageset); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_isolate_priv_lru); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_file_is_tiny); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_pgdat_balanced); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_reclaim_idx); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mm_customize_zone_can_compact); diff --git a/include/trace/hooks/compaction.h b/include/trace/hooks/compaction.h index c22b22386be8..2b546e63965f 100644 --- a/include/trace/hooks/compaction.h +++ b/include/trace/hooks/compaction.h @@ -19,6 +19,9 @@ enum compact_result; DECLARE_HOOK(android_vh_compaction_try_to_compact_exit, TP_PROTO(enum compact_result *compact_result), TP_ARGS(compact_result)); +DECLARE_HOOK(android_vh_mm_customize_zone_can_compact, + TP_PROTO(struct zone *zone, bool *can_compact), + TP_ARGS(zone, can_compact)); #endif /* _TRACE_HOOK_COMPACTION_H */ /* This part must be outside protection */ #include diff --git a/include/trace/hooks/vmscan.h b/include/trace/hooks/vmscan.h index e47dd8e03619..bd545f8444df 100644 --- a/include/trace/hooks/vmscan.h +++ b/include/trace/hooks/vmscan.h @@ -111,6 +111,20 @@ DECLARE_HOOK(android_vh_shrink_node, DECLARE_HOOK(android_vh_shrink_node_memcgs, TP_PROTO(struct mem_cgroup *memcg, bool *skip), TP_ARGS(memcg, skip)); +DECLARE_HOOK(android_vh_mm_isolate_priv_lru, + TP_PROTO(unsigned long nr_to_scan, struct lruvec *lruvec, enum lru_list lru, + struct list_head *dst, int reclaim_idx, bool may_unmap, + unsigned long *nr_scanned, unsigned long *nr_taken), + TP_ARGS(nr_to_scan, lruvec, lru, dst, reclaim_idx, may_unmap, nr_scanned, nr_taken)); +DECLARE_HOOK(android_vh_mm_customize_file_is_tiny, + TP_PROTO(unsigned int may_swap, int order, int highest_zoneidx, bool *file_is_tiny), + TP_ARGS(may_swap, order, highest_zoneidx, file_is_tiny)); +DECLARE_HOOK(android_vh_mm_customize_pgdat_balanced, + TP_PROTO(int order, int highest_zoneidx, bool *balanced, bool *customized), + TP_ARGS(order, highest_zoneidx, balanced, customized)); +DECLARE_HOOK(android_vh_mm_customize_reclaim_idx, + TP_PROTO(int order, gfp_t gfp, s8 *reclaim_idx, enum zone_type *highest_zoneidx), + TP_ARGS(order, gfp, reclaim_idx, highest_zoneidx)); #endif /* _TRACE_HOOK_VMSCAN_H */ /* This part must be outside protection */ #include diff --git a/mm/compaction.c b/mm/compaction.c index 182d7c99f820..ca7dab51554e 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -2854,6 +2854,11 @@ enum compact_result try_to_compact_pages(gfp_t gfp_mask, unsigned int order, for_each_zone_zonelist_nodemask(zone, z, ac->zonelist, ac->highest_zoneidx, ac->nodemask) { enum compact_result status; + bool can_compact = true; + + trace_android_vh_mm_customize_zone_can_compact(zone, &can_compact); + if (!can_compact) + continue; if (cpusets_enabled() && (alloc_flags & ALLOC_CPUSET) && @@ -2921,10 +2926,16 @@ void compact_node_async(int nid) }; for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) { + bool can_compact = true; + zone = &pgdat->node_zones[zoneid]; if (!populated_zone(zone)) continue; + trace_android_vh_mm_customize_zone_can_compact(zone, &can_compact); + if (!can_compact) + continue; + if (fatal_signal_pending(current)) break; @@ -2960,10 +2971,16 @@ static int compact_node(pg_data_t *pgdat, bool proactive) }; for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) { + bool can_compact = true; + zone = &pgdat->node_zones[zoneid]; if (!populated_zone(zone)) continue; + trace_android_vh_mm_customize_zone_can_compact(zone, &can_compact); + if (!can_compact) + continue; + if (fatal_signal_pending(current)) return -EINTR; @@ -3090,11 +3107,16 @@ static bool kcompactd_node_suitable(pg_data_t *pgdat) enum compact_result ret; for (zoneid = 0; zoneid <= highest_zoneidx; zoneid++) { + bool can_compact = true; zone = &pgdat->node_zones[zoneid]; if (!populated_zone(zone)) continue; + trace_android_vh_mm_customize_zone_can_compact(zone, &can_compact); + if (!can_compact) + continue; + ret = compaction_suit_allocation_order(zone, pgdat->kcompactd_max_order, highest_zoneidx, ALLOC_WMARK_MIN); @@ -3129,11 +3151,16 @@ static void kcompactd_do_work(pg_data_t *pgdat) for (zoneid = 0; zoneid <= cc.highest_zoneidx; zoneid++) { int status; + bool can_compact = true; zone = &pgdat->node_zones[zoneid]; if (!populated_zone(zone)) continue; + trace_android_vh_mm_customize_zone_can_compact(zone, &can_compact); + if (!can_compact) + continue; + if (compaction_deferred(zone, cc.order)) continue; diff --git a/mm/vmscan.c b/mm/vmscan.c index f78cfe059f14..2526acf3278f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1738,6 +1738,12 @@ static unsigned long isolate_lru_folios(unsigned long nr_to_scan, unsigned long skipped = 0; unsigned long scan, total_scan, nr_pages; LIST_HEAD(folios_skipped); + unsigned long nr_scanned_before = *nr_scanned; + + trace_android_vh_mm_isolate_priv_lru(nr_to_scan, lruvec, lru, dst, sc->reclaim_idx, + sc->may_unmap, nr_scanned, &nr_taken); + if (*nr_scanned != nr_scanned_before) + return nr_taken; total_scan = 0; scan = 0; @@ -1996,7 +2002,7 @@ static unsigned long shrink_inactive_list(unsigned long nr_to_scan, enum lru_list lru) { LIST_HEAD(folio_list); - unsigned long nr_scanned; + unsigned long nr_scanned = 0; unsigned int nr_reclaimed = 0; unsigned long nr_taken; struct reclaim_stat stat; @@ -2117,7 +2123,7 @@ static void shrink_active_list(unsigned long nr_to_scan, enum lru_list lru) { unsigned long nr_taken; - unsigned long nr_scanned; + unsigned long nr_scanned = 0; unsigned long vm_flags; LIST_HEAD(l_hold); /* The folios which were snipped off */ LIST_HEAD(l_active); @@ -2352,6 +2358,15 @@ static bool inactive_is_low(struct lruvec *lruvec, enum lru_list inactive_lru) return inactive * inactive_ratio < active; } +static void customize_sc_file_is_tiny(struct scan_control *sc) +{ + bool file_is_tiny = sc->file_is_tiny; + + trace_android_vh_mm_customize_file_is_tiny(sc->may_swap, sc->order, + sc->reclaim_idx, &file_is_tiny); + sc->file_is_tiny = file_is_tiny; +} + enum scan_balance { SCAN_EQUAL, SCAN_FRACT, @@ -2465,6 +2480,8 @@ static void prepare_scan_control(pg_data_t *pgdat, struct scan_control *sc) !(sc->may_deactivate & DEACTIVATE_ANON) && anon >> sc->priority; } + + customize_sc_file_is_tiny(sc); } /* @@ -6309,6 +6326,9 @@ static void shrink_zones(struct zonelist *zonelist, struct scan_control *sc) sc->reclaim_idx = gfp_zone(sc->gfp_mask); } + trace_android_vh_mm_customize_reclaim_idx(sc->order, sc->gfp_mask, + &sc->reclaim_idx, NULL); + for_each_zone_zonelist_nodemask(zone, z, zonelist, sc->reclaim_idx, sc->nodemask) { /* @@ -6860,8 +6880,15 @@ static bool pgdat_balanced(pg_data_t *pgdat, int order, int highest_zoneidx) { int i; unsigned long mark = -1; + bool customized = false; + bool balanced = false; struct zone *zone; + trace_android_vh_mm_customize_pgdat_balanced(order, highest_zoneidx, + &balanced, &customized); + if (customized) + return balanced; + /* * Check watermarks bottom-up as lower zones are more likely to * meet watermarks. @@ -7469,6 +7496,9 @@ void wakeup_kswapd(struct zone *zone, gfp_t gfp_flags, int order, if (!cpuset_zone_allowed(zone, gfp_flags)) return; + trace_android_vh_mm_customize_reclaim_idx(order, gfp_flags, NULL, + &highest_zoneidx); + pgdat = zone->zone_pgdat; curr_idx = READ_ONCE(pgdat->kswapd_highest_zoneidx);