/* * Copyright 2018 Google, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _LMKD_H_ #define _LMKD_H_ #include #include #include __BEGIN_DECLS /* * Supported LMKD commands */ enum lmk_cmd { LMK_TARGET = 0, /* Associate minfree with oom_adj_score */ LMK_PROCPRIO, /* Register a process and set its oom_adj_score */ LMK_PROCREMOVE, /* Unregister a process */ LMK_PROCPURGE, /* Purge all registered processes */ LMK_GETKILLCNT, /* Get number of kills */ }; /* * Max number of targets in LMK_TARGET command. */ #define MAX_TARGETS 6 /* * Max packet length in bytes. * Longest packet is LMK_TARGET followed by MAX_TARGETS * of minfree and oom_adj_score values */ #define CTRL_PACKET_MAX_SIZE (sizeof(int) * (MAX_TARGETS * 2 + 1)) /* LMKD packet - first int is lmk_cmd followed by payload */ typedef int LMKD_CTRL_PACKET[CTRL_PACKET_MAX_SIZE / sizeof(int)]; /* Get LMKD packet command */ static inline enum lmk_cmd lmkd_pack_get_cmd(LMKD_CTRL_PACKET pack) { return (enum lmk_cmd)ntohl(pack[0]); } /* LMK_TARGET packet payload */ struct lmk_target { int minfree; int oom_adj_score; }; /* * For LMK_TARGET packet get target_idx-th payload. * Warning: no checks performed, caller should ensure valid parameters. */ static inline void lmkd_pack_get_target(LMKD_CTRL_PACKET packet, int target_idx, struct lmk_target* target) { target->minfree = ntohl(packet[target_idx * 2 + 1]); target->oom_adj_score = ntohl(packet[target_idx * 2 + 2]); } /* * Prepare LMK_TARGET packet and return packet size in bytes. * Warning: no checks performed, caller should ensure valid parameters. */ static inline size_t lmkd_pack_set_target(LMKD_CTRL_PACKET packet, struct lmk_target* targets, size_t target_cnt) { int idx = 0; packet[idx++] = htonl(LMK_TARGET); while (target_cnt) { packet[idx++] = htonl(targets->minfree); packet[idx++] = htonl(targets->oom_adj_score); targets++; target_cnt--; } return idx * sizeof(int); } /* LMK_PROCPRIO packet payload */ struct lmk_procprio { pid_t pid; uid_t uid; int oomadj; }; /* * 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) { params->pid = (pid_t)ntohl(packet[1]); params->uid = (uid_t)ntohl(packet[2]); params->oomadj = ntohl(packet[3]); } /* * Prepare LMK_PROCPRIO packet and return packet size in bytes. * Warning: no checks performed, caller should ensure valid parameters. */ static inline size_t lmkd_pack_set_procprio(LMKD_CTRL_PACKET packet, struct lmk_procprio* params) { packet[0] = htonl(LMK_PROCPRIO); packet[1] = htonl(params->pid); packet[2] = htonl(params->uid); packet[3] = htonl(params->oomadj); return 4 * sizeof(int); } /* LMK_PROCREMOVE packet payload */ struct lmk_procremove { pid_t pid; }; /* * For LMK_PROCREMOVE packet get its payload. * Warning: no checks performed, caller should ensure valid parameters. */ static inline void lmkd_pack_get_procremove(LMKD_CTRL_PACKET packet, struct lmk_procremove* params) { params->pid = (pid_t)ntohl(packet[1]); } /* * Prepare LMK_PROCREMOVE packet and return packet size in bytes. * Warning: no checks performed, caller should ensure valid parameters. */ static inline size_t lmkd_pack_set_procremove(LMKD_CTRL_PACKET packet, struct lmk_procprio* params) { packet[0] = htonl(LMK_PROCREMOVE); packet[1] = htonl(params->pid); return 2 * sizeof(int); } /* * Prepare LMK_PROCPURGE packet and return packet size in bytes. * Warning: no checks performed, caller should ensure valid parameters. */ static inline size_t lmkd_pack_set_procpurge(LMKD_CTRL_PACKET packet) { packet[0] = htonl(LMK_PROCPURGE); return sizeof(int); } /* LMK_GETKILLCNT packet payload */ struct lmk_getkillcnt { int min_oomadj; int max_oomadj; }; /* * For LMK_GETKILLCNT packet get its payload. * Warning: no checks performed, caller should ensure valid parameters. */ static inline void lmkd_pack_get_getkillcnt(LMKD_CTRL_PACKET packet, struct lmk_getkillcnt* params) { params->min_oomadj = ntohl(packet[1]); params->max_oomadj = ntohl(packet[2]); } /* * Prepare LMK_GETKILLCNT packet and return packet size in bytes. * Warning: no checks performed, caller should ensure valid parameters. */ static inline size_t lmkd_pack_set_getkillcnt(LMKD_CTRL_PACKET packet, struct lmk_getkillcnt* params) { packet[0] = htonl(LMK_GETKILLCNT); packet[1] = htonl(params->min_oomadj); packet[2] = htonl(params->max_oomadj); return 3 * sizeof(int); } /* * Prepare LMK_GETKILLCNT reply packet and return packet size in bytes. * Warning: no checks performed, caller should ensure valid parameters. */ static inline size_t lmkd_pack_set_getkillcnt_repl(LMKD_CTRL_PACKET packet, int kill_cnt) { packet[0] = htonl(LMK_GETKILLCNT); packet[1] = htonl(kill_cnt); return 2 * sizeof(int); } __END_DECLS #endif /* _LMKD_H_ */