Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c47f2992 authored by Robert Benea's avatar Robert Benea
Browse files

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
parent 24c29f1b
Loading
Loading
Loading
Loading
+50 −2
Original line number Original line Diff line number Diff line
@@ -18,17 +18,18 @@


#include <arpa/inet.h>
#include <arpa/inet.h>
#include <errno.h>
#include <errno.h>
#include <inttypes.h>
#include <sched.h>
#include <sched.h>
#include <signal.h>
#include <signal.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <time.h>
#include <sys/cdefs.h>
#include <sys/cdefs.h>
#include <sys/epoll.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/eventfd.h>
#include <sys/mman.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <unistd.h>


#include <cutils/properties.h>
#include <cutils/properties.h>
@@ -41,6 +42,8 @@
#endif
#endif


#define MEMCG_SYSFS_PATH "/dev/memcg/"
#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_MEDIUM_LEVEL "medium"
#define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical"
#define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical"
#define ZONEINFO_PATH "/proc/zoneinfo"
#define ZONEINFO_PATH "/proc/zoneinfo"
@@ -75,7 +78,9 @@ static int mpevfd[2];


static int medium_oomadj;
static int medium_oomadj;
static int critical_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 */
/* control socket listen and data */
static int ctrl_lfd;
static int ctrl_lfd;
@@ -641,17 +646,58 @@ retry:
    return 0;
    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) {
static void mp_event_common(bool is_critical) {
    int ret;
    int ret;
    unsigned long long evcount;
    unsigned long long evcount;
    int min_adj_score = is_critical ? critical_oomadj : medium_oomadj;
    int min_adj_score = is_critical ? critical_oomadj : medium_oomadj;
    int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
    int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
    int64_t mem_usage, memsw_usage;


    ret = read(mpevfd[index], &evcount, sizeof(evcount));
    ret = read(mpevfd[index], &evcount, sizeof(evcount));
    if (ret < 0)
    if (ret < 0)
        ALOGE("Error reading memory pressure event fd; errno=%d",
        ALOGE("Error reading memory pressure event fd; errno=%d",
              errno);
              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 (find_and_kill_process(min_adj_score, is_critical) == 0) {
        if (debug_process_killing) {
        if (debug_process_killing) {
            ALOGI("Nothing to kill");
            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);
    medium_oomadj = property_get_int32("ro.lmk.medium", 800);
    critical_oomadj = property_get_int32("ro.lmk.critical", 0);
    critical_oomadj = property_get_int32("ro.lmk.critical", 0);
    debug_process_killing = property_get_bool("ro.lmk.debug", false);
    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);
    mlockall(MCL_FUTURE);
    sched_setscheduler(0, SCHED_FIFO, &param);
    sched_setscheduler(0, SCHED_FIFO, &param);