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 <cerrno>
20 #include <cstdio>
21 #include <unistd.h>
22 #include <sys/ioctl.h>
23 #include <fcntl.h>
24 #include <concurrent_task_log.h>
25
26 #include "qos_interface.h"
27
TrivalOpenRtgNode(void)28 static int TrivalOpenRtgNode(void)
29 {
30 char fileName[] = "/proc/self/sched_rtg_ctrl";
31 int fd = open(fileName, O_RDWR);
32 if (fd < 0) {
33 CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open rtg node failed, errno = %{public}d",
34 getpid(), getuid(), errno);
35 }
36 return fd;
37 }
38
TrivalOpenAuthCtrlNode(void)39 static int TrivalOpenAuthCtrlNode(void)
40 {
41 char fileName[] = "/dev/auth_ctrl";
42 int fd = open(fileName, O_RDWR);
43 if (fd < 0) {
44 CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open auth node failed, errno = %{public}d",
45 getpid(), getuid(), errno);
46 }
47 return fd;
48 }
49
TrivalOpenQosCtrlNode(void)50 static int TrivalOpenQosCtrlNode(void)
51 {
52 char fileName[] = "/proc/thread-self/sched_qos_ctrl";
53 int fd = open(fileName, O_RDWR);
54 if (fd < 0) {
55 CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open qos node failed, errno = %{public}d",
56 getpid(), getuid(), errno);
57 }
58 return fd;
59 }
60
EnableRtg(bool flag)61 int EnableRtg(bool flag)
62 {
63 struct RtgEnableData enableData;
64 char configStr[] = "load_freq_switch:1;sched_cycle:1;frame_max_util:1024";
65 int ret;
66
67 enableData.enable = flag;
68 enableData.len = sizeof(configStr);
69 enableData.data = configStr;
70 int fd = TrivalOpenRtgNode();
71 if (fd < 0) {
72 return fd;
73 }
74
75 ret = ioctl(fd, CMD_ID_SET_ENABLE, &enableData);
76 if (ret < 0) {
77 printf("set rtg config enable failed.\n");
78 }
79
80 close(fd);
81
82 return 0;
83 };
84
AuthEnable(unsigned int pid, unsigned int uaFlag, unsigned int status)85 int AuthEnable(unsigned int pid, unsigned int uaFlag, unsigned int status)
86 {
87 struct AuthCtrlData data;
88 int fd;
89 int ret;
90
91 fd = TrivalOpenAuthCtrlNode();
92 if (fd < 0) {
93 return fd;
94 }
95
96 data.pid = pid;
97 data.rtgUaFlag = uaFlag;
98 data.qosUaFlag = AF_QOS_DELEGATED;
99 data.status = status;
100 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_ENABLE);
101
102 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
103 #ifdef QOS_DEBUG
104 if (ret < 0) {
105 printf("auth enable failed for pid %u with status %u\n", pid, status);
106 }
107 #endif
108 close(fd);
109 return ret;
110 }
111
AuthSwitch(unsigned int pid, unsigned int rtgFlag, unsigned int qosFlag, unsigned int status)112 int AuthSwitch(unsigned int pid, unsigned int rtgFlag, unsigned int qosFlag, unsigned int status)
113 {
114 struct AuthCtrlData data;
115 int fd;
116 int ret;
117
118 fd = TrivalOpenAuthCtrlNode();
119 if (fd < 0) {
120 return fd;
121 }
122
123 data.pid = pid;
124 data.rtgUaFlag = rtgFlag;
125 data.qosUaFlag = qosFlag;
126 data.status = status;
127 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
128
129 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
130 #ifdef QOS_DEBUG
131 if (ret < 0) {
132 printf("auth switch failed for pid %u with status %u\n", pid, status);
133 }
134 #endif
135 close(fd);
136 return ret;
137 }
138
AuthDelete(unsigned int pid)139 int AuthDelete(unsigned int pid)
140 {
141 struct AuthCtrlData data;
142 int fd;
143 int ret;
144
145 fd = TrivalOpenAuthCtrlNode();
146 if (fd < 0) {
147 return fd;
148 }
149
150 data.pid = pid;
151 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_DELETE);
152
153 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
154 #ifdef QOS_DEBUG
155 if (ret < 0) {
156 printf("auth delete failed for pid %u\n", pid);
157 }
158 #endif
159 close(fd);
160 return ret;
161 }
162
AuthPause(unsigned int pid)163 int AuthPause(unsigned int pid)
164 {
165 struct AuthCtrlData data;
166 int fd;
167 int ret;
168
169 fd = TrivalOpenAuthCtrlNode();
170 if (fd < 0) {
171 return fd;
172 }
173
174 data.pid = pid;
175 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
176 data.rtgUaFlag = 0;
177 data.qosUaFlag = AF_QOS_DELEGATED;
178 data.status = static_cast<unsigned int>(AuthStatus::AUTH_STATUS_BACKGROUND);
179
180 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
181 #ifdef QOS_DEBUG
182 if (ret < 0) {
183 printf("auth pause failed for pid %u\n", pid);
184 }
185 #endif
186 close(fd);
187 return ret;
188 }
189
AuthGet(unsigned int pid)190 int AuthGet(unsigned int pid)
191 {
192 struct AuthCtrlData data;
193 int fd;
194 int ret;
195
196 fd = TrivalOpenAuthCtrlNode();
197 if (fd < 0) {
198 return fd;
199 }
200
201 data.pid = pid;
202 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_GET);
203
204 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
205 if (ret < 0) {
206 close(fd);
207 return ret;
208 }
209 close(fd);
210
211 return static_cast<int>(data.status);
212 }
213
AuthEnhance(unsigned int pid, bool enhanceStatus)214 int AuthEnhance(unsigned int pid, bool enhanceStatus)
215 {
216 int ret = 0;
217 #ifdef QOS_EXT_ENABLE
218 struct AuthCtrlData data;
219 int fd = TrivalOpenAuthCtrlNode();
220 if (fd < 0) {
221 return fd;
222 }
223
224 data.pid = pid;
225 data.enhanceStatus = enhanceStatus;
226 ret = ioctl(fd, ENHANCE_AUTH_CTRL_OPERATION, &data);
227 close(fd);
228 #endif
229 return ret;
230 }
231
QosApply(unsigned int level)232 int QosApply(unsigned int level)
233 {
234 int tid = gettid();
235 int ret;
236
237 ret = QosApplyForOther(level, tid);
238 return ret;
239 }
240
QosApplyForOther(unsigned int level, int tid)241 int QosApplyForOther(unsigned int level, int tid)
242 {
243 struct QosCtrlData data;
244 int fd;
245
246 int ret;
247
248 fd = TrivalOpenQosCtrlNode();
249 if (fd < 0) {
250 return fd;
251 }
252
253 data.level = level;
254 data.type = static_cast<unsigned int>(QosManipulateType::QOS_APPLY);
255 data.pid = tid;
256
257 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
258 if (ret < 0) {
259 CONCUR_LOGE("[Interface] task %{public}d apply qos failed, errno = %{public}d", tid, errno);
260 }
261 close(fd);
262 return ret;
263 }
264
QosLeave(void)265 int QosLeave(void)
266 {
267 struct QosCtrlData data;
268 int fd;
269 int ret;
270
271 fd = TrivalOpenQosCtrlNode();
272 if (fd < 0) {
273 return fd;
274 }
275
276 data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE);
277 data.pid = gettid();
278
279 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
280 if (ret < 0) {
281 CONCUR_LOGE("[Interface] task %{public}d leave qos failed, errno = %{public}d", gettid(), errno);
282 }
283 close(fd);
284 return ret;
285 }
286
QosLeaveForOther(int tid)287 int QosLeaveForOther(int tid)
288 {
289 struct QosCtrlData data;
290 int fd;
291 int ret;
292
293 fd = TrivalOpenQosCtrlNode();
294 if (fd < 0) {
295 return fd;
296 }
297
298 data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE);
299 data.pid = tid;
300
301 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
302 if (ret < 0) {
303 CONCUR_LOGE("[Interface] task %{public}d leave qos failed, errno = %{public}d", tid, errno);
304 }
305 close(fd);
306 return ret;
307 }
308
QosPolicySet(const struct QosPolicyDatas *policyDatas)309 int QosPolicySet(const struct QosPolicyDatas *policyDatas)
310 {
311 int fd;
312 int ret;
313
314 fd = TrivalOpenQosCtrlNode();
315 if (fd < 0) {
316 return fd;
317 }
318
319 ret = ioctl(fd, QOS_CTRL_POLICY_OPERATION, policyDatas);
320 if (ret < 0) {
321 CONCUR_LOGE("[Interface] set qos policy failed, errno = %{public}d", errno);
322 }
323 close(fd);
324 return ret;
325 }
326
QosGet(int &level)327 int QosGet(int &level)
328 {
329 int tid = gettid();
330 return QosGetForOther(tid, level);
331 }
332
QosGetForOther(int tid, int &level)333 int QosGetForOther(int tid, int &level)
334 {
335 int fd;
336 int ret = 0;
337
338 fd = TrivalOpenQosCtrlNode();
339 if (fd < 0) {
340 return fd;
341 }
342
343 struct QosCtrlData data;
344 data.type = static_cast<unsigned int>(QosManipulateType::QOS_GET);
345 data.pid = tid;
346 data.qos = -1;
347
348 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
349 if (ret < 0) {
350 CONCUR_LOGE("[Interface] task %{public}d get qos failed, errno = %{public}d", tid, errno);
351 }
352 level = data.qos;
353
354 close(fd);
355 return ret;
356 }