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 <cstring>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <unistd.h>
23 #include <sys/ioctl.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <sys/syscall.h>
27 #include "dfx/log/ffrt_log_api.h"
28 #include "eu/qos_interface.h"
29
30 #ifndef OHOS_STANDARD_SYSTEM
31 #define GET_TID() 10086
32 #else
33 #define GET_TID() syscall(SYS_gettid)
34 #endif
35
TrivalOpenRtgNode(void)36 static int TrivalOpenRtgNode(void)
37 {
38 char fileName[] = "/proc/self/sched_rtg_ctrl";
39 int fd = open(fileName, O_RDWR);
40 if (fd < 0) {
41 FFRT_LOGE("task %d belong to user %d open rtg node failed\n", getpid(), getuid());
42 }
43
44 return fd;
45 }
46
TrivalOpenAuthCtrlNode(void)47 static int TrivalOpenAuthCtrlNode(void)
48 {
49 char fileName[] = "/dev/auth_ctrl";
50 int fd = open(fileName, O_RDWR);
51 if (fd < 0) {
52 FFRT_LOGE("task %d belong to user %d open auth node failed\n", getpid(), getuid());
53 }
54
55 return fd;
56 }
57
TrivalOpenQosCtrlNode(void)58 static int TrivalOpenQosCtrlNode(void)
59 {
60 char fileName[] = "/proc/thread-self/sched_qos_ctrl";
61 int fd = open(fileName, O_RDWR);
62 if (fd < 0) {
63 FFRT_LOGW("pid %d belong to user %d open qos node warn, fd:%d, eno:%d, %s\n",
64 getpid(), getuid(), fd, errno, strerror(errno));
65 }
66
67 return fd;
68 }
69
FFRTEnableRtg(bool flag)70 int FFRTEnableRtg(bool flag)
71 {
72 struct RtgEnableData enableData;
73 char configStr[] = "load_freq_switch:1;sched_cycle:1";
74 int ret;
75
76 enableData.enable = flag;
77 enableData.len = sizeof(configStr);
78 enableData.data = configStr;
79 int fd = TrivalOpenRtgNode();
80 if (fd < 0) {
81 return fd;
82 }
83
84 ret = ioctl(fd, CMD_ID_SET_ENABLE, &enableData);
85 if (ret < 0) {
86 FFRT_LOGE("set rtg config enable failed.\n");
87 }
88
89 close(fd);
90
91 return 0;
92 };
93
FFRTAuthEnable(unsigned int uid,unsigned int uaFlag,unsigned int status)94 int FFRTAuthEnable(unsigned int uid, unsigned int uaFlag, unsigned int status)
95 {
96 struct AuthCtrlData data;
97 int fd;
98 int ret;
99
100 fd = TrivalOpenAuthCtrlNode();
101 if (fd < 0) {
102 return fd;
103 }
104
105 data.uid = uid;
106 data.rtgUaFlag = uaFlag;
107 data.qosUaFlag = AF_QOS_ALL;
108 data.status = status;
109 data.type = AUTH_ENABLE;
110
111 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
112 if (ret < 0) {
113 FFRT_LOGE("auth enable failed for uid %d with status %d\n", uid, status);
114 }
115 close(fd);
116 return ret;
117 }
118
FFRTAuthSwitch(unsigned int uid,unsigned int rtgFlag,unsigned int qosFlag,unsigned int status)119 int FFRTAuthSwitch(unsigned int uid, unsigned int rtgFlag, unsigned int qosFlag, unsigned int status)
120 {
121 struct AuthCtrlData data;
122 int fd;
123 int ret;
124
125 fd = TrivalOpenAuthCtrlNode();
126 if (fd < 0) {
127 return fd;
128 }
129
130 data.uid = uid;
131 data.rtgUaFlag = rtgFlag;
132 data.qosUaFlag = qosFlag;
133 data.status = status;
134 data.type = AUTH_SWITCH;
135
136 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
137 if (ret < 0) {
138 FFRT_LOGE("auth switch failed for uid %d with status %d\n", uid, status);
139 }
140 close(fd);
141 return ret;
142 }
143
FFRTAuthDelete(unsigned int uid)144 int FFRTAuthDelete(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 = AUTH_DELETE;
157
158 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
159 if (ret < 0) {
160 FFRT_LOGE("auth delete failed for uid %d\n", uid);
161 }
162 close(fd);
163 return ret;
164 }
165
FFRTAuthPause(unsigned int uid)166 int FFRTAuthPause(unsigned int uid)
167 {
168 struct AuthCtrlData data;
169 int fd;
170 int ret;
171
172 fd = TrivalOpenAuthCtrlNode();
173 if (fd < 0) {
174 return fd;
175 }
176
177 data.uid = uid;
178 data.type = AUTH_SWITCH;
179 data.rtgUaFlag = 0;
180 data.qosUaFlag = AF_QOS_DELEGATED;
181 data.status = AUTH_STATUS_BACKGROUND;
182
183 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
184 if (ret < 0) {
185 FFRT_LOGE("auth pause failed for uid %d\n", uid);
186 }
187 close(fd);
188 return ret;
189 }
190
FFRTAuthGet(unsigned int uid,unsigned int * uaFlag,unsigned int * status)191 int FFRTAuthGet(unsigned int uid, unsigned int *uaFlag, unsigned int *status)
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.uid = uid;
203 data.type = AUTH_GET;
204
205 ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data);
206 if (ret < 0) {
207 FFRT_LOGE("auth get failed for uid %d\n", uid);
208 }
209 close(fd);
210
211 *uaFlag = data.rtgUaFlag;
212 *status = data.status;
213
214 return ret;
215 }
216
FFRTQosApply(unsigned int level)217 int FFRTQosApply(unsigned int level)
218 {
219 int tid = GET_TID();
220 int ret;
221
222 ret = FFRTQosApplyForOther(level, tid);
223 return ret;
224 }
225
FFRTQosApplyForOther(unsigned int level,int tid)226 int FFRTQosApplyForOther(unsigned int level, int tid)
227 {
228 struct QosCtrlData data;
229 int fd;
230
231 int ret;
232
233 fd = TrivalOpenQosCtrlNode();
234 if (fd < 0) {
235 return fd;
236 }
237
238 data.level = level;
239 data.type = QOS_APPLY;
240 data.pid = tid;
241
242 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
243 if (ret < 0) {
244 FFRT_LOGW("tid %d, %s, ret:%d, eno:%d\n", tid, strerror(errno), ret, errno);
245 }
246 close(fd);
247 return ret;
248 }
249
FFRTQosLeave(void)250 int FFRTQosLeave(void)
251 {
252 struct QosCtrlData data;
253 int fd;
254 int ret;
255
256 fd = TrivalOpenQosCtrlNode();
257 if (fd < 0) {
258 return fd;
259 }
260
261 data.type = QOS_LEAVE;
262 data.pid = GET_TID();
263
264 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
265 if (ret < 0) {
266 FFRT_LOGE("qos leave failed for task %d\n", getpid());
267 }
268
269 close(fd);
270 return ret;
271 }
272
FFRTQosLeaveForOther(int tid)273 int FFRTQosLeaveForOther(int tid)
274 {
275 struct QosCtrlData data;
276 int fd;
277 int ret;
278
279 fd = TrivalOpenQosCtrlNode();
280 if (fd < 0) {
281 return fd;
282 }
283
284 data.type = QOS_LEAVE;
285 data.pid = tid;
286
287 ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
288 if (ret < 0) {
289 FFRT_LOGE("qos leave failed for task %d\n", tid);
290 }
291 close(fd);
292 return ret;
293 }
294
QosPolicy(struct QosPolicyDatas * policyDatas)295 int QosPolicy(struct QosPolicyDatas *policyDatas)
296 {
297 int fd;
298 int ret;
299
300 fd = TrivalOpenQosCtrlNode();
301 if (fd < 0) {
302 return fd;
303 }
304
305 ret = ioctl(fd, QOS_CTRL_POLICY_OPERATION, policyDatas);
306 if (ret < 0) {
307 FFRT_LOGE("set qos policy failed for task %d\n", getpid());
308 }
309
310 close(fd);
311 return ret;
312 }
313
FFRTThreadCtrl(int tid,struct ThreadAttrCtrl & ctrlDatas)314 int FFRTThreadCtrl(int tid, struct ThreadAttrCtrl &ctrlDatas)
315 {
316 int fd;
317 int ret;
318 fd = TrivalOpenQosCtrlNode();
319 if (fd < 0) {
320 return fd;
321 }
322 ctrlDatas.tid = tid;
323 ret = ioctl(fd, QOS_THREAD_CTRL_OPERATION, &ctrlDatas);
324 if (ret < 0) {
325 FFRT_LOGE("set thread ctrl data failed for task %d, this func is not enable in OHOS\n", getpid());
326 }
327
328 close(fd);
329 return ret;
330 }
331
FFRTQosGet(struct QosCtrlData & data)332 int FFRTQosGet(struct QosCtrlData &data)
333 {
334 int tid = GET_TID();
335 return FFRTQosGetForOther(tid, data);
336 }
337
FFRTQosGetForOther(int tid,struct QosCtrlData & data)338 int FFRTQosGetForOther(int tid, struct QosCtrlData &data)
339 {
340 int fd = TrivalOpenQosCtrlNode();
341 if (fd < 0) {
342 return fd;
343 }
344
345 data.type = QOS_GET;
346 data.pid = tid;
347 data.qos = -1;
348 data.staticQos = -1;
349 data.dynamicQos = -1;
350
351 int ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data);
352 if (ret < 0) {
353 FFRT_LOGE("%s: qos get failed for thread %d, return %d", __func__, tid, ret);
354 }
355 close(fd);
356
357 return ret;
358 }
359
360 static Func_affinity funcAffinity = nullptr;
setFuncAffinity(Func_affinity func)361 void setFuncAffinity(Func_affinity func)
362 {
363 funcAffinity = func;
364 }
365
getFuncAffinity(void)366 Func_affinity getFuncAffinity(void)
367 {
368 return funcAffinity;
369 }
370
371 static Func_priority funcPriority = nullptr;
setFuncPriority(Func_priority func)372 void setFuncPriority(Func_priority func)
373 {
374 funcPriority = func;
375 }
376
getFuncPriority(void)377 Func_priority getFuncPriority(void)
378 {
379 return funcPriority;
380 }