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 <unistd.h>
25 #include <concurrent_task_log.h>
26
27 #include "qos_interface.h"
28
TrivalOpenRtgNode(void)29 static int TrivalOpenRtgNode(void)
30 {
31 char fileName[] = "/proc/self/sched_rtg_ctrl";
32 int fd = open(fileName, O_RDWR);
33 if (fd < 0) {
34 CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open rtg node failed, errno = %{public}d",
35 getpid(), getuid(), errno);
36 }
37 return fd;
38 }
39
TrivalOpenAuthCtrlNode(void)40 static int TrivalOpenAuthCtrlNode(void)
41 {
42 char fileName[] = "/dev/auth_ctrl";
43 int fd = open(fileName, O_RDWR);
44 if (fd < 0) {
45 CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open auth node failed, errno = %{public}d",
46 getpid(), getuid(), errno);
47 }
48 return fd;
49 }
50
TrivalOpenQosCtrlNode(void)51 static int TrivalOpenQosCtrlNode(void)
52 {
53 char fileName[] = "/proc/thread-self/sched_qos_ctrl";
54 int fd = open(fileName, O_RDWR);
55 if (fd < 0) {
56 CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open qos node failed, errno = %{public}d",
57 getpid(), getuid(), errno);
58 }
59 return fd;
60 }
61
EnableRtg(bool flag)62 int EnableRtg(bool flag)
63 {
64 struct RtgEnableData enableData;
65 char configStr[] = "load_freq_switch:1;sched_cycle:1;frame_max_util:1024";
66 int ret;
67
68 enableData.enable = flag;
69 enableData.len = sizeof(configStr);
70 enableData.data = configStr;
71 int fd = TrivalOpenRtgNode();
72 if (fd < 0) {
73 return fd;
74 }
75
76 ret = ioctl(fd, CMD_ID_SET_ENABLE, &enableData);
77 if (ret < 0) {
78 printf("set rtg config enable failed.\n");
79 }
80
81 close(fd);
82
83 return 0;
84 };
85
AuthEnable(unsigned int pid,unsigned int uaFlag,unsigned int status)86 int AuthEnable(unsigned int pid, unsigned int uaFlag, unsigned int status)
87 {
88 struct AuthCtrlData data;
89 int fd;
90 int ret;
91
92 fd = TrivalOpenAuthCtrlNode();
93 if (fd < 0) {
94 return fd;
95 }
96
97 data.pid = pid;
98 data.rtgUaFlag = uaFlag;
99 data.qosUaFlag = AF_QOS_DELEGATED;
100 data.status = status;
101 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_ENABLE);
102
103 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
104 #ifdef QOS_DEBUG
105 if (ret < 0) {
106 printf("auth enable failed for pid %u with status %u\n", pid, status);
107 }
108 #endif
109 close(fd);
110 return ret;
111 }
112
AuthSwitch(unsigned int pid,unsigned int rtgFlag,unsigned int qosFlag,unsigned int status)113 int AuthSwitch(unsigned int pid, unsigned int rtgFlag, unsigned int qosFlag, unsigned int status)
114 {
115 struct AuthCtrlData data;
116 int fd;
117 int ret;
118
119 fd = TrivalOpenAuthCtrlNode();
120 if (fd < 0) {
121 return fd;
122 }
123
124 data.pid = pid;
125 data.rtgUaFlag = rtgFlag;
126 data.qosUaFlag = qosFlag;
127 data.status = status;
128 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
129
130 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
131 #ifdef QOS_DEBUG
132 if (ret < 0) {
133 printf("auth switch failed for pid %u with status %u\n", pid, status);
134 }
135 #endif
136 close(fd);
137 return ret;
138 }
139
AuthDelete(unsigned int pid)140 int AuthDelete(unsigned int pid)
141 {
142 struct AuthCtrlData data;
143 int fd;
144 int ret;
145
146 fd = TrivalOpenAuthCtrlNode();
147 if (fd < 0) {
148 return fd;
149 }
150
151 data.pid = pid;
152 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_DELETE);
153
154 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
155 #ifdef QOS_DEBUG
156 if (ret < 0) {
157 printf("auth delete failed for pid %u\n", pid);
158 }
159 #endif
160 close(fd);
161 return ret;
162 }
163
AuthPause(unsigned int pid)164 int AuthPause(unsigned int pid)
165 {
166 struct AuthCtrlData data;
167 int fd;
168 int ret;
169
170 fd = TrivalOpenAuthCtrlNode();
171 if (fd < 0) {
172 return fd;
173 }
174
175 data.pid = pid;
176 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH);
177 data.rtgUaFlag = 0;
178 data.qosUaFlag = AF_QOS_DELEGATED;
179 data.status = static_cast<unsigned int>(AuthStatus::AUTH_STATUS_BACKGROUND);
180
181 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
182 #ifdef QOS_DEBUG
183 if (ret < 0) {
184 printf("auth pause failed for pid %u\n", pid);
185 }
186 #endif
187 close(fd);
188 return ret;
189 }
190
AuthGet(unsigned int pid)191 int AuthGet(unsigned int pid)
192 {
193 struct AuthCtrlData data;
194 int fd;
195 int ret;
196
197 fd = TrivalOpenAuthCtrlNode();
198 if (fd < 0) {
199 return fd;
200 }
201
202 data.pid = pid;
203 data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_GET);
204
205 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
206 if (ret < 0) {
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 }