1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef GNU_SOURCE
17 #define GNU_SOURCE
18 #endif
19 #include <cstdio>
20 #include <unistd.h>
21 #include <sys/ioctl.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24
25 #include "../include/qos_interface.h"
26
27 constexpr unsigned int AF_QOS_ALL = 0x0003;
28 constexpr unsigned int AF_QOS_DELEGATED = 0x0001;
29
TrivalOpenRtgNode(void)30 static int TrivalOpenRtgNode(void)
31 {
32 char fileName[] = "/proc/self/sched_rtg_ctrl";
33 int fd = open(fileName, O_RDWR);
34 #ifdef QOS_DEBUG
35 if (fd < 0) {
36 printf("task %d belong to user %d open rtg node failed\n", getpid(), getuid());
37 }
38 #endif
39 return fd;
40 }
41
TrivalOpenAuthCtrlNode(void)42 static int TrivalOpenAuthCtrlNode(void)
43 {
44 char fileName[] = "/dev/auth_ctrl";
45 int fd = open(fileName, O_RDWR);
46 #ifdef QOS_DEBUG
47 if (fd < 0) {
48 printf("task %d belong to user %d open auth node failed\n", getpid(), getuid());
49 }
50 #endif
51 return fd;
52 }
53
TrivalOpenQosCtrlNode(void)54 static int TrivalOpenQosCtrlNode(void)
55 {
56 char fileName[] = "/proc/thread-self/sched_qos_ctrl";
57 int fd = open(fileName, O_RDWR);
58 #ifdef QOS_DEBUG
59 if (fd < 0) {
60 printf("task %d belong to user %d open qos node failed\n", getpid(), getuid());
61 }
62 #endif
63 return fd;
64 }
65
EnableRtg(bool flag)66 int EnableRtg(bool flag)
67 {
68 struct RtgEnableData enableData;
69 char configStr[] = "load_freq_switch:1;sched_cycle:1;frame_max_util:750";
70 int ret;
71
72 enableData.enable = flag;
73 enableData.len = sizeof(configStr);
74 enableData.data = configStr;
75 int fd = TrivalOpenRtgNode();
76 if (fd < 0) {
77 return fd;
78 }
79
80 ret = ioctl(fd, CMD_ID_SET_ENABLE, &enableData);
81 if (ret < 0) {
82 printf("set rtg config enable failed.\n");
83 }
84
85 close(fd);
86
87 return 0;
88 };
89
AuthEnable(unsigned int uid,unsigned int uaFlag,unsigned int status)90 int AuthEnable(unsigned int uid, unsigned int uaFlag, unsigned int status)
91 {
92 struct AuthCtrlData data;
93 int fd;
94 int ret;
95
96 fd = TrivalOpenAuthCtrlNode();
97 if (fd < 0) {
98 return fd;
99 }
100
101 data.uid = uid;
102 data.rtgUaFlag = uaFlag;
103 data.qosUaFlag = AF_QOS_ALL;
104 data.status = status;
105 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_ENABLE);
106
107 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
108 #ifdef QOS_DEBUG
109 if (ret < 0) {
110 printf("auth enable failed for uid %u with status %u\n", uid, status);
111 }
112 #endif
113 close(fd);
114 return ret;
115 }
116
AuthSwitch(unsigned int uid,unsigned int rtgFlag,unsigned int qosFlag,unsigned int status)117 int AuthSwitch(unsigned int uid, unsigned int rtgFlag, unsigned int qosFlag, unsigned int status)
118 {
119 struct AuthCtrlData data;
120 int fd;
121 int ret;
122
123 fd = TrivalOpenAuthCtrlNode();
124 if (fd < 0) {
125 return fd;
126 }
127
128 data.uid = uid;
129 data.rtgUaFlag = rtgFlag;
130 data.qosUaFlag = qosFlag;
131 data.status = status;
132 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
133
134 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
135 #ifdef QOS_DEBUG
136 if (ret < 0) {
137 printf("auth switch failed for uid %u with status %u\n", uid, status);
138 }
139 #endif
140 close(fd);
141 return ret;
142 }
143
AuthDelete(unsigned int uid)144 int AuthDelete(unsigned int uid)
145 {
146 struct AuthCtrlData data;
147 int fd;
148 int ret;
149
150 fd = TrivalOpenAuthCtrlNode();
151 if (fd < 0) {
152 return fd;
153 }
154
155 data.uid = uid;
156 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_DELETE);
157
158 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
159 #ifdef QOS_DEBUG
160 if (ret < 0) {
161 printf("auth delete failed for uid %u\n", uid);
162 }
163 #endif
164 close(fd);
165 return ret;
166 }
167
AuthPause(unsigned int uid)168 int AuthPause(unsigned int uid)
169 {
170 struct AuthCtrlData data;
171 int fd;
172 int ret;
173
174 fd = TrivalOpenAuthCtrlNode();
175 if (fd < 0) {
176 return fd;
177 }
178
179 data.uid = uid;
180 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
181 data.rtgUaFlag = 0;
182 data.qosUaFlag = AF_QOS_DELEGATED;
183 data.status = static_cast<unsigned int>(AuthStatus::AUTH_STATUS_BACKGROUND);
184
185 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
186 #ifdef QOS_DEBUG
187 if (ret < 0) {
188 printf("auth pause failed for uid %u\n", uid);
189 }
190 #endif
191 close(fd);
192 return ret;
193 }
194
AuthGet(unsigned int uid,unsigned int * uaFlag,unsigned int * status)195 int AuthGet(unsigned int uid, unsigned int *uaFlag, unsigned int *status)
196 {
197 struct AuthCtrlData data;
198 int fd;
199 int ret;
200
201 fd = TrivalOpenAuthCtrlNode();
202 if (fd < 0) {
203 return fd;
204 }
205
206 data.uid = uid;
207 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_GET);
208
209 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
210 #ifdef QOS_DEBUG
211 if (ret < 0) {
212 printf("auth get failed for uid %u\n", uid);
213 }
214 #endif
215 close(fd);
216
217 *uaFlag = data.rtgUaFlag;
218 *status = data.status;
219
220 return ret;
221 }
222
QosApply(unsigned int level)223 int QosApply(unsigned int level)
224 {
225 int tid = gettid();
226 int ret;
227
228 ret = QosApplyForOther(level, tid);
229 return ret;
230 }
231
QosApplyForOther(unsigned int level,int tid)232 int QosApplyForOther(unsigned int level, int tid)
233 {
234 struct QosCtrlData data;
235 int fd;
236
237 int ret;
238
239 fd = TrivalOpenQosCtrlNode();
240 if (fd < 0) {
241 return fd;
242 }
243
244 data.level = level;
245 data.type = static_cast<unsigned int>(QosManipulateType::QOS_APPLY);
246 data.pid = tid;
247
248 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
249 #ifdef QOS_DEBUG
250 if (ret < 0) {
251 printf("qos apply failed for task %d\n", tid);
252 }
253 #endif
254 close(fd);
255 return ret;
256 }
257
QosLeave(void)258 int QosLeave(void)
259 {
260 struct QosCtrlData data;
261 int fd;
262 int ret;
263
264 fd = TrivalOpenQosCtrlNode();
265 if (fd < 0) {
266 return fd;
267 }
268
269 data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE);
270 data.pid = gettid();
271
272 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
273 #ifdef QOS_DEBUG
274 if (ret < 0) {
275 printf("qos leave failed for task %d\n", getpid());
276 }
277 #endif
278 close(fd);
279 return ret;
280 }
281
QosLeaveForOther(int tid)282 int QosLeaveForOther(int tid)
283 {
284 struct QosCtrlData data;
285 int fd;
286 int ret;
287
288 fd = TrivalOpenQosCtrlNode();
289 if (fd < 0) {
290 return fd;
291 }
292
293 data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE);
294 data.pid = tid;
295
296 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
297 #ifdef QOS_DEBUG
298 if (ret < 0) {
299 printf("qos leave failed for task %d\n", tid);
300 }
301 #endif
302 close(fd);
303 return ret;
304 }
305
QosPolicy(struct QosPolicyDatas * policyDatas)306 int QosPolicy(struct QosPolicyDatas *policyDatas)
307 {
308 int fd;
309 int ret;
310
311 fd = TrivalOpenQosCtrlNode();
312 if (fd < 0) {
313 return fd;
314 }
315
316 ret = ioctl(fd, QOS_CTRL_POLICY_OPERATION, policyDatas);
317 #ifdef QOS_DEBUG
318 if (ret < 0) {
319 printf("set qos policy failed for task %d\n", getpid());
320 }
321 #endif
322 close(fd);
323 return ret;
324 }
325