lmkd: Support process types when registering a process

Add an optional process type field into lmkd registration protocol so that
applications can be distinguished from services.

Bug: 129011369
Test: boot and verify native service registration
Change-Id: Ie610b5d07cbe247a55ab31bc079ee5c5923bea11
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
Suren Baghdasaryan 2019-10-22 17:12:01 -07:00
parent 7d3c5c6ea2
commit a93503e3d7
2 changed files with 27 additions and 7 deletions

View File

@ -87,21 +87,33 @@ static inline size_t lmkd_pack_set_target(LMKD_CTRL_PACKET packet, struct lmk_ta
return idx * sizeof(int); 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 */ /* LMK_PROCPRIO packet payload */
struct lmk_procprio { struct lmk_procprio {
pid_t pid; pid_t pid;
uid_t uid; uid_t uid;
int oomadj; int oomadj;
enum proc_type ptype;
}; };
/* /*
* For LMK_PROCPRIO packet get its payload. * For LMK_PROCPRIO packet get its payload.
* Warning: no checks performed, caller should ensure valid parameters. * 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->pid = (pid_t)ntohl(packet[1]);
params->uid = (uid_t)ntohl(packet[2]); params->uid = (uid_t)ntohl(packet[2]);
params->oomadj = ntohl(packet[3]); 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[1] = htonl(params->pid);
packet[2] = htonl(params->uid); packet[2] = htonl(params->uid);
packet[3] = htonl(params->oomadj); packet[3] = htonl(params->oomadj);
return 4 * sizeof(int); packet[4] = htonl((int)params->ptype);
return 5 * sizeof(int);
} }
/* LMK_PROCREMOVE packet payload */ /* LMK_PROCREMOVE packet payload */

17
lmkd.c
View File

@ -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; struct proc *procp;
char path[LINE_MAX]; char path[LINE_MAX];
char val[20]; char val[20];
@ -886,7 +886,7 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet, struct ucred *cred) {
struct passwd *pwdrec; struct passwd *pwdrec;
int tgid; int tgid;
lmkd_pack_get_procprio(packet, &params); lmkd_pack_get_procprio(packet, field_count, &params);
if (params.oomadj < OOM_SCORE_ADJ_MIN || if (params.oomadj < OOM_SCORE_ADJ_MIN ||
params.oomadj > OOM_SCORE_ADJ_MAX) { params.oomadj > OOM_SCORE_ADJ_MAX) {
@ -894,6 +894,11 @@ static void cmd_procprio(LMKD_CTRL_PACKET packet, struct ucred *cred) {
return; 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 */ /* Check if registered process is a thread group leader */
tgid = proc_get_tgid(params.pid); tgid = proc_get_tgid(params.pid);
if (tgid >= 0 && 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; 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) { if (params.oomadj >= 900) {
soft_limit_mult = 0; soft_limit_mult = 0;
} else if (params.oomadj >= 800) { } else if (params.oomadj >= 800) {
@ -1298,9 +1304,10 @@ static void ctrl_command_handler(int dsock_idx) {
cmd_target(targets, packet); cmd_target(targets, packet);
break; break;
case LMK_PROCPRIO: case LMK_PROCPRIO:
if (nargs != 3) /* process type field is optional for backward compatibility */
if (nargs < 3 || nargs > 4)
goto wronglen; goto wronglen;
cmd_procprio(packet, &cred); cmd_procprio(packet, nargs, &cred);
break; break;
case LMK_PROCREMOVE: case LMK_PROCREMOVE:
if (nargs != 1) if (nargs != 1)