From 844f26bc24cb8d7f53d2d580247e3f4d5d4fa401 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Mon, 15 Jul 2019 15:42:09 -0700 Subject: [PATCH] lmkd: Enable new kill strategy, add and adjust required system properties Enable new kill strategy when PSI mode is used in combination with ro.lmk.use_minfree_levels=false. Adjust ro.lmk.swap_free_low_percentage, introduce ro.lmk.psi_partial_stall_ms and ro.lmk.psi_complete_stall_ms system properties to support two levels of PSI events measuring partial and complete stalls. Add ro.lmk.use_new_strategy system property to switch to the old strategy if necessary. Bug: 132642304 Test: lmkd_unit_test, ACT memory pressure tests Change-Id: I6f1b65e19dbe9b58c862e5e4255270c82f0afb9a Signed-off-by: Suren Baghdasaryan --- lmkd/README.md | 8 ++++++++ lmkd/lmkd.c | 45 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/lmkd/README.md b/lmkd/README.md index a735955ae..8a7369273 100644 --- a/lmkd/README.md +++ b/lmkd/README.md @@ -80,3 +80,11 @@ properties: the threshold when system does not recover even after a kill. Default for low-RAM devices = 50, for high-end devices = 10 + + ro.lmk.psi_partial_stall_ms: partial PSI stall threshold in milliseconds for + triggering low memory notification. Default for + low-RAM devices = 200, for high-end devices = 70 + + ro.lmk.psi_complete_stall_ms: complete PSI stall threshold in milliseconds for + triggering critical memory notification. Default = + 700 diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 42e3db33e..1db3d5aab 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -133,6 +133,11 @@ /* ro.lmk.thrashing_limit_decay property defaults */ #define DEF_THRASHING_DECAY_LOWRAM 50 #define DEF_THRASHING_DECAY 10 +/* ro.lmk.psi_partial_stall_ms property defaults */ +#define DEF_PARTIAL_STALL_LOWRAM 200 +#define DEF_PARTIAL_STALL 70 +/* ro.lmk.psi_complete_stall_ms property defaults */ +#define DEF_COMPLETE_STALL 700 /* default to old in-kernel interface if no memory pressure events */ static bool use_inkernel_interface = true; @@ -174,6 +179,8 @@ static unsigned long kill_timeout_ms; static bool use_minfree_levels; static bool per_app_memcg; static int swap_free_low_percentage; +static int psi_partial_stall_ms; +static int psi_complete_stall_ms; static int thrashing_limit_pct; static int thrashing_limit_decay_pct; static bool use_psi_monitors = false; @@ -2406,8 +2413,15 @@ do_kill: } } -static bool init_mp_psi(enum vmpressure_level level) { - int fd = init_psi_monitor(psi_thresholds[level].stall_type, +static bool init_mp_psi(enum vmpressure_level level, bool use_new_strategy) { + int fd; + + /* Do not register a handler if threshold_ms is not set */ + if (!psi_thresholds[level].threshold_ms) { + return true; + } + + fd = init_psi_monitor(psi_thresholds[level].stall_type, psi_thresholds[level].threshold_ms * US_PER_MS, PSI_WINDOW_SIZE_MS * US_PER_MS); @@ -2415,7 +2429,7 @@ static bool init_mp_psi(enum vmpressure_level level) { return false; } - vmpressure_hinfo[level].handler = mp_event_common; + vmpressure_hinfo[level].handler = use_new_strategy ? mp_event_psi : mp_event_common; vmpressure_hinfo[level].data = level; if (register_psi_monitor(epollfd, fd, &vmpressure_hinfo[level]) < 0) { destroy_psi_monitor(fd); @@ -2439,14 +2453,29 @@ static void destroy_mp_psi(enum vmpressure_level level) { } static bool init_psi_monitors() { - if (!init_mp_psi(VMPRESS_LEVEL_LOW)) { + /* + * When PSI is used on low-ram devices or on high-end devices without memfree levels + * use new kill strategy based on zone watermarks, free swap and thrashing stats + */ + bool use_new_strategy = + property_get_bool("ro.lmk.use_new_strategy", low_ram_device || !use_minfree_levels); + + /* In default PSI mode override stall amounts using system properties */ + if (use_new_strategy) { + /* Do not use low pressure level */ + psi_thresholds[VMPRESS_LEVEL_LOW].threshold_ms = 0; + psi_thresholds[VMPRESS_LEVEL_MEDIUM].threshold_ms = psi_partial_stall_ms; + psi_thresholds[VMPRESS_LEVEL_CRITICAL].threshold_ms = psi_complete_stall_ms; + } + + if (!init_mp_psi(VMPRESS_LEVEL_LOW, use_new_strategy)) { return false; } - if (!init_mp_psi(VMPRESS_LEVEL_MEDIUM)) { + if (!init_mp_psi(VMPRESS_LEVEL_MEDIUM, use_new_strategy)) { destroy_mp_psi(VMPRESS_LEVEL_LOW); return false; } - if (!init_mp_psi(VMPRESS_LEVEL_CRITICAL)) { + if (!init_mp_psi(VMPRESS_LEVEL_CRITICAL, use_new_strategy)) { destroy_mp_psi(VMPRESS_LEVEL_MEDIUM); destroy_mp_psi(VMPRESS_LEVEL_LOW); return false; @@ -2831,6 +2860,10 @@ int main(int argc __unused, char **argv __unused) { property_get_bool("ro.config.per_app_memcg", low_ram_device); swap_free_low_percentage = clamp(0, 100, property_get_int32("ro.lmk.swap_free_low_percentage", low_ram_device ? DEF_LOW_SWAP_LOWRAM : DEF_LOW_SWAP)); + psi_partial_stall_ms = property_get_int32("ro.lmk.psi_partial_stall_ms", + low_ram_device ? DEF_PARTIAL_STALL_LOWRAM : DEF_PARTIAL_STALL); + psi_complete_stall_ms = property_get_int32("ro.lmk.psi_complete_stall_ms", + DEF_COMPLETE_STALL); thrashing_limit_pct = max(0, property_get_int32("ro.lmk.thrashing_limit", low_ram_device ? DEF_THRASHING_LOWRAM : DEF_THRASHING)); thrashing_limit_decay_pct = clamp(0, 100, property_get_int32("ro.lmk.thrashing_limit_decay",