lmkd: Introduce liblmkd_utils for communicating with lmkd process
A number of tools and tests require communication with lmkd.
In order to avoid code duplication liblmkd_utils implements
functions commonly used when interacting with lmkd process.
Isolate communication protocol details into lmkd.h
Bug: 63631020
Change-Id: Id840983d55b7db60013d52dee0c3187943811822
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
diff --git a/lmkd.c b/lmkd.c
index 988f9f2..1eec2f2 100644
--- a/lmkd.c
+++ b/lmkd.c
@@ -16,7 +16,6 @@
#define LOG_TAG "lowmemorykiller"
-#include <arpa/inet.h>
#include <errno.h>
#include <inttypes.h>
#include <sched.h>
@@ -34,6 +33,7 @@
#include <cutils/properties.h>
#include <cutils/sockets.h>
+#include <lmkd.h>
#include <log/log.h>
/*
@@ -71,19 +71,6 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define EIGHT_MEGA (1 << 23)
-enum lmk_cmd {
- LMK_TARGET,
- LMK_PROCPRIO,
- LMK_PROCREMOVE,
-};
-
-#define MAX_TARGETS 6
-/*
- * longest is LMK_TARGET followed by MAX_TARGETS each minfree and minkillprio
- * values
- */
-#define CTRL_PACKET_MAX (sizeof(int) * (MAX_TARGETS * 2 + 1))
-
/* default to old in-kernel interface if no memory pressure events */
static int use_inkernel_interface = 1;
static bool has_inkernel_module;
@@ -300,45 +287,49 @@
close(fd);
}
-static void cmd_procprio(int pid, int uid, int oomadj) {
+static void cmd_procprio(LMKD_CTRL_PACKET packet) {
struct proc *procp;
char path[80];
char val[20];
int soft_limit_mult;
+ struct lmk_procprio params;
- if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) {
- ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj);
+ lmkd_pack_get_procprio(packet, ¶ms);
+
+ if (params.oomadj < OOM_SCORE_ADJ_MIN ||
+ params.oomadj > OOM_SCORE_ADJ_MAX) {
+ ALOGE("Invalid PROCPRIO oomadj argument %d", params.oomadj);
return;
}
- snprintf(path, sizeof(path), "/proc/%d/oom_score_adj", pid);
- snprintf(val, sizeof(val), "%d", oomadj);
+ snprintf(path, sizeof(path), "/proc/%d/oom_score_adj", params.pid);
+ snprintf(val, sizeof(val), "%d", params.oomadj);
writefilestring(path, val);
if (use_inkernel_interface)
return;
- if (oomadj >= 900) {
+ if (params.oomadj >= 900) {
soft_limit_mult = 0;
- } else if (oomadj >= 800) {
+ } else if (params.oomadj >= 800) {
soft_limit_mult = 0;
- } else if (oomadj >= 700) {
+ } else if (params.oomadj >= 700) {
soft_limit_mult = 0;
- } else if (oomadj >= 600) {
+ } else if (params.oomadj >= 600) {
// Launcher should be perceptible, don't kill it.
- oomadj = 200;
+ params.oomadj = 200;
soft_limit_mult = 1;
- } else if (oomadj >= 500) {
+ } else if (params.oomadj >= 500) {
soft_limit_mult = 0;
- } else if (oomadj >= 400) {
+ } else if (params.oomadj >= 400) {
soft_limit_mult = 0;
- } else if (oomadj >= 300) {
+ } else if (params.oomadj >= 300) {
soft_limit_mult = 1;
- } else if (oomadj >= 200) {
+ } else if (params.oomadj >= 200) {
soft_limit_mult = 2;
- } else if (oomadj >= 100) {
+ } else if (params.oomadj >= 100) {
soft_limit_mult = 10;
- } else if (oomadj >= 0) {
+ } else if (params.oomadj >= 0) {
soft_limit_mult = 20;
} else {
// Persistent processes will have a large
@@ -346,11 +337,13 @@
soft_limit_mult = 64;
}
- snprintf(path, sizeof(path), "/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes", uid, pid);
+ snprintf(path, sizeof(path),
+ "/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes",
+ params.uid, params.pid);
snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
writefilestring(path, val);
- procp = pid_lookup(pid);
+ procp = pid_lookup(params.pid);
if (!procp) {
procp = malloc(sizeof(struct proc));
if (!procp) {
@@ -358,33 +351,38 @@
return;
}
- procp->pid = pid;
- procp->uid = uid;
- procp->oomadj = oomadj;
+ procp->pid = params.pid;
+ procp->uid = params.uid;
+ procp->oomadj = params.oomadj;
proc_insert(procp);
} else {
proc_unslot(procp);
- procp->oomadj = oomadj;
+ procp->oomadj = params.oomadj;
proc_slot(procp);
}
}
-static void cmd_procremove(int pid) {
+static void cmd_procremove(LMKD_CTRL_PACKET packet) {
+ struct lmk_procremove params;
+
if (use_inkernel_interface)
return;
- pid_remove(pid);
+ lmkd_pack_get_procremove(packet, ¶ms);
+ pid_remove(params.pid);
}
-static void cmd_target(int ntargets, int *params) {
+static void cmd_target(int ntargets, LMKD_CTRL_PACKET packet) {
int i;
+ struct lmk_target target;
if (ntargets > (int)ARRAY_SIZE(lowmem_adj))
return;
for (i = 0; i < ntargets; i++) {
- lowmem_minfree[i] = ntohl(*params++);
- lowmem_adj[i] = ntohl(*params++);
+ lmkd_pack_get_target(packet, i, &target);
+ lowmem_minfree[i] = target.minfree;
+ lowmem_adj[i] = target.oom_adj_score;
}
lowmem_targets_size = ntargets;
@@ -445,38 +443,42 @@
}
static void ctrl_command_handler(int dsock_idx) {
- int ibuf[CTRL_PACKET_MAX / sizeof(int)];
+ LMKD_CTRL_PACKET packet;
int len;
- int cmd = -1;
+ enum lmk_cmd cmd;
int nargs;
int targets;
- len = ctrl_data_read(dsock_idx, (char *)ibuf, CTRL_PACKET_MAX);
+ len = ctrl_data_read(dsock_idx, (char *)packet, CTRL_PACKET_MAX_SIZE);
if (len <= 0)
return;
+ if (len < (int)sizeof(int)) {
+ ALOGE("Wrong control socket read length len=%d", len);
+ return;
+ }
+
+ cmd = lmkd_pack_get_cmd(packet);
nargs = len / sizeof(int) - 1;
if (nargs < 0)
goto wronglen;
- cmd = ntohl(ibuf[0]);
-
switch(cmd) {
case LMK_TARGET:
targets = nargs / 2;
if (nargs & 0x1 || targets > (int)ARRAY_SIZE(lowmem_adj))
goto wronglen;
- cmd_target(targets, &ibuf[1]);
+ cmd_target(targets, packet);
break;
case LMK_PROCPRIO:
if (nargs != 3)
goto wronglen;
- cmd_procprio(ntohl(ibuf[1]), ntohl(ibuf[2]), ntohl(ibuf[3]));
+ cmd_procprio(packet);
break;
case LMK_PROCREMOVE:
if (nargs != 1)
goto wronglen;
- cmd_procremove(ntohl(ibuf[1]));
+ cmd_procremove(packet);
break;
default:
ALOGE("Received unknown command code %d", cmd);