Snap for 8426163 from f6dc513ad77f32447c916edbdbed4955d1624c93 to mainline-tzdata2-release

Change-Id: I0d22739db2d53816baa393c0f812191508cdd722
diff --git a/.clang-format b/.clang-format
deleted file mode 120000
index 973b2fa..0000000
--- a/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-../../../build/soong/scripts/system-clang-format
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 4f53ded..f177b0d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,12 +1,13 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 cc_defaults {
     name: "stats_defaults",
-    cflags: [
-        "-DLMKD_LOG_STATS"
-    ],
+
+    product_variables: {
+        use_lmkd_stats_log: {
+            cflags: [
+                "-DLMKD_LOG_STATS"
+            ],
+        },
+    },
 }
 
 cc_binary {
@@ -18,14 +19,13 @@
         "liblog",
         "libprocessgroup",
         "libpsi",
+        "libstatssocket",
     ],
     static_libs: [
         "libstatslogc",
+        "libstatslog_lmkd",
         "liblmkd_utils",
     ],
-    header_libs: [
-        "bpf_syscall_wrappers",
-    ],
     local_include_dirs: ["include"],
     cflags: [
         "-Wall",
@@ -41,7 +41,6 @@
 cc_library_static {
     name: "libstatslogc",
     srcs: ["statslog.cpp"],
-    local_include_dirs: ["include"],
     cflags: [
         "-Wall",
         "-Werror",
@@ -51,6 +50,37 @@
     shared_libs: [
         "liblog",
     ],
+    static_libs: [
+        "libstatslog_lmkd",
+    ],
+}
+
+genrule {
+    name: "statslog_lmkd.h",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_lmkd.h --module lmkd --namespace android,lmkd,stats",
+    out: [
+        "statslog_lmkd.h",
+    ],
+}
+
+genrule {
+    name: "statslog_lmkd.cpp",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_lmkd.cpp --module lmkd --namespace android,lmkd,stats --importHeader statslog_lmkd.h",
+    out: [
+        "statslog_lmkd.cpp",
+    ],
+}
+
+cc_library_static {
+    name: "libstatslog_lmkd",
+    generated_sources: ["statslog_lmkd.cpp"],
+    generated_headers: ["statslog_lmkd.h"],
+    export_generated_headers: ["statslog_lmkd.h"],
+    shared_libs: [
+        "libstatssocket",
+    ],
 }
 
 cc_library_static {
diff --git a/event.logtags b/event.logtags
index 5382b49..452f411 100644
--- a/event.logtags
+++ b/event.logtags
@@ -35,4 +35,4 @@
 # TODO: generate ".java" and ".h" files with integer constants from this file.
 
 # for killinfo logs
-10195355 killinfo (Pid|1|5),(Uid|1|5),(OomAdj|1),(MinOomAdj|1),(TaskSize|1),(enum kill_reasons|1|5),(MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(IonHeap|1),(IonHeapPool|1),(CmaFree|1),(MsSinceEvent|1),(MsSincePrevWakeup|1),(WakeupsSinceEvent|1),(SkippedWakeups|1),(TaskSwapSize|1),(GPU|1)
+10195355 killinfo (Pid|1|5),(Uid|1|5),(OomAdj|1),(MinOomAdj|1),(TaskSize|1),(enum kill_reasons|1|5),(MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(IonHeap|1),(IonHeapPool|1),(CmaFree|1)
diff --git a/include/lmkd.h b/include/lmkd.h
index c814d17..ad5dc75 100644
--- a/include/lmkd.h
+++ b/include/lmkd.h
@@ -27,16 +27,14 @@
  * Supported LMKD commands
  */
 enum lmk_cmd {
-    LMK_TARGET = 0,         /* Associate minfree with oom_adj_score */
-    LMK_PROCPRIO,           /* Register a process and set its oom_adj_score */
-    LMK_PROCREMOVE,         /* Unregister a process */
-    LMK_PROCPURGE,          /* Purge all registered processes */
-    LMK_GETKILLCNT,         /* Get number of kills */
-    LMK_SUBSCRIBE,          /* Subscribe for asynchronous events */
-    LMK_PROCKILL,           /* Unsolicited msg to subscribed clients on proc kills */
-    LMK_UPDATE_PROPS,       /* Reinit properties */
-    LMK_STAT_KILL_OCCURRED, /* Unsolicited msg to subscribed clients on proc kills for statsd log */
-    LMK_STAT_STATE_CHANGED, /* Unsolicited msg to subscribed clients on state changed */
+    LMK_TARGET = 0, /* Associate minfree with oom_adj_score */
+    LMK_PROCPRIO,   /* Register a process and set its oom_adj_score */
+    LMK_PROCREMOVE, /* Unregister a process */
+    LMK_PROCPURGE,  /* Purge all registered processes */
+    LMK_GETKILLCNT, /* Get number of kills */
+    LMK_SUBSCRIBE,  /* Subscribe for asynchronous events */
+    LMK_PROCKILL,   /* Unsolicited msg to subscribed clients on proc kills */
+    LMK_UPDATE_PROPS, /* Reinit properties */
 };
 
 /*
@@ -206,11 +204,10 @@
     return 2 * sizeof(int);
 }
 
-/* Types of asynchronous events sent from lmkd to its clients */
+/* Types of asyncronous events sent from lmkd to its clients */
 enum async_event_type {
     LMK_ASYNC_EVENT_FIRST,
     LMK_ASYNC_EVENT_KILL = LMK_ASYNC_EVENT_FIRST,
-    LMK_ASYNC_EVENT_STAT,
     LMK_ASYNC_EVENT_COUNT,
 };
 
diff --git a/libpsi/Android.bp b/libpsi/Android.bp
index eff9f38..da0da08 100644
--- a/libpsi/Android.bp
+++ b/libpsi/Android.bp
@@ -1,23 +1,16 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 cc_library_headers {
     name: "libpsi_headers",
     export_include_dirs: ["include"],
-    vendor_available: true,
 }
 
 cc_library {
     name: "libpsi",
     srcs: ["psi.cpp"],
-    vendor_available: true,
     shared_libs: [
         "liblog"
     ],
     header_libs: [
         "libpsi_headers",
-        "libcutils_headers",
     ],
     export_header_lib_headers: [
         "libpsi_headers",
diff --git a/libpsi/psi.cpp b/libpsi/psi.cpp
index 89f07ed..f4d5d18 100644
--- a/libpsi/psi.cpp
+++ b/libpsi/psi.cpp
@@ -17,15 +17,10 @@
 #define LOG_TAG "libpsi"
 
 #include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
 #include <string.h>
 #include <sys/epoll.h>
-#include <unistd.h>
 
 #include <log/log.h>
-#include <cutils/fs.h>
-#include <stdio.h>
 #include "psi/psi.h"
 
 #define PSI_MON_FILE_MEMORY "/proc/pressure/memory"
diff --git a/lmkd.cpp b/lmkd.cpp
index 2f0df91..882ae4a 100644
--- a/lmkd.cpp
+++ b/lmkd.cpp
@@ -22,6 +22,7 @@
 #include <pwd.h>
 #include <sched.h>
 #include <signal.h>
+#include <statslog_lmkd.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
@@ -29,7 +30,6 @@
 #include <sys/epoll.h>
 #include <sys/eventfd.h>
 #include <sys/mman.h>
-#include <sys/pidfd.h>
 #include <sys/resource.h>
 #include <sys/socket.h>
 #include <sys/syscall.h>
@@ -53,9 +53,6 @@
 
 #include "statslog.h"
 
-#define BPF_FD_JUST_USE_INT
-#include "BpfSyscallWrappers.h"
-
 /*
  * Define LMKD_TRACE_KILLS to record lmkd kills in kernel traces
  * to profile and correlate with OOM kills
@@ -86,8 +83,6 @@
 #define MEMINFO_PATH "/proc/meminfo"
 #define VMSTAT_PATH "/proc/vmstat"
 #define PROC_STATUS_TGID_FIELD "Tgid:"
-#define PROC_STATUS_RSS_FIELD "VmRSS:"
-#define PROC_STATUS_SWAP_FIELD "VmSwap:"
 #define LINE_MAX 128
 
 #define PERCEPTIBLE_APP_ADJ 200
@@ -103,7 +98,6 @@
 #define EIGHT_MEGA (1 << 23)
 
 #define TARGET_UPDATE_MIN_INTERVAL_MS 1000
-#define THRASHING_RESET_INTERVAL_MS 1000
 
 #define NS_PER_MS (NS_PER_SEC / MS_PER_SEC)
 #define US_PER_MS (US_PER_SEC / MS_PER_SEC)
@@ -150,6 +144,15 @@
 
 #define LMKD_REINIT_PROP "lmkd.reinit"
 
+static inline int sys_pidfd_open(pid_t pid, unsigned int flags) {
+    return syscall(__NR_pidfd_open, pid, flags);
+}
+
+static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
+                                        unsigned int flags) {
+    return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
+}
+
 /* default to old in-kernel interface if no memory pressure events */
 static bool use_inkernel_interface = true;
 static bool has_inkernel_module;
@@ -199,9 +202,6 @@
 static int psi_complete_stall_ms;
 static int thrashing_limit_pct;
 static int thrashing_limit_decay_pct;
-static int thrashing_critical_pct;
-static int swap_util_max;
-static int64_t filecache_min_kb;
 static bool use_psi_monitors = false;
 static int kpoll_fd;
 static struct psi_threshold psi_thresholds[VMPRESS_LEVEL_COUNT] = {
@@ -332,18 +332,21 @@
 enum zoneinfo_node_field {
     ZI_NODE_NR_INACTIVE_FILE = 0,
     ZI_NODE_NR_ACTIVE_FILE,
+    ZI_NODE_WORKINGSET_REFAULT,
     ZI_NODE_FIELD_COUNT
 };
 
 static const char* const zoneinfo_node_field_names[ZI_NODE_FIELD_COUNT] = {
     "nr_inactive_file",
     "nr_active_file",
+    "workingset_refault",
 };
 
 union zoneinfo_node_fields {
     struct {
         int64_t nr_inactive_file;
         int64_t nr_active_file;
+        int64_t workingset_refault;
     } field;
     int64_t arr[ZI_NODE_FIELD_COUNT];
 };
@@ -364,6 +367,7 @@
     int64_t totalreserve_pages;
     int64_t total_inactive_file;
     int64_t total_active_file;
+    int64_t total_workingset_refault;
 };
 
 /* Fields to parse in /proc/meminfo */
@@ -435,7 +439,6 @@
         int64_t cma_free;
         /* fields below are calculated rather than read from the file */
         int64_t nr_file_pages;
-        int64_t total_gpu_kb;
     } field;
     int64_t arr[MI_FIELD_COUNT];
 };
@@ -446,7 +449,6 @@
     VS_INACTIVE_FILE,
     VS_ACTIVE_FILE,
     VS_WORKINGSET_REFAULT,
-    VS_WORKINGSET_REFAULT_FILE,
     VS_PGSCAN_KSWAPD,
     VS_PGSCAN_DIRECT,
     VS_PGSCAN_DIRECT_THROTTLE,
@@ -458,7 +460,6 @@
     "nr_inactive_file",
     "nr_active_file",
     "workingset_refault",
-    "workingset_refault_file",
     "pgscan_kswapd",
     "pgscan_direct",
     "pgscan_direct_throttle",
@@ -470,7 +471,6 @@
         int64_t nr_inactive_file;
         int64_t nr_active_file;
         int64_t workingset_refault;
-        int64_t workingset_refault_file;
         int64_t pgscan_kswapd;
         int64_t pgscan_direct;
         int64_t pgscan_direct_throttle;
@@ -762,49 +762,6 @@
     }
 }
 
-/*
- * Write the kill_stat/memory_stat over the data socket to be propagated via AMS to statsd
- */
-static void stats_write_lmk_kill_occurred(struct kill_stat *kill_st,
-                                          struct memory_stat *mem_st) {
-    LMK_KILL_OCCURRED_PACKET packet;
-    const size_t len = lmkd_pack_set_kill_occurred(packet, kill_st, mem_st);
-    if (len == 0) {
-        return;
-    }
-
-    for (int i = 0; i < MAX_DATA_CONN; i++) {
-        if (data_sock[i].sock >= 0 && data_sock[i].async_event_mask & 1 << LMK_ASYNC_EVENT_STAT) {
-            ctrl_data_write(i, packet, len);
-        }
-    }
-
-}
-
-static void stats_write_lmk_kill_occurred_pid(int pid, struct kill_stat *kill_st,
-                                              struct memory_stat *mem_st) {
-    kill_st->taskname = stats_get_task_name(pid);
-    if (kill_st->taskname != NULL) {
-        stats_write_lmk_kill_occurred(kill_st, mem_st);
-    }
-}
-
-/*
- * Write the state_changed over the data socket to be propagated via AMS to statsd
- */
-static void stats_write_lmk_state_changed(enum lmk_state state) {
-    LMKD_CTRL_PACKET packet_state_changed;
-    const size_t len = lmkd_pack_set_state_changed(packet_state_changed, state);
-    if (len == 0) {
-        return;
-    }
-    for (int i = 0; i < MAX_DATA_CONN; i++) {
-        if (data_sock[i].sock >= 0 && data_sock[i].async_event_mask & 1 << LMK_ASYNC_EVENT_STAT) {
-            ctrl_data_write(i, (char*)packet_state_changed, len);
-        }
-    }
-}
-
 static void poll_kernel(int poll_fd) {
     if (poll_fd == -1) {
         // not waiting
@@ -839,16 +796,8 @@
             ctrl_data_write_lmk_kill_occurred((pid_t)pid, (uid_t)uid);
             mem_st.process_start_time_ns = starttime * (NS_PER_SEC / sysconf(_SC_CLK_TCK));
             mem_st.rss_in_bytes = rss_in_pages * PAGE_SIZE;
-
-            struct kill_stat kill_st = {
-                .uid = static_cast<int32_t>(uid),
-                .kill_reason = NONE,
-                .oom_score = oom_score_adj,
-                .min_oom_score = min_score_adj,
-                .free_mem_kb = 0,
-                .free_swap_kb = 0,
-            };
-            stats_write_lmk_kill_occurred_pid(pid, &kill_st, &mem_st);
+            stats_write_lmk_kill_occurred_pid(uid, pid, oom_score_adj,
+                                              min_score_adj, 0, &mem_st);
         }
 
         free(taskname);
@@ -980,33 +929,30 @@
            (to->tv_nsec - from->tv_nsec) / (long)NS_PER_MS;
 }
 
-/* Reads /proc/pid/status into buf. */
-static bool read_proc_status(int pid, char *buf, size_t buf_sz) {
+static int proc_get_tgid(int pid) {
     char path[PATH_MAX];
+    char buf[PAGE_SIZE];
     int fd;
     ssize_t size;
+    char *pos;
+    int64_t tgid = -1;
 
     snprintf(path, PATH_MAX, "/proc/%d/status", pid);
     fd = open(path, O_RDONLY | O_CLOEXEC);
     if (fd < 0) {
-        return false;
+        return -1;
     }
 
-    size = read_all(fd, buf, buf_sz - 1);
-    close(fd);
+    size = read_all(fd, buf, sizeof(buf) - 1);
     if (size < 0) {
-        return false;
+        goto out;
     }
     buf[size] = 0;
-    return true;
-}
 
-/* Looks for tag in buf and parses the first integer */
-static bool parse_status_tag(char *buf, const char *tag, int64_t *out) {
-    char *pos = buf;
+    pos = buf;
     while (true) {
-        pos = strstr(pos, tag);
-        /* Stop if tag not found or found at the line beginning */
+        pos = strstr(pos, PROC_STATUS_TGID_FIELD);
+        /* Stop if TGID tag not found or found at the line beginning */
         if (pos == NULL || pos == buf || pos[-1] == '\n') {
             break;
         }
@@ -1014,12 +960,16 @@
     }
 
     if (pos == NULL) {
-        return false;
+        goto out;
     }
 
-    pos += strlen(tag);
-    while (*pos == ' ') ++pos;
-    return parse_int64(pos, out);
+    pos += strlen(PROC_STATUS_TGID_FIELD);
+    while (*pos == ' ') pos++;
+    parse_int64(pos, &tgid);
+
+out:
+    close(fd);
+    return (int)tgid;
 }
 
 static int proc_get_size(int pid) {
@@ -1083,8 +1033,7 @@
     struct lmk_procprio params;
     bool is_system_server;
     struct passwd *pwdrec;
-    int64_t tgid;
-    char buf[PAGE_SIZE];
+    int tgid;
 
     lmkd_pack_get_procprio(packet, field_count, &params);
 
@@ -1100,12 +1049,11 @@
     }
 
     /* Check if registered process is a thread group leader */
-    if (read_proc_status(params.pid, buf, sizeof(buf))) {
-        if (parse_status_tag(buf, PROC_STATUS_TGID_FIELD, &tgid) && tgid != params.pid) {
-            ALOGE("Attempt to register a task that is not a thread group leader "
-                  "(tid %d, tgid %" PRId64 ")", params.pid, tgid);
-            return;
-        }
+    tgid = proc_get_tgid(params.pid);
+    if (tgid >= 0 && tgid != params.pid) {
+        ALOGE("Attempt to register a task that is not a thread group leader (tid %d, tgid %d)",
+            params.pid, tgid);
+        return;
     }
 
     /* gid containing AID_READPROC required */
@@ -1175,7 +1123,7 @@
         int pidfd = -1;
 
         if (pidfd_supported) {
-            pidfd = TEMP_FAILURE_RETRY(pidfd_open(params.pid, 0));
+            pidfd = TEMP_FAILURE_RETRY(sys_pidfd_open(params.pid, 0));
             if (pidfd < 0) {
                 ALOGE("pidfd_open for pid %d failed; errno=%d", params.pid, errno);
                 return;
@@ -1197,10 +1145,9 @@
     } else {
         if (!claim_record(procp, cred->pid)) {
             char buf[LINE_MAX];
-            char *taskname = proc_get_name(cred->pid, buf, sizeof(buf));
             /* Only registrant of the record can remove it */
             ALOGE("%s (%d, %d) attempts to modify a process registered by another client",
-                taskname ? taskname : "A process ", cred->uid, cred->pid);
+                proc_get_name(cred->pid, buf, sizeof(buf)), cred->uid, cred->pid);
             return;
         }
         proc_unslot(procp);
@@ -1235,10 +1182,9 @@
 
     if (!claim_record(procp, cred->pid)) {
         char buf[LINE_MAX];
-        char *taskname = proc_get_name(cred->pid, buf, sizeof(buf));
         /* Only registrant of the record can remove it */
         ALOGE("%s (%d, %d) attempts to unregister a process registered by another client",
-            taskname ? taskname : "A process ", cred->uid, cred->pid);
+            proc_get_name(cred->pid, buf, sizeof(buf)), cred->uid, cred->pid);
         return;
     }
 
@@ -1759,6 +1705,7 @@
         }
         zi->total_inactive_file += node->fields.field.nr_inactive_file;
         zi->total_active_file += node->fields.field.nr_active_file;
+        zi->total_workingset_refault += node->fields.field.workingset_refault;
     }
     return 0;
 }
@@ -1790,21 +1737,6 @@
     return (match_res != PARSE_FAIL);
 }
 
-static int64_t read_gpu_total_kb() {
-    static int fd = android::bpf::bpfFdGet(
-            "/sys/fs/bpf/map_gpu_mem_gpu_mem_total_map", BPF_F_RDONLY);
-    static constexpr uint64_t kBpfKeyGpuTotalUsage = 0;
-    uint64_t value;
-
-    if (fd < 0) {
-        return 0;
-    }
-
-    return android::bpf::findMapEntry(fd, &kBpfKeyGpuTotalUsage, &value)
-            ? 0
-            : (int32_t)(value / 1024);
-}
-
 static int meminfo_parse(union meminfo *mi) {
     static struct reread_data file_data = {
         .filename = MEMINFO_PATH,
@@ -1829,7 +1761,6 @@
     }
     mi->field.nr_file_pages = mi->field.cached + mi->field.swap_cached +
         mi->field.buffers;
-    mi->field.total_gpu_kb = read_gpu_total_kb();
 
     return 0;
 }
@@ -1887,50 +1818,14 @@
     return 0;
 }
 
-enum wakeup_reason {
-    Event,
-    Polling
-};
-
-struct wakeup_info {
-    struct timespec wakeup_tm;
-    struct timespec prev_wakeup_tm;
-    struct timespec last_event_tm;
-    int wakeups_since_event;
-    int skipped_wakeups;
-};
-
-/*
- * After the initial memory pressure event is received lmkd schedules periodic wakeups to check
- * the memory conditions and kill if needed (polling). This is done because pressure events are
- * rate-limited and memory conditions can change in between events. Therefore after the initial
- * event there might be multiple wakeups. This function records the wakeup information such as the
- * timestamps of the last event and the last wakeup, the number of wakeups since the last event
- * and how many of those wakeups were skipped (some wakeups are skipped if previously killed
- * process is still freeing its memory).
- */
-static void record_wakeup_time(struct timespec *tm, enum wakeup_reason reason,
-                               struct wakeup_info *wi) {
-    wi->prev_wakeup_tm = wi->wakeup_tm;
-    wi->wakeup_tm = *tm;
-    if (reason == Event) {
-        wi->last_event_tm = *tm;
-        wi->wakeups_since_event = 0;
-        wi->skipped_wakeups = 0;
-    } else {
-        wi->wakeups_since_event++;
-    }
-}
-
-static void killinfo_log(struct proc* procp, int min_oom_score, int rss_kb,
-                         int swap_kb, int kill_reason, union meminfo *mi,
-                         struct wakeup_info *wi, struct timespec *tm) {
+static void killinfo_log(struct proc* procp, int min_oom_score, int tasksize,
+                         int kill_reason, union meminfo *mi) {
     /* log process information */
     android_log_write_int32(ctx, procp->pid);
     android_log_write_int32(ctx, procp->uid);
     android_log_write_int32(ctx, procp->oomadj);
     android_log_write_int32(ctx, min_oom_score);
-    android_log_write_int32(ctx, (int32_t)min(rss_kb, INT32_MAX));
+    android_log_write_int32(ctx, (int32_t)min(tasksize * page_k, INT32_MAX));
     android_log_write_int32(ctx, kill_reason);
 
     /* log meminfo fields */
@@ -1938,14 +1833,6 @@
         android_log_write_int32(ctx, (int32_t)min(mi->arr[field_idx] * page_k, INT32_MAX));
     }
 
-    /* log lmkd wakeup information */
-    android_log_write_int32(ctx, (int32_t)get_time_diff_ms(&wi->last_event_tm, tm));
-    android_log_write_int32(ctx, (int32_t)get_time_diff_ms(&wi->prev_wakeup_tm, tm));
-    android_log_write_int32(ctx, wi->wakeups_since_event);
-    android_log_write_int32(ctx, wi->skipped_wakeups);
-    android_log_write_int32(ctx, (int32_t)min(swap_kb, INT32_MAX));
-    android_log_write_int32(ctx, (int32_t)mi->field.total_gpu_kb);
-
     android_log_write_list(ctx, LOG_ID_EVENTS);
     android_log_reset(ctx);
 }
@@ -1962,7 +1849,7 @@
     while (curr != head) {
         int pid = ((struct proc *)curr)->pid;
         int tasksize = proc_get_size(pid);
-        if (tasksize < 0) {
+        if (tasksize <= 0) {
             struct adjslot_list *next = curr->next;
             pid_remove(pid);
             curr = next;
@@ -2110,55 +1997,37 @@
     maxevents++;
 }
 
-struct kill_info {
-    enum kill_reasons kill_reason;
-    const char *kill_desc;
-    int thrashing;
-    int max_thrashing;
-};
-
-/* Kill one process specified by procp.  Returns the size (in pages) of the process killed */
-static int kill_one_process(struct proc* procp, int min_oom_score, struct kill_info *ki,
-                            union meminfo *mi, struct wakeup_info *wi, struct timespec *tm) {
+/* Kill one process specified by procp.  Returns the size of the process killed */
+static int kill_one_process(struct proc* procp, int min_oom_score, int kill_reason,
+                            const char *kill_desc, union meminfo *mi, struct timespec *tm) {
     int pid = procp->pid;
     int pidfd = procp->pidfd;
     uid_t uid = procp->uid;
+    int tgid;
     char *taskname;
+    int tasksize;
     int r;
     int result = -1;
     struct memory_stat *mem_st;
-    struct kill_stat kill_st;
-    int64_t tgid;
-    int64_t rss_kb;
-    int64_t swap_kb;
-    char buf[PAGE_SIZE];
+    char buf[LINE_MAX];
 
-    if (!read_proc_status(pid, buf, sizeof(buf))) {
-        goto out;
-    }
-    if (!parse_status_tag(buf, PROC_STATUS_TGID_FIELD, &tgid)) {
-        ALOGE("Unable to parse tgid from /proc/%d/status", pid);
-        goto out;
-    }
-    if (tgid != pid) {
-        ALOGE("Possible pid reuse detected (pid %d, tgid %" PRId64 ")!", pid, tgid);
-        goto out;
-    }
-    // Zombie processes will not have RSS / Swap fields.
-    if (!parse_status_tag(buf, PROC_STATUS_RSS_FIELD, &rss_kb)) {
-        goto out;
-    }
-    if (!parse_status_tag(buf, PROC_STATUS_SWAP_FIELD, &swap_kb)) {
+    tgid = proc_get_tgid(pid);
+    if (tgid >= 0 && tgid != pid) {
+        ALOGE("Possible pid reuse detected (pid %d, tgid %d)!", pid, tgid);
         goto out;
     }
 
     taskname = proc_get_name(pid, buf, sizeof(buf));
-    // taskname will point inside buf, do not reuse buf onwards.
     if (!taskname) {
         goto out;
     }
 
-    mem_st = stats_read_memory_stat(per_app_memcg, pid, uid, rss_kb * 1024, swap_kb * 1024);
+    tasksize = proc_get_size(pid);
+    if (tasksize <= 0) {
+        goto out;
+    }
+
+    mem_st = stats_read_memory_stat(per_app_memcg, pid, uid);
 
     TRACE_KILL_START(pid);
 
@@ -2168,7 +2037,7 @@
         r = kill(pid, SIGKILL);
     } else {
         start_wait_for_proc_kill(pidfd);
-        r = pidfd_send_signal(pidfd, SIGKILL, NULL, 0);
+        r = sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0);
     }
 
     TRACE_KILL_END();
@@ -2186,34 +2055,21 @@
 
     inc_killcnt(procp->oomadj);
 
-    if (ki) {
-        kill_st.kill_reason = ki->kill_reason;
-        kill_st.thrashing = ki->thrashing;
-        kill_st.max_thrashing = ki->max_thrashing;
-        killinfo_log(procp, min_oom_score, rss_kb, swap_kb, ki->kill_reason, mi, wi, tm);
-        ALOGI("Kill '%s' (%d), uid %d, oom_score_adj %d to free %" PRId64 "kB rss, %" PRId64
-              "kB swap; reason: %s", taskname, pid, uid, procp->oomadj, rss_kb, swap_kb,
-              ki->kill_desc);
+    killinfo_log(procp, min_oom_score, tasksize, kill_reason, mi);
+
+    if (kill_desc) {
+        ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB; reason: %s", taskname, pid,
+              uid, procp->oomadj, tasksize * page_k, kill_desc);
     } else {
-        kill_st.kill_reason = NONE;
-        kill_st.thrashing = 0;
-        kill_st.max_thrashing = 0;
-        killinfo_log(procp, min_oom_score, rss_kb, swap_kb, NONE, mi, wi, tm);
-        ALOGI("Kill '%s' (%d), uid %d, oom_score_adj %d to free %" PRId64 "kB rss, %" PRId64
-              "kb swap", taskname, pid, uid, procp->oomadj, rss_kb, swap_kb);
+        ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB", taskname, pid,
+              uid, procp->oomadj, tasksize * page_k);
     }
 
-    kill_st.uid = static_cast<int32_t>(uid);
-    kill_st.taskname = taskname;
-    kill_st.oom_score = procp->oomadj;
-    kill_st.min_oom_score = min_oom_score;
-    kill_st.free_mem_kb = mi->field.nr_free_pages * page_k;
-    kill_st.free_swap_kb = mi->field.free_swap * page_k;
-    stats_write_lmk_kill_occurred(&kill_st, mem_st);
+    stats_write_lmk_kill_occurred(uid, taskname, procp->oomadj, min_oom_score, tasksize, mem_st);
 
     ctrl_data_write_lmk_kill_occurred((pid_t)pid, uid);
 
-    result = rss_kb / page_k;
+    result = tasksize;
 
 out:
     /*
@@ -2225,39 +2081,31 @@
 }
 
 /*
- * Find one process to kill at or above the given oom_score_adj level.
+ * Find one process to kill at or above the given oom_adj level.
  * Returns size of the killed process.
  */
-static int find_and_kill_process(int min_score_adj, struct kill_info *ki, union meminfo *mi,
-                                 struct wakeup_info *wi, struct timespec *tm) {
+static int find_and_kill_process(int min_score_adj, int kill_reason, const char *kill_desc,
+                                 union meminfo *mi, struct timespec *tm) {
     int i;
     int killed_size = 0;
     bool lmk_state_change_start = false;
-    bool choose_heaviest_task = kill_heaviest_task;
 
     for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) {
         struct proc *procp;
 
-        if (!choose_heaviest_task && i <= PERCEPTIBLE_APP_ADJ) {
-            /*
-             * If we have to choose a perceptible process, choose the heaviest one to
-             * hopefully minimize the number of victims.
-             */
-            choose_heaviest_task = true;
-        }
-
         while (true) {
-            procp = choose_heaviest_task ?
+            procp = kill_heaviest_task ?
                 proc_get_heaviest(i) : proc_adj_lru(i);
 
             if (!procp)
                 break;
 
-            killed_size = kill_one_process(procp, min_score_adj, ki, mi, wi, tm);
+            killed_size = kill_one_process(procp, min_score_adj, kill_reason, kill_desc, mi, tm);
             if (killed_size >= 0) {
                 if (!lmk_state_change_start) {
                     lmk_state_change_start = true;
-                    stats_write_lmk_state_changed(STATE_START);
+                    stats_write_lmk_state_changed(
+                            android::lmkd::stats::LMK_STATE_CHANGED__STATE__START);
                 }
                 break;
             }
@@ -2268,7 +2116,7 @@
     }
 
     if (lmk_state_change_start) {
-        stats_write_lmk_state_changed(STATE_STOP);
+        stats_write_lmk_state_changed(android::lmkd::stats::LMK_STATE_CHANGED__STATE__STOP);
     }
 
     return killed_size;
@@ -2382,34 +2230,32 @@
     }
 }
 
-static int calc_swap_utilization(union meminfo *mi) {
-    int64_t swap_used = mi->field.total_swap - mi->field.free_swap;
-    int64_t total_swappable = mi->field.active_anon + mi->field.inactive_anon +
-                              mi->field.shmem + swap_used;
-    return total_swappable > 0 ? (swap_used * 100) / total_swappable : 0;
-}
-
 static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_params) {
+    enum kill_reasons {
+        NONE = -1, /* To denote no kill condition */
+        PRESSURE_AFTER_KILL = 0,
+        NOT_RESPONDING,
+        LOW_SWAP_AND_THRASHING,
+        LOW_MEM_AND_SWAP,
+        LOW_MEM_AND_THRASHING,
+        DIRECT_RECL_AND_THRASHING,
+        KILL_REASON_COUNT
+    };
     enum reclaim_state {
         NO_RECLAIM = 0,
         KSWAPD_RECLAIM,
         DIRECT_RECLAIM,
     };
     static int64_t init_ws_refault;
-    static int64_t prev_workingset_refault;
     static int64_t base_file_lru;
     static int64_t init_pgscan_kswapd;
     static int64_t init_pgscan_direct;
     static int64_t swap_low_threshold;
     static bool killing;
-    static int thrashing_limit = thrashing_limit_pct;
+    static int thrashing_limit;
+    static bool in_reclaim;
     static struct zone_watermarks watermarks;
     static struct timespec wmark_update_tm;
-    static struct wakeup_info wi;
-    static struct timespec thrashing_reset_tm;
-    static int64_t prev_thrash_growth = 0;
-    static bool check_filecache = false;
-    static int max_thrashing = 0;
 
     union meminfo mi;
     union vmstat vs;
@@ -2424,22 +2270,16 @@
     char kill_desc[LINE_MAX];
     bool cut_thrashing_limit = false;
     int min_score_adj = 0;
-    int swap_util = 0;
-    long since_thrashing_reset_ms;
-    int64_t workingset_refault_file;
 
     if (clock_gettime(CLOCK_MONOTONIC_COARSE, &curr_tm) != 0) {
         ALOGE("Failed to get current time");
         return;
     }
 
-    record_wakeup_time(&curr_tm, events ? Event : Polling, &wi);
-
     bool kill_pending = is_kill_pending();
     if (kill_pending && (kill_timeout_ms == 0 ||
         get_time_diff_ms(&last_kill_tm, &curr_tm) < static_cast<long>(kill_timeout_ms))) {
         /* Skip while still killing a process */
-        wi.skipped_wakeups++;
         goto no_kill;
     }
     /*
@@ -2452,8 +2292,6 @@
         ALOGE("Failed to parse vmstat!");
         return;
     }
-    /* Starting 5.9 kernel workingset_refault vmstat field was renamed workingset_refault_file */
-    workingset_refault_file = vs.field.workingset_refault ? : vs.field.workingset_refault_file;
 
     if (meminfo_parse(&mi) < 0) {
         ALOGE("Failed to parse meminfo!");
@@ -2466,9 +2304,7 @@
         cycle_after_kill = true;
         /* Reset file-backed pagecache size and refault amounts after a kill */
         base_file_lru = vs.field.nr_inactive_file + vs.field.nr_active_file;
-        init_ws_refault = workingset_refault_file;
-        thrashing_reset_tm = curr_tm;
-        prev_thrash_growth = 0;
+        init_ws_refault = vs.field.workingset_refault;
     }
 
     /* Check free swap levels */
@@ -2487,57 +2323,22 @@
     } else if (vs.field.pgscan_kswapd > init_pgscan_kswapd) {
         init_pgscan_kswapd = vs.field.pgscan_kswapd;
         reclaim = KSWAPD_RECLAIM;
-    } else if (workingset_refault_file == prev_workingset_refault) {
-        /*
-         * Device is not thrashing and not reclaiming, bail out early until we see these stats
-         * changing
-         */
+    } else {
+        in_reclaim = false;
+        /* Skip if system is not reclaiming */
         goto no_kill;
     }
 
-    prev_workingset_refault = workingset_refault_file;
-
-     /*
-     * It's possible we fail to find an eligible process to kill (ex. no process is
-     * above oom_adj_min). When this happens, we should retry to find a new process
-     * for a kill whenever a new eligible process is available. This is especially
-     * important for a slow growing refault case. While retrying, we should keep
-     * monitoring new thrashing counter as someone could release the memory to mitigate
-     * the thrashing. Thus, when thrashing reset window comes, we decay the prev thrashing
-     * counter by window counts. If the counter is still greater than thrashing limit,
-     * we preserve the current prev_thrash counter so we will retry kill again. Otherwise,
-     * we reset the prev_thrash counter so we will stop retrying.
-     */
-    since_thrashing_reset_ms = get_time_diff_ms(&thrashing_reset_tm, &curr_tm);
-    if (since_thrashing_reset_ms > THRASHING_RESET_INTERVAL_MS) {
-        long windows_passed;
-        /* Calculate prev_thrash_growth if we crossed THRASHING_RESET_INTERVAL_MS */
-        prev_thrash_growth = (workingset_refault_file - init_ws_refault) * 100
-                            / (base_file_lru + 1);
-        windows_passed = (since_thrashing_reset_ms / THRASHING_RESET_INTERVAL_MS);
-        /*
-         * Decay prev_thrashing unless over-the-limit thrashing was registered in the window we
-         * just crossed, which means there were no eligible processes to kill. We preserve the
-         * counter in that case to ensure a kill if a new eligible process appears.
-         */
-        if (windows_passed > 1 || prev_thrash_growth < thrashing_limit) {
-            prev_thrash_growth >>= windows_passed;
-        }
-
-        /* Record file-backed pagecache size when crossing THRASHING_RESET_INTERVAL_MS */
+    if (!in_reclaim) {
+        /* Record file-backed pagecache size when entering reclaim cycle */
         base_file_lru = vs.field.nr_inactive_file + vs.field.nr_active_file;
-        init_ws_refault = workingset_refault_file;
-        thrashing_reset_tm = curr_tm;
+        init_ws_refault = vs.field.workingset_refault;
         thrashing_limit = thrashing_limit_pct;
     } else {
         /* Calculate what % of the file-backed pagecache refaulted so far */
-        thrashing = (workingset_refault_file - init_ws_refault) * 100 / (base_file_lru + 1);
+        thrashing = (vs.field.workingset_refault - init_ws_refault) * 100 / base_file_lru;
     }
-    /* Add previous cycle's decayed thrashing amount */
-    thrashing += prev_thrash_growth;
-    if (max_thrashing < thrashing) {
-        max_thrashing = thrashing;
-    }
+    in_reclaim = true;
 
     /*
      * Refresh watermarks once per min in case user updated one of the margins.
@@ -2554,7 +2355,7 @@
 
         calc_zone_watermarks(&zi, &watermarks);
         wmark_update_tm = curr_tm;
-    }
+     }
 
     /* Find out which watermark is breached if any */
     wmark = get_lowest_watermark(&mi, &watermarks);
@@ -2585,81 +2386,44 @@
         snprintf(kill_desc, sizeof(kill_desc), "device is low on swap (%" PRId64
             "kB < %" PRId64 "kB) and thrashing (%" PRId64 "%%)",
             mi.field.free_swap * page_k, swap_low_threshold * page_k, thrashing);
-        /* Do not kill perceptible apps unless below min watermark or heavily thrashing */
-        if (wmark > WMARK_MIN && thrashing < thrashing_critical_pct) {
+        /* Do not kill perceptible apps unless below min watermark */
+        if (wmark > WMARK_MIN) {
             min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
         }
-        check_filecache = true;
     } else if (swap_is_low && wmark < WMARK_HIGH) {
         /* Both free memory and swap are low */
         kill_reason = LOW_MEM_AND_SWAP;
         snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and swap is low (%"
-            PRId64 "kB < %" PRId64 "kB)", wmark < WMARK_LOW ? "min" : "low",
+            PRId64 "kB < %" PRId64 "kB)", wmark > WMARK_LOW ? "min" : "low",
             mi.field.free_swap * page_k, swap_low_threshold * page_k);
-        /* Do not kill perceptible apps unless below min watermark or heavily thrashing */
-        if (wmark > WMARK_MIN && thrashing < thrashing_critical_pct) {
+        /* Do not kill perceptible apps unless below min watermark */
+        if (wmark > WMARK_MIN) {
             min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
         }
-    } else if (wmark < WMARK_HIGH && swap_util_max < 100 &&
-               (swap_util = calc_swap_utilization(&mi)) > swap_util_max) {
-        /*
-         * Too much anon memory is swapped out but swap is not low.
-         * Non-swappable allocations created memory pressure.
-         */
-        kill_reason = LOW_MEM_AND_SWAP_UTIL;
-        snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and swap utilization"
-            " is high (%d%% > %d%%)", wmark < WMARK_LOW ? "min" : "low",
-            swap_util, swap_util_max);
     } else if (wmark < WMARK_HIGH && thrashing > thrashing_limit) {
         /* Page cache is thrashing while memory is low */
         kill_reason = LOW_MEM_AND_THRASHING;
         snprintf(kill_desc, sizeof(kill_desc), "%s watermark is breached and thrashing (%"
-            PRId64 "%%)", wmark < WMARK_LOW ? "min" : "low", thrashing);
+            PRId64 "%%)", wmark > WMARK_LOW ? "min" : "low", thrashing);
         cut_thrashing_limit = true;
-        /* Do not kill perceptible apps unless thrashing at critical levels */
-        if (thrashing < thrashing_critical_pct) {
-            min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
-        }
-        check_filecache = true;
+        /* Do not kill perceptible apps because of thrashing */
+        min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
     } else if (reclaim == DIRECT_RECLAIM && thrashing > thrashing_limit) {
         /* Page cache is thrashing while in direct reclaim (mostly happens on lowram devices) */
         kill_reason = DIRECT_RECL_AND_THRASHING;
         snprintf(kill_desc, sizeof(kill_desc), "device is in direct reclaim and thrashing (%"
             PRId64 "%%)", thrashing);
         cut_thrashing_limit = true;
-        /* Do not kill perceptible apps unless thrashing at critical levels */
-        if (thrashing < thrashing_critical_pct) {
-            min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
-        }
-        check_filecache = true;
-    } else if (check_filecache) {
-        int64_t file_lru_kb = (vs.field.nr_inactive_file + vs.field.nr_active_file) * page_k;
-
-        if (file_lru_kb < filecache_min_kb) {
-            /* File cache is too low after thrashing, keep killing background processes */
-            kill_reason = LOW_FILECACHE_AFTER_THRASHING;
-            snprintf(kill_desc, sizeof(kill_desc),
-                "filecache is low (%" PRId64 "kB < %" PRId64 "kB) after thrashing",
-                file_lru_kb, filecache_min_kb);
-            min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
-        } else {
-            /* File cache is big enough, stop checking */
-            check_filecache = false;
-        }
+        /* Do not kill perceptible apps because of thrashing */
+        min_score_adj = PERCEPTIBLE_APP_ADJ + 1;
     }
 
     /* Kill a process if necessary */
     if (kill_reason != NONE) {
-        struct kill_info ki = {
-            .kill_reason = kill_reason,
-            .kill_desc = kill_desc,
-            .thrashing = (int)thrashing,
-            .max_thrashing = max_thrashing,
-        };
-        int pages_freed = find_and_kill_process(min_score_adj, &ki, &mi, &wi, &curr_tm);
+        int pages_freed = find_and_kill_process(min_score_adj, kill_reason, kill_desc, &mi,
+                                                &curr_tm);
         if (pages_freed > 0) {
             killing = true;
-            max_thrashing = 0;
             if (cut_thrashing_limit) {
                 /*
                  * Cut thrasing limit by thrashing_limit_decay_pct percentage of the current
@@ -2718,7 +2482,6 @@
         .filename = MEMCG_MEMORYSW_USAGE,
         .fd = -1,
     };
-    static struct wakeup_info wi;
 
     if (debug_process_killing) {
         ALOGI("%s memory pressure event is triggered", level_name[level]);
@@ -2754,8 +2517,6 @@
         return;
     }
 
-    record_wakeup_time(&curr_tm, events ? Event : Polling, &wi);
-
     if (kill_timeout_ms &&
         get_time_diff_ms(&last_kill_tm, &curr_tm) < static_cast<long>(kill_timeout_ms)) {
         /*
@@ -2764,7 +2525,6 @@
          */
         if (is_kill_pending()) {
             kill_skip_count++;
-            wi.skipped_wakeups++;
             return;
         }
         /*
@@ -2876,7 +2636,7 @@
 do_kill:
     if (low_ram_device) {
         /* For Go devices kill only one task */
-        if (find_and_kill_process(level_oomadj[level], NULL, &mi, &wi, &curr_tm) == 0) {
+        if (find_and_kill_process(level_oomadj[level], -1, NULL, &mi, &curr_tm) == 0) {
             if (debug_process_killing) {
                 ALOGI("Nothing to kill");
             }
@@ -2899,7 +2659,7 @@
             min_score_adj = level_oomadj[level];
         }
 
-        pages_freed = find_and_kill_process(min_score_adj, NULL, &mi, &wi, &curr_tm);
+        pages_freed = find_and_kill_process(min_score_adj, -1, NULL, &mi, &curr_tm);
 
         if (pages_freed == 0) {
             /* Rate limit kill reports when nothing was reclaimed */
@@ -2911,14 +2671,15 @@
 
         /* Log whenever we kill or when report rate limit allows */
         if (use_minfree_levels) {
-            ALOGI("Reclaimed %ldkB, cache(%ldkB) and free(%" PRId64 "kB)-reserved(%" PRId64 "kB) "
-                "below min(%ldkB) for oom_score_adj %d",
+            ALOGI("Reclaimed %ldkB, cache(%ldkB) and "
+                "free(%" PRId64 "kB)-reserved(%" PRId64 "kB) below min(%ldkB) for oom_adj %d",
                 pages_freed * page_k,
                 other_file * page_k, mi.field.nr_free_pages * page_k,
                 zi.totalreserve_pages * page_k,
                 minfree * page_k, min_score_adj);
         } else {
-            ALOGI("Reclaimed %ldkB at oom_score_adj %d", pages_freed * page_k, min_score_adj);
+            ALOGI("Reclaimed %ldkB at oom_adj %d",
+                pages_freed * page_k, min_score_adj);
         }
 
         if (report_skip_count > 0) {
@@ -3220,7 +2981,7 @@
     }
 
     /* check if kernel supports pidfd_open syscall */
-    pidfd = TEMP_FAILURE_RETRY(pidfd_open(getpid(), 0));
+    pidfd = TEMP_FAILURE_RETRY(sys_pidfd_open(getpid(), 0));
     if (pidfd < 0) {
         pidfd_supported = (errno != ENOSYS);
     } else {
@@ -3239,8 +3000,6 @@
 static void resume_polling(struct polling_params *poll_params, struct timespec curr_tm) {
     poll_params->poll_start_tm = curr_tm;
     poll_params->poll_handler = poll_params->paused_handler;
-    poll_params->polling_interval_ms = PSI_POLL_PERIOD_SHORT_MS;
-    poll_params->paused_handler = NULL;
 }
 
 static void call_handler(struct event_handler_info* handler_info,
@@ -3275,6 +3034,7 @@
         if (get_time_diff_ms(&poll_params->poll_start_tm, &curr_tm) > PSI_WINDOW_SIZE_MS) {
             /* Polled for the duration of PSI window, time to stop */
             poll_params->poll_handler = NULL;
+            poll_params->paused_handler = NULL;
         }
         break;
     }
@@ -3299,8 +3059,12 @@
             bool poll_now;
 
             clock_gettime(CLOCK_MONOTONIC_COARSE, &curr_tm);
-            if (poll_params.update == POLLING_RESUME) {
-                /* Just transitioned into POLLING_RESUME, poll immediately. */
+            if (poll_params.poll_handler == poll_params.paused_handler) {
+                /*
+                 * Just transitioned into POLLING_RESUME. Reset paused_handler
+                 * and poll immediately
+                 */
+                poll_params.paused_handler = NULL;
                 poll_now = true;
                 nevents = 0;
             } else {
@@ -3331,7 +3095,6 @@
                     stop_wait_for_proc_kill(false);
                     if (polling_paused(&poll_params)) {
                         clock_gettime(CLOCK_MONOTONIC_COARSE, &curr_tm);
-                        poll_params.update = POLLING_RESUME;
                         resume_polling(&poll_params, curr_tm);
                     }
                 }
@@ -3433,7 +3196,7 @@
         property_get_bool("ro.lmk.kill_heaviest_task", false);
     low_ram_device = property_get_bool("ro.config.low_ram", false);
     kill_timeout_ms =
-        (unsigned long)property_get_int32("ro.lmk.kill_timeout_ms", 100);
+        (unsigned long)property_get_int32("ro.lmk.kill_timeout_ms", 0);
     use_minfree_levels =
         property_get_bool("ro.lmk.use_minfree_levels", false);
     per_app_memcg =
@@ -3448,10 +3211,6 @@
         low_ram_device ? DEF_THRASHING_LOWRAM : DEF_THRASHING));
     thrashing_limit_decay_pct = clamp(0, 100, property_get_int32("ro.lmk.thrashing_limit_decay",
         low_ram_device ? DEF_THRASHING_DECAY_LOWRAM : DEF_THRASHING_DECAY));
-    thrashing_critical_pct = max(0, property_get_int32("ro.lmk.thrashing_limit_critical",
-        thrashing_limit_pct * 2));
-    swap_util_max = clamp(0, 100, property_get_int32("ro.lmk.swap_util_max", 100));
-    filecache_min_kb = property_get_int64("ro.lmk.filecache_min_kb", 0);
 }
 
 int main(int argc, char **argv) {
diff --git a/statslog.cpp b/statslog.cpp
index 6568f73..8fb441c 100644
--- a/statslog.cpp
+++ b/statslog.cpp
@@ -16,7 +16,6 @@
 
 #include <assert.h>
 #include <errno.h>
-#include <fcntl.h>
 #include <log/log.h>
 #include <log/log_id.h>
 #include <statslog.h>
@@ -24,27 +23,20 @@
 #include <string.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/endian.h>
-#include <sys/param.h>
 #include <sys/uio.h>
 #include <time.h>
-#include <unistd.h>
 
 #ifdef LMKD_LOG_STATS
 
+#define LINE_MAX 128
 #define STRINGIFY(x) STRINGIFY_INTERNAL(x)
 #define STRINGIFY_INTERNAL(x) #x
 
-/**
- * Used to make sure that the payload is always smaller than LMKD_REPLY_MAX_SIZE
- */
-#define BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)]))
-
-static bool enable_stats_log = property_get_bool("ro.lmk.log_stats", true);
+static bool enable_stats_log = property_get_bool("ro.lmk.log_stats", false);
 
 struct proc {
     int pid;
-    char taskname[MAX_TASKNAME_LEN];
+    char taskname[LINE_MAX];
     struct proc* pidhash_next;
 };
 
@@ -52,6 +44,20 @@
 static struct proc** pidhash = NULL;
 #define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
 
+/**
+ * Logs the change in LMKD state which is used as start/stop boundaries for logging
+ * LMK_KILL_OCCURRED event.
+ * Code: LMK_STATE_CHANGED = 54
+ */
+int
+stats_write_lmk_state_changed(int32_t state) {
+    if (enable_stats_log) {
+        return android::lmkd::stats::stats_write(android::lmkd::stats::LMK_STATE_CHANGED, state);
+    } else {
+        return -EINVAL;
+    }
+}
+
 static struct proc* pid_lookup(int pid) {
     struct proc* procp;
 
@@ -63,11 +69,48 @@
     return procp;
 }
 
+/**
+ * Logs the event when LMKD kills a process to reduce memory pressure.
+ * Code: LMK_KILL_OCCURRED = 51
+ */
+int
+stats_write_lmk_kill_occurred(int32_t uid, char const* process_name,
+                              int32_t oom_score, int32_t min_oom_score, int tasksize,
+                              struct memory_stat *mem_st) {
+    if (enable_stats_log) {
+        return android::lmkd::stats::stats_write(
+                android::lmkd::stats::LMK_KILL_OCCURRED,
+                uid,
+                process_name,
+                oom_score,
+                mem_st ? mem_st->pgfault : -1,
+                mem_st ? mem_st->pgmajfault : -1,
+                mem_st ? mem_st->rss_in_bytes : tasksize * BYTES_IN_KILOBYTE,
+                mem_st ? mem_st->cache_in_bytes : -1,
+                mem_st ? mem_st->swap_in_bytes : -1,
+                mem_st ? mem_st->process_start_time_ns : -1,
+                min_oom_score
+        );
+    } else {
+        return -EINVAL;
+    }
+}
+
+int stats_write_lmk_kill_occurred_pid(int32_t uid, int pid, int32_t oom_score,
+                                      int32_t min_oom_score, int tasksize,
+                                      struct memory_stat* mem_st) {
+    struct proc* proc = pid_lookup(pid);
+    if (!proc) return -EINVAL;
+
+    return stats_write_lmk_kill_occurred(uid, proc->taskname, oom_score, min_oom_score,
+                                         tasksize, mem_st);
+}
+
 static void memory_stat_parse_line(char* line, struct memory_stat* mem_st) {
-    char key[MAX_TASKNAME_LEN + 1];
+    char key[LINE_MAX + 1];
     int64_t value;
 
-    sscanf(line, "%" STRINGIFY(MAX_TASKNAME_LEN) "s  %" SCNd64 "", key, &value);
+    sscanf(line, "%" STRINGIFY(LINE_MAX) "s  %" SCNd64 "", key, &value);
 
     if (strcmp(key, "total_") < 0) {
         return;
@@ -125,24 +168,26 @@
     // field 10 is pgfault
     // field 12 is pgmajfault
     // field 22 is starttime
-    int64_t pgfault = 0, pgmajfault = 0, starttime = 0;
+    // field 24 is rss_in_pages
+    int64_t pgfault = 0, pgmajfault = 0, starttime = 0, rss_in_pages = 0;
     if (sscanf(buffer,
                "%*u %*s %*s %*d %*d %*d %*d %*d %*d %" SCNd64 " %*d "
                "%" SCNd64 " %*d %*u %*u %*d %*d %*d %*d %*d %*d "
-               "%" SCNd64 "",
-               &pgfault, &pgmajfault, &starttime) != 3) {
+               "%" SCNd64 " %*d %" SCNd64 "",
+               &pgfault, &pgmajfault, &starttime, &rss_in_pages) != 4) {
         return -1;
     }
     mem_st->pgfault = pgfault;
     mem_st->pgmajfault = pgmajfault;
+    mem_st->rss_in_bytes = (rss_in_pages * PAGE_SIZE);
     mem_st->process_start_time_ns = starttime * (NS_PER_SEC / sysconf(_SC_CLK_TCK));
 
     return 0;
 }
 
-struct memory_stat *stats_read_memory_stat(bool per_app_memcg, int pid, uid_t uid,
-                                           int64_t rss_bytes, int64_t swap_bytes) {
+struct memory_stat *stats_read_memory_stat(bool per_app_memcg, int pid, uid_t uid) {
     static struct memory_stat mem_st = {};
+
     if (!enable_stats_log) {
         return NULL;
     }
@@ -153,8 +198,6 @@
         }
     } else {
         if (memory_stat_from_procfs(&mem_st, pid) == 0) {
-            mem_st.rss_in_bytes = rss_bytes;
-            mem_st.swap_in_bytes = swap_bytes;
             return &mem_st;
         }
     }
@@ -197,7 +240,7 @@
 }
 
 void stats_store_taskname(int pid, const char* taskname) {
-    if (!enable_stats_log || !taskname) {
+    if (!enable_stats_log) {
         return;
     }
 
@@ -210,8 +253,8 @@
     }
     procp = static_cast<struct proc*>(malloc(sizeof(struct proc)));
     procp->pid = pid;
-    strncpy(procp->taskname, taskname, MAX_TASKNAME_LEN - 1);
-    procp->taskname[MAX_TASKNAME_LEN - 1] = '\0';
+    strncpy(procp->taskname, taskname, LINE_MAX - 1);
+    procp->taskname[LINE_MAX - 1] = '\0';
     proc_insert(procp);
 }
 
@@ -234,112 +277,4 @@
     memset(pidhash, 0, PIDHASH_SZ * sizeof(*pidhash));
 }
 
-const char* stats_get_task_name(int pid) {
-    struct proc* proc = pid_lookup(pid);
-    return proc ? proc->taskname : NULL;
-}
-
-/**
- * Writes int32 in a machine independent way
- * https://docs.oracle.com/javase/7/docs/api/java/io/DataOutput.html#writeInt(int)
- */
-static inline size_t pack_int32(LMK_KILL_OCCURRED_PACKET packet,
-                                size_t index,
-                                int32_t value) {
-    int32_t* int_buffer = (int32_t*)(packet + index);
-
-    *int_buffer = htonl(value);
-
-    return index + sizeof(int32_t);
-}
-
-/**
- * Writes int64 in a machine independent way
- * https://docs.oracle.com/javase/7/docs/api/java/io/DataOutput.html#writeLong(long)
- */
-static inline size_t pack_int64(LMK_KILL_OCCURRED_PACKET packet,
-                                size_t index,
-                                int64_t value) {
-    int64_t* int64_buffer = (int64_t*)(packet + index);
-
-    *int64_buffer = htonq(value);
-
-    return index + sizeof(int64_t);
-}
-
-/**
- * Writes ANSI string in a machine independent way
- * https://docs.oracle.com/javase/7/docs/api/java/io/DataOutput.html#writeShort(int)
- * 2 bytes str len following n chars
- * to be read on the Java side with
- * https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readUTF()
- * Truncates the value string & packs up to MAX_TASKNAME_LEN - 1 chars
- */
-static inline size_t pack_string(LMK_KILL_OCCURRED_PACKET packet,
-                                 size_t index,
-                                 const char* value) {
-    const size_t len_proc_name = MIN(strlen(value), MAX_TASKNAME_LEN - 1);
-    int16_t* short_buffer = (int16_t*)(packet + index);
-    *short_buffer = htons((int16_t)len_proc_name);
-
-    char* byte_buffer = (char*)(short_buffer + 1);
-    strncpy(byte_buffer, value, MAX_TASKNAME_LEN - 1);
-    byte_buffer[MAX_TASKNAME_LEN - 1] = '\0';
-
-    return index + sizeof(int16_t) + len_proc_name + 1;
-}
-
-size_t lmkd_pack_set_kill_occurred(LMK_KILL_OCCURRED_PACKET packet,
-                                   struct kill_stat *kill_stat,
-                                   struct memory_stat *mem_stat) {
-    BUILD_BUG_ON(sizeof(LMK_KILL_OCCURRED_PACKET) > LMKD_REPLY_MAX_SIZE);
-
-    if (!enable_stats_log) {
-        return 0;
-    }
-
-    int32_t index = 0;
-    index = pack_int32(packet, index, LMK_STAT_KILL_OCCURRED);
-
-    if (mem_stat) {
-        index = pack_int64(packet, index, mem_stat->pgfault);
-        index = pack_int64(packet, index, mem_stat->pgmajfault);
-        index = pack_int64(packet, index, mem_stat->rss_in_bytes);
-        index = pack_int64(packet, index, mem_stat->cache_in_bytes);
-        index = pack_int64(packet, index, mem_stat->swap_in_bytes);
-        index = pack_int64(packet, index, mem_stat->process_start_time_ns);
-    } else {
-        index = pack_int64(packet, index, -1);
-        index = pack_int64(packet, index, -1);
-        index = pack_int64(packet, index, -1);
-        index = pack_int64(packet, index, -1);
-        index = pack_int64(packet, index, -1);
-        index = pack_int64(packet, index, -1);
-    }
-
-    index = pack_int32(packet, index, kill_stat->uid);
-    index = pack_int32(packet, index, kill_stat->oom_score);
-    index = pack_int32(packet, index, kill_stat->min_oom_score);
-    index = pack_int32(packet, index, (int)kill_stat->free_mem_kb);
-    index = pack_int32(packet, index, (int)kill_stat->free_swap_kb);
-    index = pack_int32(packet, index, (int)kill_stat->kill_reason);
-    index = pack_int32(packet, index, kill_stat->thrashing);
-    index = pack_int32(packet, index, kill_stat->max_thrashing);
-
-    index = pack_string(packet, index, kill_stat->taskname);
-    return index;
-}
-
-size_t lmkd_pack_set_state_changed(LMKD_CTRL_PACKET packet,
-                                   enum lmk_state state) {
-    if (!enable_stats_log) {
-        return 0;
-    }
-
-    packet[0] = htonl(LMK_STAT_STATE_CHANGED);
-    packet[1] = htonl(state);
-
-    return 2 * sizeof(int);
-}
-
 #endif /* LMKD_LOG_STATS */
diff --git a/statslog.h b/statslog.h
index 89e4d2e..9cba6b2 100644
--- a/statslog.h
+++ b/statslog.h
@@ -17,10 +17,9 @@
 #ifndef _STATSLOG_H_
 #define _STATSLOG_H_
 
-#include <lmkd.h>
-
 #include <assert.h>
 #include <inttypes.h>
+#include <statslog_lmkd.h>
 #include <stdbool.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
@@ -29,21 +28,6 @@
 
 __BEGIN_DECLS
 
-#define MAX_TASKNAME_LEN 128
-
-/*
- * Max LMKD reply packet length in bytes
- * Notes about size calculation:
- * 4 bytes for packet type
- * 88 bytes for the LmkKillOccurred fields: memory_stat + kill_stat
- * 2 bytes for process name string size
- * MAX_TASKNAME_LEN bytes for the process name string
- *
- * Must be in sync with LmkdConnection.java
- */
-#define LMKD_REPLY_MAX_SIZE 222
-
-/* LMK_MEMORY_STATS packet payload */
 struct memory_stat {
     int64_t pgfault;
     int64_t pgmajfault;
@@ -53,71 +37,39 @@
     int64_t process_start_time_ns;
 };
 
-// If you update this, also update the corresponding stats enum mapping and LmkdStatsReporter.java
-enum kill_reasons {
-    NONE = -1, /* To denote no kill condition */
-    PRESSURE_AFTER_KILL = 0,
-    NOT_RESPONDING,
-    LOW_SWAP_AND_THRASHING,
-    LOW_MEM_AND_SWAP,
-    LOW_MEM_AND_THRASHING,
-    DIRECT_RECL_AND_THRASHING,
-    LOW_MEM_AND_SWAP_UTIL,
-    LOW_FILECACHE_AFTER_THRASHING,
-    KILL_REASON_COUNT
-};
-
-/* LMK_KILL_STAT packet payload */
-struct kill_stat {
-    int32_t uid;
-    const char *taskname;
-    enum kill_reasons kill_reason;
-    int32_t oom_score;
-    int32_t min_oom_score;
-    int64_t free_mem_kb;
-    int64_t free_swap_kb;
-    int32_t thrashing;
-    int32_t max_thrashing;
-};
-
-/* LMKD reply packet to hold data for the LmkKillOccurred statsd atom */
-typedef char LMK_KILL_OCCURRED_PACKET[LMKD_REPLY_MAX_SIZE];
-
-// If you update this, also update the corresponding stats enum mapping.
-enum lmk_state {
-    STATE_UNKNOWN = 0,
-    STATE_START,
-    STATE_STOP,
-};
-
 #ifdef LMKD_LOG_STATS
 
-#define MEMCG_PROCESS_MEMORY_STAT_PATH "/dev/memcg/apps/uid_%u/pid_%d/memory.stat"
+#define MEMCG_PROCESS_MEMORY_STAT_PATH "/dev/memcg/apps/uid_%u/pid_%u/memory.stat"
 #define PROC_STAT_FILE_PATH "/proc/%d/stat"
 #define PROC_STAT_BUFFER_SIZE 1024
 #define BYTES_IN_KILOBYTE 1024
 
 /**
- * Produces packet with the change in LMKD state which is used as start/stop boundaries for logging
+ * Logs the change in LMKD state which is used as start/stop boundaries for logging
  * LMK_KILL_OCCURRED event.
  * Code: LMK_STATE_CHANGED = 54
  */
-size_t lmkd_pack_set_state_changed(LMKD_CTRL_PACKET packet,
-                                   enum lmk_state state);
+int
+stats_write_lmk_state_changed(int32_t state);
 
 /**
- * Produces packet with the event when LMKD kills a process to reduce memory pressure.
+ * Logs the event when LMKD kills a process to reduce memory pressure.
  * Code: LMK_KILL_OCCURRED = 51
  */
-size_t lmkd_pack_set_kill_occurred(LMK_KILL_OCCURRED_PACKET packet,
-                                   struct kill_stat *kill_st,
-                                   struct memory_stat *mem_st);
+int
+stats_write_lmk_kill_occurred(int32_t uid, char const* process_name,
+                              int32_t oom_score, int32_t min_oom_score,
+                              int tasksize, struct memory_stat *mem_st);
 
 /**
- * Reads memory stats used to log the statsd atom. Returns non-null ptr on success.
+ * Logs the event when LMKD kills a process to reduce memory pressure.
+ * Code: LMK_KILL_OCCURRED = 51
  */
-struct memory_stat *stats_read_memory_stat(bool per_app_memcg, int pid, uid_t uid,
-                                           int64_t rss_bytes, int64_t swap_bytes);
+int stats_write_lmk_kill_occurred_pid(int32_t uid, int pid, int32_t oom_score,
+                                      int32_t min_oom_score, int tasksize,
+                                      struct memory_stat* mem_st);
+
+struct memory_stat *stats_read_memory_stat(bool per_app_memcg, int pid, uid_t uid);
 
 /**
  * Registers a process taskname by pid, while it is still alive.
@@ -134,27 +86,27 @@
  */
 void stats_remove_taskname(int pid);
 
-const char* stats_get_task_name(int pid);
-
 #else /* LMKD_LOG_STATS */
 
-static inline size_t
-lmkd_pack_set_state_changed(LMKD_CTRL_PACKET packet __unused, enum lmk_state state __unused) {
-    return -EINVAL;
-}
+static inline int
+stats_write_lmk_state_changed(int32_t state __unused) { return -EINVAL; }
 
-static inline size_t
-lmkd_pack_set_kill_occurred(LMK_KILL_OCCURRED_PACKET packet __unused,
-                            struct kill_stat *kill_st __unused,
-                            struct memory_stat *mem_st __unused) {
+static inline int
+stats_write_lmk_kill_occurred(int32_t uid __unused,
+                              char const* process_name __unused, int32_t oom_score __unused,
+                              int32_t min_oom_score __unused, int tasksize __unused,
+                              struct memory_stat *mem_st __unused) { return -EINVAL; }
+
+static inline int stats_write_lmk_kill_occurred_pid(int32_t uid __unused,
+                                                    int pid __unused, int32_t oom_score __unused,
+                                                    int32_t min_oom_score __unused,
+                                                    int tasksize __unused,
+                                                    struct memory_stat* mem_st __unused) {
     return -EINVAL;
 }
 
 static inline struct memory_stat *stats_read_memory_stat(bool per_app_memcg __unused,
-                                    int pid __unused, uid_t uid __unused,
-                                    int64_t rss_bytes __unused, int64_t swap_bytes __unused) {
-    return NULL;
-}
+                                    int pid __unused, uid_t uid __unused) { return NULL; }
 
 static inline void stats_store_taskname(int pid __unused, const char* taskname __unused) {}
 
@@ -162,8 +114,6 @@
 
 static inline void stats_remove_taskname(int pid __unused) {}
 
-static inline const char* stats_get_task_name(int pid __unused) { return NULL; }
-
 #endif /* LMKD_LOG_STATS */
 
 __END_DECLS
diff --git a/tests/Android.bp b/tests/Android.bp
index dfbe0c7..4e845fd 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -12,10 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
 cc_test {
     name: "lmkd_unit_test",
 
diff --git a/tests/lmkd_test.cpp b/tests/lmkd_test.cpp
index 07d91bb..5dbf6db 100644
--- a/tests/lmkd_test.cpp
+++ b/tests/lmkd_test.cpp
@@ -27,7 +27,6 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <cutils/properties.h>
 #include <gtest/gtest.h>
 #include <lmkd.h>
 #include <liblmkd_utils.h>
@@ -252,7 +251,6 @@
             params.pid = pid;
             params.uid = uid;
             params.oomadj = data->oomadj;
-            params.ptype = PROC_TYPE_APP;
             ASSERT_FALSE(lmkd_register_proc(sock, &params) < 0)
                 << "Failed to communicate with lmkd, err=" << strerror(errno);
             // signal the child it can proceed
@@ -275,10 +273,8 @@
                              << data->oomadj;
             data->allocated = 0;
             data->finished = false;
-            if (property_get_bool("ro.config.low_ram", false)) {
-                ASSERT_FALSE(create_memcg(uid, pid) != 0)
-                    << "Child [pid=" << pid << "] failed to create a cgroup";
-            }
+            ASSERT_FALSE(create_memcg(uid, pid) != 0)
+                << "Child [pid=" << pid << "] failed to create a cgroup";
             signal_state(ssync, STATE_CHILD_READY);
             wait_for_state(ssync, STATE_PARENT_READY);
             add_pressure(data);