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 LMK_PROCPURGE, /* Purge all registered processes */
34 LMK_GETKILLCNT, /* Get number of kills */
35 };
36
37 /*
38 * Max number of targets in LMK_TARGET command.
39 */
40 #define MAX_TARGETS 6
41
42 /*
43 * Max packet length in bytes.
44 * Longest packet is LMK_TARGET followed by MAX_TARGETS
45 * of minfree and oom_adj_score values
46 */
47 #define CTRL_PACKET_MAX_SIZE (sizeof(int) * (MAX_TARGETS * 2 + 1))
48
49 /* LMKD packet - first int is lmk_cmd followed by payload */
50 typedef int LMKD_CTRL_PACKET[CTRL_PACKET_MAX_SIZE / sizeof(int)];
51
52 /* Get LMKD packet command */
lmkd_pack_get_cmd(LMKD_CTRL_PACKET pack)53 static inline enum lmk_cmd lmkd_pack_get_cmd(LMKD_CTRL_PACKET pack) {
54 return (enum lmk_cmd)ntohl(pack[0]);
55 }
56
57 /* LMK_TARGET packet payload */
58 struct lmk_target {
59 int minfree;
60 int oom_adj_score;
61 };
62
63 /*
64 * For LMK_TARGET packet get target_idx-th payload.
65 * Warning: no checks performed, caller should ensure valid parameters.
66 */
lmkd_pack_get_target(LMKD_CTRL_PACKET packet,int target_idx,struct lmk_target * target)67 static inline void lmkd_pack_get_target(LMKD_CTRL_PACKET packet, int target_idx,
68 struct lmk_target* target) {
69 target->minfree = ntohl(packet[target_idx * 2 + 1]);
70 target->oom_adj_score = ntohl(packet[target_idx * 2 + 2]);
71 }
72
73 /*
74 * Prepare LMK_TARGET packet and return packet size in bytes.
75 * Warning: no checks performed, caller should ensure valid parameters.
76 */
lmkd_pack_set_target(LMKD_CTRL_PACKET packet,struct lmk_target * targets,size_t target_cnt)77 static inline size_t lmkd_pack_set_target(LMKD_CTRL_PACKET packet, struct lmk_target* targets,
78 size_t target_cnt) {
79 int idx = 0;
80 packet[idx++] = htonl(LMK_TARGET);
81 while (target_cnt) {
82 packet[idx++] = htonl(targets->minfree);
83 packet[idx++] = htonl(targets->oom_adj_score);
84 targets++;
85 target_cnt--;
86 }
87 return idx * sizeof(int);
88 }
89
90 /* LMK_PROCPRIO packet payload */
91 struct lmk_procprio {
92 pid_t pid;
93 uid_t uid;
94 int oomadj;
95 };
96
97 /*
98 * For LMK_PROCPRIO packet get its payload.
99 * Warning: no checks performed, caller should ensure valid parameters.
100 */
lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet,struct lmk_procprio * params)101 static inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet, 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 */
lmkd_pack_set_procprio(LMKD_CTRL_PACKET packet,struct lmk_procprio * params)111 static inline size_t lmkd_pack_set_procprio(LMKD_CTRL_PACKET packet, struct lmk_procprio* params) {
112 packet[0] = htonl(LMK_PROCPRIO);
113 packet[1] = htonl(params->pid);
114 packet[2] = htonl(params->uid);
115 packet[3] = htonl(params->oomadj);
116 return 4 * sizeof(int);
117 }
118
119 /* LMK_PROCREMOVE packet payload */
120 struct lmk_procremove {
121 pid_t pid;
122 };
123
124 /*
125 * For LMK_PROCREMOVE packet get its payload.
126 * Warning: no checks performed, caller should ensure valid parameters.
127 */
lmkd_pack_get_procremove(LMKD_CTRL_PACKET packet,struct lmk_procremove * params)128 static inline void lmkd_pack_get_procremove(LMKD_CTRL_PACKET packet,
129 struct lmk_procremove* params) {
130 params->pid = (pid_t)ntohl(packet[1]);
131 }
132
133 /*
134 * Prepare LMK_PROCREMOVE packet and return packet size in bytes.
135 * Warning: no checks performed, caller should ensure valid parameters.
136 */
lmkd_pack_set_procremove(LMKD_CTRL_PACKET packet,struct lmk_procprio * params)137 static inline size_t lmkd_pack_set_procremove(LMKD_CTRL_PACKET packet,
138 struct lmk_procprio* params) {
139 packet[0] = htonl(LMK_PROCREMOVE);
140 packet[1] = htonl(params->pid);
141 return 2 * sizeof(int);
142 }
143
144 /*
145 * Prepare LMK_PROCPURGE packet and return packet size in bytes.
146 * Warning: no checks performed, caller should ensure valid parameters.
147 */
lmkd_pack_set_procpurge(LMKD_CTRL_PACKET packet)148 static inline size_t lmkd_pack_set_procpurge(LMKD_CTRL_PACKET packet) {
149 packet[0] = htonl(LMK_PROCPURGE);
150 return sizeof(int);
151 }
152
153 /* LMK_GETKILLCNT packet payload */
154 struct lmk_getkillcnt {
155 int min_oomadj;
156 int max_oomadj;
157 };
158
159 /*
160 * For LMK_GETKILLCNT packet get its payload.
161 * Warning: no checks performed, caller should ensure valid parameters.
162 */
lmkd_pack_get_getkillcnt(LMKD_CTRL_PACKET packet,struct lmk_getkillcnt * params)163 static inline void lmkd_pack_get_getkillcnt(LMKD_CTRL_PACKET packet,
164 struct lmk_getkillcnt* params) {
165 params->min_oomadj = ntohl(packet[1]);
166 params->max_oomadj = ntohl(packet[2]);
167 }
168
169 /*
170 * Prepare LMK_GETKILLCNT packet and return packet size in bytes.
171 * Warning: no checks performed, caller should ensure valid parameters.
172 */
lmkd_pack_set_getkillcnt(LMKD_CTRL_PACKET packet,struct lmk_getkillcnt * params)173 static inline size_t lmkd_pack_set_getkillcnt(LMKD_CTRL_PACKET packet,
174 struct lmk_getkillcnt* params) {
175 packet[0] = htonl(LMK_GETKILLCNT);
176 packet[1] = htonl(params->min_oomadj);
177 packet[2] = htonl(params->max_oomadj);
178 return 3 * sizeof(int);
179 }
180
181 /*
182 * Prepare LMK_GETKILLCNT reply packet and return packet size in bytes.
183 * Warning: no checks performed, caller should ensure valid parameters.
184 */
lmkd_pack_set_getkillcnt_repl(LMKD_CTRL_PACKET packet,int kill_cnt)185 static inline size_t lmkd_pack_set_getkillcnt_repl(LMKD_CTRL_PACKET packet, int kill_cnt) {
186 packet[0] = htonl(LMK_GETKILLCNT);
187 packet[1] = htonl(kill_cnt);
188 return 2 * sizeof(int);
189 }
190
191 __END_DECLS
192
193 #endif /* _LMKD_H_ */
194