ANDROID: vendor_hook: Added hook for memory reclaim tuning
The following hooks are added for memory reclaim tuning: android_vh_mm_isolate_priv_lru - This hook is used to properly handle certain folios when they are reclaimed. android_vh_mm_customize_file_is_tiny - For a specific process, we want only anonymous pages to be reclaimed. This hook allows vendors to modify the value of file_is_tiny to affect the reclaim behavior. android_vh_mm_customize_pgdat_balanced - When there are multiple zones, it is not always reasonable to perform indirect reclaim only when all zones do not meet the watermark. This hook allows vendors to customize pgdat_balanced to use their own strategy to determine whether to perform and stop indirect collection. android_vh_mm_customize_reclaim_idx - When there are multiple zones, vendors use this hook to customize which zones can be reclaimed. android_vh_mm_customize_zone_can_compact - When there are multiple zones, vendors use this hook to customize which zones can be compacted. Bug: 431672372 Change-Id: I860c2665088753a5c3b6d6dfeeb25a82aeefc8af Signed-off-by: Pengfei Li <pengfei.kernel@vivo.corp-partner.google.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 <trace/define_trace.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 <trace/define_trace.h>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+32
-2
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user