Move register proc logic to prepare for new PROCS_PRIO cmd

Moving logic for registering proc, after oom adjustment, to its
own function. This work is for the introduction of the new
PROCS_PRIO cmd. This logic will be shared between the current PROCPRIO
and PROCS_PRIO cmd.

Test: m
Bug: 325525024
Change-Id: I0683f63faa3dfa2e4534cdfb8935b4d2f83a6af9
Signed-off-by: Carlos Galo <carlosgalo@google.com>
This commit is contained in:
Carlos Galo 2024-04-30 22:16:07 +00:00
parent e1eb315723
commit 7da353fb00
1 changed files with 96 additions and 90 deletions

186
lmkd.cpp
View File

@ -1124,14 +1124,105 @@ static char *proc_get_name(int pid, char *buf, size_t buf_size) {
return buf; return buf;
} }
static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred *cred) { static void register_oom_adj_proc(const struct lmk_procprio& proc, struct ucred* cred) {
struct proc *procp;
char path[PROCFS_PATH_MAX];
char val[20]; char val[20];
int soft_limit_mult; int soft_limit_mult;
struct lmk_procprio params;
bool is_system_server; bool is_system_server;
struct passwd *pwdrec; struct passwd *pwdrec;
struct proc* procp;
int oom_adj_score = proc.oomadj;
/* lmkd should not change soft limits for services */
if (proc.ptype == PROC_TYPE_APP && per_app_memcg) {
if (proc.oomadj >= 900) {
soft_limit_mult = 0;
} else if (proc.oomadj >= 800) {
soft_limit_mult = 0;
} else if (proc.oomadj >= 700) {
soft_limit_mult = 0;
} else if (proc.oomadj >= 600) {
// Launcher should be perceptible, don't kill it.
oom_adj_score = 200;
soft_limit_mult = 1;
} else if (proc.oomadj >= 500) {
soft_limit_mult = 0;
} else if (proc.oomadj >= 400) {
soft_limit_mult = 0;
} else if (proc.oomadj >= 300) {
soft_limit_mult = 1;
} else if (proc.oomadj >= 200) {
soft_limit_mult = 8;
} else if (proc.oomadj >= 100) {
soft_limit_mult = 10;
} else if (proc.oomadj >= 0) {
soft_limit_mult = 20;
} else {
// Persistent processes will have a large
// soft limit 512MB.
soft_limit_mult = 64;
}
std::string soft_limit_path;
if (!CgroupGetAttributePathForTask("MemSoftLimit", proc.pid, &soft_limit_path)) {
ALOGE("Querying MemSoftLimit path failed");
return;
}
snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
/*
* system_server process has no memcg under /dev/memcg/apps but should be
* registered with lmkd. This is the best way so far to identify it.
*/
is_system_server = (oom_adj_score == SYSTEM_ADJ && (pwdrec = getpwnam("system")) != NULL &&
proc.uid == pwdrec->pw_uid);
writefilestring(soft_limit_path.c_str(), val, !is_system_server);
}
procp = pid_lookup(proc.pid);
if (!procp) {
int pidfd = -1;
if (pidfd_supported) {
pidfd = TEMP_FAILURE_RETRY(pidfd_open(proc.pid, 0));
if (pidfd < 0) {
ALOGE("pidfd_open for pid %d failed; errno=%d", proc.pid, errno);
return;
}
}
procp = static_cast<struct proc*>(calloc(1, sizeof(struct proc)));
if (!procp) {
// Oh, the irony. May need to rebuild our state.
return;
}
procp->pid = proc.pid;
procp->pidfd = pidfd;
procp->uid = proc.uid;
procp->reg_pid = cred->pid;
procp->oomadj = oom_adj_score;
procp->valid = true;
proc_insert(procp);
} 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);
return;
}
proc_unslot(procp);
procp->oomadj = oom_adj_score;
proc_slot(procp);
}
}
static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred* cred) {
char path[PROCFS_PATH_MAX];
char val[20];
struct lmk_procprio params;
int64_t tgid; int64_t tgid;
char buf[pagesize]; char buf[pagesize];
@ -1174,92 +1265,7 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred
return; return;
} }
/* lmkd should not change soft limits for services */ register_oom_adj_proc(params, cred);
if (params.ptype == PROC_TYPE_APP && per_app_memcg) {
if (params.oomadj >= 900) {
soft_limit_mult = 0;
} else if (params.oomadj >= 800) {
soft_limit_mult = 0;
} else if (params.oomadj >= 700) {
soft_limit_mult = 0;
} else if (params.oomadj >= 600) {
// Launcher should be perceptible, don't kill it.
params.oomadj = 200;
soft_limit_mult = 1;
} else if (params.oomadj >= 500) {
soft_limit_mult = 0;
} else if (params.oomadj >= 400) {
soft_limit_mult = 0;
} else if (params.oomadj >= 300) {
soft_limit_mult = 1;
} else if (params.oomadj >= 200) {
soft_limit_mult = 8;
} else if (params.oomadj >= 100) {
soft_limit_mult = 10;
} else if (params.oomadj >= 0) {
soft_limit_mult = 20;
} else {
// Persistent processes will have a large
// soft limit 512MB.
soft_limit_mult = 64;
}
std::string path;
if (!CgroupGetAttributePathForTask("MemSoftLimit", params.pid, &path)) {
ALOGE("Querying MemSoftLimit path failed");
return;
}
snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
/*
* system_server process has no memcg under /dev/memcg/apps but should be
* registered with lmkd. This is the best way so far to identify it.
*/
is_system_server = (params.oomadj == SYSTEM_ADJ &&
(pwdrec = getpwnam("system")) != NULL &&
params.uid == pwdrec->pw_uid);
writefilestring(path.c_str(), val, !is_system_server);
}
procp = pid_lookup(params.pid);
if (!procp) {
int pidfd = -1;
if (pidfd_supported) {
pidfd = TEMP_FAILURE_RETRY(pidfd_open(params.pid, 0));
if (pidfd < 0) {
ALOGE("pidfd_open for pid %d failed; errno=%d", params.pid, errno);
return;
}
}
procp = static_cast<struct proc*>(calloc(1, sizeof(struct proc)));
if (!procp) {
// Oh, the irony. May need to rebuild our state.
return;
}
procp->pid = params.pid;
procp->pidfd = pidfd;
procp->uid = params.uid;
procp->reg_pid = cred->pid;
procp->oomadj = params.oomadj;
procp->valid = true;
proc_insert(procp);
} 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);
return;
}
proc_unslot(procp);
procp->oomadj = params.oomadj;
proc_slot(procp);
}
} }
static void cmd_procremove(LMKD_CTRL_PACKET packet, struct ucred *cred) { static void cmd_procremove(LMKD_CTRL_PACKET packet, struct ucred *cred) {