diff --git a/lmkd/include/lmkd.h b/lmkd/include/lmkd.h index 08805fbfd..bd9b80e3e 100644 --- a/lmkd/include/lmkd.h +++ b/lmkd/include/lmkd.h @@ -87,21 +87,33 @@ static inline size_t lmkd_pack_set_target(LMKD_CTRL_PACKET packet, struct lmk_ta return idx * sizeof(int); } +/* Process types for lmk_procprio.ptype */ +enum proc_type { + PROC_TYPE_FIRST, + PROC_TYPE_APP = PROC_TYPE_FIRST, + PROC_TYPE_SERVICE, + PROC_TYPE_COUNT, +}; + /* LMK_PROCPRIO packet payload */ struct lmk_procprio { pid_t pid; uid_t uid; int oomadj; + enum proc_type ptype; }; /* * For LMK_PROCPRIO packet get its payload. * Warning: no checks performed, caller should ensure valid parameters. */ -static inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet, struct lmk_procprio* params) { +static inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet, int field_count, + struct lmk_procprio* params) { params->pid = (pid_t)ntohl(packet[1]); params->uid = (uid_t)ntohl(packet[2]); params->oomadj = ntohl(packet[3]); + /* if field is missing assume PROC_TYPE_APP for backward compatibility */ + params->ptype = field_count > 3 ? (enum proc_type)ntohl(packet[4]) : PROC_TYPE_APP; } /* @@ -113,7 +125,8 @@ static inline size_t lmkd_pack_set_procprio(LMKD_CTRL_PACKET packet, struct lmk_ packet[1] = htonl(params->pid); packet[2] = htonl(params->uid); packet[3] = htonl(params->oomadj); - return 4 * sizeof(int); + packet[4] = htonl((int)params->ptype); + return 5 * sizeof(int); } /* LMK_PROCREMOVE packet payload */ diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 1edd77223..435249806 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -876,7 +876,7 @@ static void remove_claims(pid_t pid) { } } -static void cmd_procprio(LMKD_CTRL_PACKET packet, struct ucred *cred) { +static void cmd_procprio(LMKD_CTRL_PACKET packet, int field_count, struct ucred *cred) { struct proc *procp; char path[LINE_MAX]; char val[20]; @@ -886,7 +886,7 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet, struct ucred *cred) { struct passwd *pwdrec; int tgid; - lmkd_pack_get_procprio(packet, ¶ms); + lmkd_pack_get_procprio(packet, field_count, ¶ms); if (params.oomadj < OOM_SCORE_ADJ_MIN || params.oomadj > OOM_SCORE_ADJ_MAX) { @@ -894,6 +894,11 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet, struct ucred *cred) { return; } + if (params.ptype < PROC_TYPE_FIRST || params.ptype >= PROC_TYPE_COUNT) { + ALOGE("Invalid PROCPRIO process type argument %d", params.ptype); + return; + } + /* Check if registered process is a thread group leader */ tgid = proc_get_tgid(params.pid); if (tgid >= 0 && tgid != params.pid) { @@ -920,7 +925,8 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet, struct ucred *cred) { return; } - if (per_app_memcg) { + /* 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) { @@ -1298,9 +1304,10 @@ static void ctrl_command_handler(int dsock_idx) { cmd_target(targets, packet); break; case LMK_PROCPRIO: - if (nargs != 3) + /* process type field is optional for backward compatibility */ + if (nargs < 3 || nargs > 4) goto wronglen; - cmd_procprio(packet, &cred); + cmd_procprio(packet, nargs, &cred); break; case LMK_PROCREMOVE: if (nargs != 1)