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