summaryrefslogtreecommitdiffstats
path: root/lmkd
diff options
context:
space:
mode:
authorRobert Benea <robenea@google.com>2017-08-21 15:18:31 -0700
committerRobert Benea <robenea@google.com>2017-08-25 19:01:54 -0700
commitc47f2992b58bfcd1f5d75cd25dc8172eb4fb5cc9 (patch)
tree292f7b52b4e3e80811faffcf4ffe4f1f5bcdd172 /lmkd
parent24c29f1be49f47a6d8a098a10591d9c3f0d4e8ee (diff)
downloadcore-c47f2992b58bfcd1f5d75cd25dc8172eb4fb5cc9.tar.gz
core-c47f2992b58bfcd1f5d75cd25dc8172eb4fb5cc9.tar.bz2
core-c47f2992b58bfcd1f5d75cd25dc8172eb4fb5cc9.zip
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
Diffstat (limited to 'lmkd')
-rw-r--r--lmkd/lmkd.c52
1 files changed, 50 insertions, 2 deletions
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 <arpa/inet.h>
#include <errno.h>
+#include <inttypes.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include <sys/cdefs.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#include <cutils/properties.h>
@@ -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, &param);