From c47f2992b58bfcd1f5d75cd25dc8172eb4fb5cc9 Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Mon, 21 Aug 2017 15:18:31 -0700 Subject: Detect critical preassure When close to oom the system tend to become very thrashy and keeps paging. This change looks at the current working sent and checks it against swap. Test: tested on gobo Bug: 64721547 Change-Id: I93d42def93cbc03a01a54988fd5286ec9f124e36 --- lmkd/lmkd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'lmkd') diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 02a9601f9..08eff0901 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -18,17 +18,18 @@ #include #include +#include #include #include #include #include -#include #include #include #include #include #include #include +#include #include #include @@ -41,6 +42,8 @@ #endif #define MEMCG_SYSFS_PATH "/dev/memcg/" +#define MEMCG_MEMORY_USAGE "/dev/memcg/memory.usage_in_bytes" +#define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes" #define MEMPRESSURE_WATCH_MEDIUM_LEVEL "medium" #define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical" #define ZONEINFO_PATH "/proc/zoneinfo" @@ -75,7 +78,9 @@ static int mpevfd[2]; static int medium_oomadj; static int critical_oomadj; -static int debug_process_killing; +static bool debug_process_killing; +static bool enable_pressure_upgrade; +static int64_t upgrade_pressure; /* control socket listen and data */ static int ctrl_lfd; @@ -641,17 +646,58 @@ retry: return 0; } +static int64_t get_memory_usage(const char* path) { + int ret; + int64_t mem_usage; + char buf[32]; + int fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + ALOGE("%s open: errno=%d", path, errno); + return -1; + } + + ret = read_all(fd, buf, sizeof(buf) - 1); + close(fd); + if (ret < 0) { + ALOGE("%s error: errno=%d", path, errno); + return -1; + } + sscanf(buf, "%" SCNd64, &mem_usage); + if (mem_usage == 0) { + ALOGE("No memory!"); + return -1; + } + return mem_usage; +} + static void mp_event_common(bool is_critical) { int ret; unsigned long long evcount; int min_adj_score = is_critical ? critical_oomadj : medium_oomadj; int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; + int64_t mem_usage, memsw_usage; ret = read(mpevfd[index], &evcount, sizeof(evcount)); if (ret < 0) ALOGE("Error reading memory pressure event fd; errno=%d", errno); + if (enable_pressure_upgrade && !is_critical) { + mem_usage = get_memory_usage(MEMCG_MEMORY_USAGE); + memsw_usage = get_memory_usage(MEMCG_MEMORYSW_USAGE); + if (memsw_usage < 0 || mem_usage < 0) { + find_and_kill_process(min_adj_score, is_critical); + return; + } + + // We are swapping too much, calculate percent for swappinness. + if (((mem_usage * 100) / memsw_usage) < upgrade_pressure) { + ALOGI("Event upgraded to critical."); + min_adj_score = critical_oomadj; + is_critical = true; + } + } + if (find_and_kill_process(min_adj_score, is_critical) == 0) { if (debug_process_killing) { ALOGI("Nothing to kill"); @@ -827,6 +873,8 @@ int main(int argc __unused, char **argv __unused) { medium_oomadj = property_get_int32("ro.lmk.medium", 800); critical_oomadj = property_get_int32("ro.lmk.critical", 0); debug_process_killing = property_get_bool("ro.lmk.debug", false); + enable_pressure_upgrade = property_get_bool("ro.lmk.critical_upgrade", false); + upgrade_pressure = (int64_t)property_get_int32("ro.lmk.upgrade_pressure", 50); mlockall(MCL_FUTURE); sched_setscheduler(0, SCHED_FIFO, ¶m); -- cgit v1.2.3