1 /* 2 * Copyright 2018 Google, Inc 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _LMKD_H_ 18 #define _LMKD_H_ 19 20 #include <arpa/inet.h> 21 #include <sys/cdefs.h> 22 #include <sys/types.h> 23 24 __BEGIN_DECLS 25 26 /* 27 * Supported LMKD commands 28 */ 29 enum lmk_cmd { 30 LMK_TARGET = 0, /* Associate minfree with oom_adj_score */ 31 LMK_PROCPRIO, /* Register a process and set its oom_adj_score */ 32 LMK_PROCREMOVE, /* Unregister a process */ 33 }; 34 35 /* 36 * Max number of targets in LMK_TARGET command. 37 */ 38 #define MAX_TARGETS 6 39 40 /* 41 * Max packet length in bytes. 42 * Longest packet is LMK_TARGET followed by MAX_TARGETS 43 * of minfree and oom_adj_score values 44 */ 45 #define CTRL_PACKET_MAX_SIZE (sizeof(int) * (MAX_TARGETS * 2 + 1)) 46 47 /* LMKD packet - first int is lmk_cmd followed by payload */ 48 typedef int LMKD_CTRL_PACKET[CTRL_PACKET_MAX_SIZE / sizeof(int)]; 49 50 /* Get LMKD packet command */ 51 inline enum lmk_cmd lmkd_pack_get_cmd(LMKD_CTRL_PACKET pack) { 52 return (enum lmk_cmd)ntohl(pack[0]); 53 } 54 55 /* LMK_TARGET packet payload */ 56 struct lmk_target { 57 int minfree; 58 int oom_adj_score; 59 }; 60 61 /* 62 * For LMK_TARGET packet get target_idx-th payload. 63 * Warning: no checks performed, caller should ensure valid parameters. 64 */ 65 inline void lmkd_pack_get_target(LMKD_CTRL_PACKET packet, 66 int target_idx, struct lmk_target *target) { 67 target->minfree = ntohl(packet[target_idx * 2 + 1]); 68 target->oom_adj_score = ntohl(packet[target_idx * 2 + 2]); 69 } 70 71 /* 72 * Prepare LMK_TARGET packet and return packet size in bytes. 73 * Warning: no checks performed, caller should ensure valid parameters. 74 */ 75 inline size_t lmkd_pack_set_target(LMKD_CTRL_PACKET packet, 76 struct lmk_target *targets, 77 size_t target_cnt) { 78 int idx = 0; 79 packet[idx++] = htonl(LMK_TARGET); 80 while (target_cnt) { 81 packet[idx++] = htonl(targets->minfree); 82 packet[idx++] = htonl(targets->oom_adj_score); 83 targets++; 84 target_cnt--; 85 } 86 return idx * sizeof(int); 87 } 88 89 /* LMK_PROCPRIO packet payload */ 90 struct lmk_procprio { 91 pid_t pid; 92 uid_t uid; 93 int oomadj; 94 }; 95 96 /* 97 * For LMK_PROCPRIO packet get its payload. 98 * Warning: no checks performed, caller should ensure valid parameters. 99 */ 100 inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet, 101 struct lmk_procprio *params) { 102 params->pid = (pid_t)ntohl(packet[1]); 103 params->uid = (uid_t)ntohl(packet[2]); 104 params->oomadj = ntohl(packet[3]); 105 } 106 107 /* 108 * Prepare LMK_PROCPRIO packet and return packet size in bytes. 109 * Warning: no checks performed, caller should ensure valid parameters. 110 */ 111 inline size_t lmkd_pack_set_procprio(LMKD_CTRL_PACKET packet, 112 struct lmk_procprio *params) { 113 packet[0] = htonl(LMK_PROCPRIO); 114 packet[1] = htonl(params->pid); 115 packet[2] = htonl(params->uid); 116 packet[3] = htonl(params->oomadj); 117 return 4 * sizeof(int); 118 } 119 120 /* LMK_PROCREMOVE packet payload */ 121 struct lmk_procremove { 122 pid_t pid; 123 }; 124 125 /* 126 * For LMK_PROCREMOVE packet get its payload. 127 * Warning: no checks performed, caller should ensure valid parameters. 128 */ 129 inline void lmkd_pack_get_procremove(LMKD_CTRL_PACKET packet, 130 struct lmk_procremove *params) { 131 params->pid = (pid_t)ntohl(packet[1]); 132 } 133 134 /* 135 * Prepare LMK_PROCREMOVE packet and return packet size in bytes. 136 * Warning: no checks performed, caller should ensure valid parameters. 137 */ 138 inline size_t lmkd_pack_set_procremove(LMKD_CTRL_PACKET packet, 139 struct lmk_procprio *params) { 140 packet[0] = htonl(LMK_PROCREMOVE); 141 packet[1] = htonl(params->pid); 142 return 2 * sizeof(int); 143 } 144 145 __END_DECLS 146 147 #endif /* _LMKD_H_ */ 148