From 7da353fb005ec9d66ffff917160ac047e91a36b0 Mon Sep 17 00:00:00 2001 From: Carlos Galo Date: Tue, 30 Apr 2024 22:16:07 +0000 Subject: [PATCH] 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 --- lmkd.cpp | 186 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 96 insertions(+), 90 deletions(-) diff --git a/lmkd.cpp b/lmkd.cpp index a3d553a..0408872 100644 --- a/lmkd.cpp +++ b/lmkd.cpp @@ -1124,14 +1124,105 @@ static char *proc_get_name(int pid, char *buf, size_t buf_size) { return buf; } -static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred *cred) { - struct proc *procp; - char path[PROCFS_PATH_MAX]; +static void register_oom_adj_proc(const struct lmk_procprio& proc, struct ucred* cred) { char val[20]; int soft_limit_mult; - struct lmk_procprio params; bool is_system_server; 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(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; char buf[pagesize]; @@ -1174,92 +1265,7 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred return; } - /* lmkd should not change soft limits for services */ - 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(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); - } + register_oom_adj_proc(params, cred); } static void cmd_procremove(LMKD_CTRL_PACKET packet, struct ucred *cred) {