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 28static 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 39static 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 50static 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 61int 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 85int 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 112int 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 139int 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 163int 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 190int 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 214int 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 232int QosApply(unsigned int level) 233{ 234 int tid = gettid(); 235 int ret; 236 237 ret = QosApplyForOther(level, tid); 238 return ret; 239} 240 241int 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 265int 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 287int 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 309int 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 327int QosGet(int &level) 328{ 329 int tid = gettid(); 330 return QosGetForOther(tid, level); 331} 332 333int 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}