13c3173acSopenharmony_ci/* 23c3173acSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 33c3173acSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43c3173acSopenharmony_ci * you may not use this file except in compliance with the License. 53c3173acSopenharmony_ci * You may obtain a copy of the License at 63c3173acSopenharmony_ci * 73c3173acSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83c3173acSopenharmony_ci * 93c3173acSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103c3173acSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113c3173acSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123c3173acSopenharmony_ci * See the License for the specific language governing permissions and 133c3173acSopenharmony_ci * limitations under the License. 143c3173acSopenharmony_ci */ 153c3173acSopenharmony_ci 163c3173acSopenharmony_ci#ifndef GNU_SOURCE 173c3173acSopenharmony_ci#define GNU_SOURCE 183c3173acSopenharmony_ci#endif 193c3173acSopenharmony_ci#include <cerrno> 203c3173acSopenharmony_ci#include <cstdio> 213c3173acSopenharmony_ci#include <unistd.h> 223c3173acSopenharmony_ci#include <sys/ioctl.h> 233c3173acSopenharmony_ci#include <fcntl.h> 243c3173acSopenharmony_ci#include <concurrent_task_log.h> 253c3173acSopenharmony_ci 263c3173acSopenharmony_ci#include "qos_interface.h" 273c3173acSopenharmony_ci 283c3173acSopenharmony_cistatic int TrivalOpenRtgNode(void) 293c3173acSopenharmony_ci{ 303c3173acSopenharmony_ci char fileName[] = "/proc/self/sched_rtg_ctrl"; 313c3173acSopenharmony_ci int fd = open(fileName, O_RDWR); 323c3173acSopenharmony_ci if (fd < 0) { 333c3173acSopenharmony_ci CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open rtg node failed, errno = %{public}d", 343c3173acSopenharmony_ci getpid(), getuid(), errno); 353c3173acSopenharmony_ci } 363c3173acSopenharmony_ci return fd; 373c3173acSopenharmony_ci} 383c3173acSopenharmony_ci 393c3173acSopenharmony_cistatic int TrivalOpenAuthCtrlNode(void) 403c3173acSopenharmony_ci{ 413c3173acSopenharmony_ci char fileName[] = "/dev/auth_ctrl"; 423c3173acSopenharmony_ci int fd = open(fileName, O_RDWR); 433c3173acSopenharmony_ci if (fd < 0) { 443c3173acSopenharmony_ci CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open auth node failed, errno = %{public}d", 453c3173acSopenharmony_ci getpid(), getuid(), errno); 463c3173acSopenharmony_ci } 473c3173acSopenharmony_ci return fd; 483c3173acSopenharmony_ci} 493c3173acSopenharmony_ci 503c3173acSopenharmony_cistatic int TrivalOpenQosCtrlNode(void) 513c3173acSopenharmony_ci{ 523c3173acSopenharmony_ci char fileName[] = "/proc/thread-self/sched_qos_ctrl"; 533c3173acSopenharmony_ci int fd = open(fileName, O_RDWR); 543c3173acSopenharmony_ci if (fd < 0) { 553c3173acSopenharmony_ci CONCUR_LOGE("[Interface] task %{public}d belong to user %{public}d open qos node failed, errno = %{public}d", 563c3173acSopenharmony_ci getpid(), getuid(), errno); 573c3173acSopenharmony_ci } 583c3173acSopenharmony_ci return fd; 593c3173acSopenharmony_ci} 603c3173acSopenharmony_ci 613c3173acSopenharmony_ciint EnableRtg(bool flag) 623c3173acSopenharmony_ci{ 633c3173acSopenharmony_ci struct RtgEnableData enableData; 643c3173acSopenharmony_ci char configStr[] = "load_freq_switch:1;sched_cycle:1;frame_max_util:1024"; 653c3173acSopenharmony_ci int ret; 663c3173acSopenharmony_ci 673c3173acSopenharmony_ci enableData.enable = flag; 683c3173acSopenharmony_ci enableData.len = sizeof(configStr); 693c3173acSopenharmony_ci enableData.data = configStr; 703c3173acSopenharmony_ci int fd = TrivalOpenRtgNode(); 713c3173acSopenharmony_ci if (fd < 0) { 723c3173acSopenharmony_ci return fd; 733c3173acSopenharmony_ci } 743c3173acSopenharmony_ci 753c3173acSopenharmony_ci ret = ioctl(fd, CMD_ID_SET_ENABLE, &enableData); 763c3173acSopenharmony_ci if (ret < 0) { 773c3173acSopenharmony_ci printf("set rtg config enable failed.\n"); 783c3173acSopenharmony_ci } 793c3173acSopenharmony_ci 803c3173acSopenharmony_ci close(fd); 813c3173acSopenharmony_ci 823c3173acSopenharmony_ci return 0; 833c3173acSopenharmony_ci}; 843c3173acSopenharmony_ci 853c3173acSopenharmony_ciint AuthEnable(unsigned int pid, unsigned int uaFlag, unsigned int status) 863c3173acSopenharmony_ci{ 873c3173acSopenharmony_ci struct AuthCtrlData data; 883c3173acSopenharmony_ci int fd; 893c3173acSopenharmony_ci int ret; 903c3173acSopenharmony_ci 913c3173acSopenharmony_ci fd = TrivalOpenAuthCtrlNode(); 923c3173acSopenharmony_ci if (fd < 0) { 933c3173acSopenharmony_ci return fd; 943c3173acSopenharmony_ci } 953c3173acSopenharmony_ci 963c3173acSopenharmony_ci data.pid = pid; 973c3173acSopenharmony_ci data.rtgUaFlag = uaFlag; 983c3173acSopenharmony_ci data.qosUaFlag = AF_QOS_DELEGATED; 993c3173acSopenharmony_ci data.status = status; 1003c3173acSopenharmony_ci data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_ENABLE); 1013c3173acSopenharmony_ci 1023c3173acSopenharmony_ci ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data); 1033c3173acSopenharmony_ci#ifdef QOS_DEBUG 1043c3173acSopenharmony_ci if (ret < 0) { 1053c3173acSopenharmony_ci printf("auth enable failed for pid %u with status %u\n", pid, status); 1063c3173acSopenharmony_ci } 1073c3173acSopenharmony_ci#endif 1083c3173acSopenharmony_ci close(fd); 1093c3173acSopenharmony_ci return ret; 1103c3173acSopenharmony_ci} 1113c3173acSopenharmony_ci 1123c3173acSopenharmony_ciint AuthSwitch(unsigned int pid, unsigned int rtgFlag, unsigned int qosFlag, unsigned int status) 1133c3173acSopenharmony_ci{ 1143c3173acSopenharmony_ci struct AuthCtrlData data; 1153c3173acSopenharmony_ci int fd; 1163c3173acSopenharmony_ci int ret; 1173c3173acSopenharmony_ci 1183c3173acSopenharmony_ci fd = TrivalOpenAuthCtrlNode(); 1193c3173acSopenharmony_ci if (fd < 0) { 1203c3173acSopenharmony_ci return fd; 1213c3173acSopenharmony_ci } 1223c3173acSopenharmony_ci 1233c3173acSopenharmony_ci data.pid = pid; 1243c3173acSopenharmony_ci data.rtgUaFlag = rtgFlag; 1253c3173acSopenharmony_ci data.qosUaFlag = qosFlag; 1263c3173acSopenharmony_ci data.status = status; 1273c3173acSopenharmony_ci data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH); 1283c3173acSopenharmony_ci 1293c3173acSopenharmony_ci ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data); 1303c3173acSopenharmony_ci#ifdef QOS_DEBUG 1313c3173acSopenharmony_ci if (ret < 0) { 1323c3173acSopenharmony_ci printf("auth switch failed for pid %u with status %u\n", pid, status); 1333c3173acSopenharmony_ci } 1343c3173acSopenharmony_ci#endif 1353c3173acSopenharmony_ci close(fd); 1363c3173acSopenharmony_ci return ret; 1373c3173acSopenharmony_ci} 1383c3173acSopenharmony_ci 1393c3173acSopenharmony_ciint AuthDelete(unsigned int pid) 1403c3173acSopenharmony_ci{ 1413c3173acSopenharmony_ci struct AuthCtrlData data; 1423c3173acSopenharmony_ci int fd; 1433c3173acSopenharmony_ci int ret; 1443c3173acSopenharmony_ci 1453c3173acSopenharmony_ci fd = TrivalOpenAuthCtrlNode(); 1463c3173acSopenharmony_ci if (fd < 0) { 1473c3173acSopenharmony_ci return fd; 1483c3173acSopenharmony_ci } 1493c3173acSopenharmony_ci 1503c3173acSopenharmony_ci data.pid = pid; 1513c3173acSopenharmony_ci data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_DELETE); 1523c3173acSopenharmony_ci 1533c3173acSopenharmony_ci ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data); 1543c3173acSopenharmony_ci#ifdef QOS_DEBUG 1553c3173acSopenharmony_ci if (ret < 0) { 1563c3173acSopenharmony_ci printf("auth delete failed for pid %u\n", pid); 1573c3173acSopenharmony_ci } 1583c3173acSopenharmony_ci#endif 1593c3173acSopenharmony_ci close(fd); 1603c3173acSopenharmony_ci return ret; 1613c3173acSopenharmony_ci} 1623c3173acSopenharmony_ci 1633c3173acSopenharmony_ciint AuthPause(unsigned int pid) 1643c3173acSopenharmony_ci{ 1653c3173acSopenharmony_ci struct AuthCtrlData data; 1663c3173acSopenharmony_ci int fd; 1673c3173acSopenharmony_ci int ret; 1683c3173acSopenharmony_ci 1693c3173acSopenharmony_ci fd = TrivalOpenAuthCtrlNode(); 1703c3173acSopenharmony_ci if (fd < 0) { 1713c3173acSopenharmony_ci return fd; 1723c3173acSopenharmony_ci } 1733c3173acSopenharmony_ci 1743c3173acSopenharmony_ci data.pid = pid; 1753c3173acSopenharmony_ci data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_SWITCH); 1763c3173acSopenharmony_ci data.rtgUaFlag = 0; 1773c3173acSopenharmony_ci data.qosUaFlag = AF_QOS_DELEGATED; 1783c3173acSopenharmony_ci data.status = static_cast<unsigned int>(AuthStatus::AUTH_STATUS_BACKGROUND); 1793c3173acSopenharmony_ci 1803c3173acSopenharmony_ci ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data); 1813c3173acSopenharmony_ci#ifdef QOS_DEBUG 1823c3173acSopenharmony_ci if (ret < 0) { 1833c3173acSopenharmony_ci printf("auth pause failed for pid %u\n", pid); 1843c3173acSopenharmony_ci } 1853c3173acSopenharmony_ci#endif 1863c3173acSopenharmony_ci close(fd); 1873c3173acSopenharmony_ci return ret; 1883c3173acSopenharmony_ci} 1893c3173acSopenharmony_ci 1903c3173acSopenharmony_ciint AuthGet(unsigned int pid) 1913c3173acSopenharmony_ci{ 1923c3173acSopenharmony_ci struct AuthCtrlData data; 1933c3173acSopenharmony_ci int fd; 1943c3173acSopenharmony_ci int ret; 1953c3173acSopenharmony_ci 1963c3173acSopenharmony_ci fd = TrivalOpenAuthCtrlNode(); 1973c3173acSopenharmony_ci if (fd < 0) { 1983c3173acSopenharmony_ci return fd; 1993c3173acSopenharmony_ci } 2003c3173acSopenharmony_ci 2013c3173acSopenharmony_ci data.pid = pid; 2023c3173acSopenharmony_ci data.type = static_cast<unsigned int>(AuthManipulateType::AUTH_GET); 2033c3173acSopenharmony_ci 2043c3173acSopenharmony_ci ret = ioctl(fd, BASIC_AUTH_CTRL_OPERATION, &data); 2053c3173acSopenharmony_ci if (ret < 0) { 2063c3173acSopenharmony_ci close(fd); 2073c3173acSopenharmony_ci return ret; 2083c3173acSopenharmony_ci } 2093c3173acSopenharmony_ci close(fd); 2103c3173acSopenharmony_ci 2113c3173acSopenharmony_ci return static_cast<int>(data.status); 2123c3173acSopenharmony_ci} 2133c3173acSopenharmony_ci 2143c3173acSopenharmony_ciint AuthEnhance(unsigned int pid, bool enhanceStatus) 2153c3173acSopenharmony_ci{ 2163c3173acSopenharmony_ci int ret = 0; 2173c3173acSopenharmony_ci#ifdef QOS_EXT_ENABLE 2183c3173acSopenharmony_ci struct AuthCtrlData data; 2193c3173acSopenharmony_ci int fd = TrivalOpenAuthCtrlNode(); 2203c3173acSopenharmony_ci if (fd < 0) { 2213c3173acSopenharmony_ci return fd; 2223c3173acSopenharmony_ci } 2233c3173acSopenharmony_ci 2243c3173acSopenharmony_ci data.pid = pid; 2253c3173acSopenharmony_ci data.enhanceStatus = enhanceStatus; 2263c3173acSopenharmony_ci ret = ioctl(fd, ENHANCE_AUTH_CTRL_OPERATION, &data); 2273c3173acSopenharmony_ci close(fd); 2283c3173acSopenharmony_ci#endif 2293c3173acSopenharmony_ci return ret; 2303c3173acSopenharmony_ci} 2313c3173acSopenharmony_ci 2323c3173acSopenharmony_ciint QosApply(unsigned int level) 2333c3173acSopenharmony_ci{ 2343c3173acSopenharmony_ci int tid = gettid(); 2353c3173acSopenharmony_ci int ret; 2363c3173acSopenharmony_ci 2373c3173acSopenharmony_ci ret = QosApplyForOther(level, tid); 2383c3173acSopenharmony_ci return ret; 2393c3173acSopenharmony_ci} 2403c3173acSopenharmony_ci 2413c3173acSopenharmony_ciint QosApplyForOther(unsigned int level, int tid) 2423c3173acSopenharmony_ci{ 2433c3173acSopenharmony_ci struct QosCtrlData data; 2443c3173acSopenharmony_ci int fd; 2453c3173acSopenharmony_ci 2463c3173acSopenharmony_ci int ret; 2473c3173acSopenharmony_ci 2483c3173acSopenharmony_ci fd = TrivalOpenQosCtrlNode(); 2493c3173acSopenharmony_ci if (fd < 0) { 2503c3173acSopenharmony_ci return fd; 2513c3173acSopenharmony_ci } 2523c3173acSopenharmony_ci 2533c3173acSopenharmony_ci data.level = level; 2543c3173acSopenharmony_ci data.type = static_cast<unsigned int>(QosManipulateType::QOS_APPLY); 2553c3173acSopenharmony_ci data.pid = tid; 2563c3173acSopenharmony_ci 2573c3173acSopenharmony_ci ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data); 2583c3173acSopenharmony_ci if (ret < 0) { 2593c3173acSopenharmony_ci CONCUR_LOGE("[Interface] task %{public}d apply qos failed, errno = %{public}d", tid, errno); 2603c3173acSopenharmony_ci } 2613c3173acSopenharmony_ci close(fd); 2623c3173acSopenharmony_ci return ret; 2633c3173acSopenharmony_ci} 2643c3173acSopenharmony_ci 2653c3173acSopenharmony_ciint QosLeave(void) 2663c3173acSopenharmony_ci{ 2673c3173acSopenharmony_ci struct QosCtrlData data; 2683c3173acSopenharmony_ci int fd; 2693c3173acSopenharmony_ci int ret; 2703c3173acSopenharmony_ci 2713c3173acSopenharmony_ci fd = TrivalOpenQosCtrlNode(); 2723c3173acSopenharmony_ci if (fd < 0) { 2733c3173acSopenharmony_ci return fd; 2743c3173acSopenharmony_ci } 2753c3173acSopenharmony_ci 2763c3173acSopenharmony_ci data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE); 2773c3173acSopenharmony_ci data.pid = gettid(); 2783c3173acSopenharmony_ci 2793c3173acSopenharmony_ci ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data); 2803c3173acSopenharmony_ci if (ret < 0) { 2813c3173acSopenharmony_ci CONCUR_LOGE("[Interface] task %{public}d leave qos failed, errno = %{public}d", gettid(), errno); 2823c3173acSopenharmony_ci } 2833c3173acSopenharmony_ci close(fd); 2843c3173acSopenharmony_ci return ret; 2853c3173acSopenharmony_ci} 2863c3173acSopenharmony_ci 2873c3173acSopenharmony_ciint QosLeaveForOther(int tid) 2883c3173acSopenharmony_ci{ 2893c3173acSopenharmony_ci struct QosCtrlData data; 2903c3173acSopenharmony_ci int fd; 2913c3173acSopenharmony_ci int ret; 2923c3173acSopenharmony_ci 2933c3173acSopenharmony_ci fd = TrivalOpenQosCtrlNode(); 2943c3173acSopenharmony_ci if (fd < 0) { 2953c3173acSopenharmony_ci return fd; 2963c3173acSopenharmony_ci } 2973c3173acSopenharmony_ci 2983c3173acSopenharmony_ci data.type = static_cast<unsigned int>(QosManipulateType::QOS_LEAVE); 2993c3173acSopenharmony_ci data.pid = tid; 3003c3173acSopenharmony_ci 3013c3173acSopenharmony_ci ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data); 3023c3173acSopenharmony_ci if (ret < 0) { 3033c3173acSopenharmony_ci CONCUR_LOGE("[Interface] task %{public}d leave qos failed, errno = %{public}d", tid, errno); 3043c3173acSopenharmony_ci } 3053c3173acSopenharmony_ci close(fd); 3063c3173acSopenharmony_ci return ret; 3073c3173acSopenharmony_ci} 3083c3173acSopenharmony_ci 3093c3173acSopenharmony_ciint QosPolicySet(const struct QosPolicyDatas *policyDatas) 3103c3173acSopenharmony_ci{ 3113c3173acSopenharmony_ci int fd; 3123c3173acSopenharmony_ci int ret; 3133c3173acSopenharmony_ci 3143c3173acSopenharmony_ci fd = TrivalOpenQosCtrlNode(); 3153c3173acSopenharmony_ci if (fd < 0) { 3163c3173acSopenharmony_ci return fd; 3173c3173acSopenharmony_ci } 3183c3173acSopenharmony_ci 3193c3173acSopenharmony_ci ret = ioctl(fd, QOS_CTRL_POLICY_OPERATION, policyDatas); 3203c3173acSopenharmony_ci if (ret < 0) { 3213c3173acSopenharmony_ci CONCUR_LOGE("[Interface] set qos policy failed, errno = %{public}d", errno); 3223c3173acSopenharmony_ci } 3233c3173acSopenharmony_ci close(fd); 3243c3173acSopenharmony_ci return ret; 3253c3173acSopenharmony_ci} 3263c3173acSopenharmony_ci 3273c3173acSopenharmony_ciint QosGet(int &level) 3283c3173acSopenharmony_ci{ 3293c3173acSopenharmony_ci int tid = gettid(); 3303c3173acSopenharmony_ci return QosGetForOther(tid, level); 3313c3173acSopenharmony_ci} 3323c3173acSopenharmony_ci 3333c3173acSopenharmony_ciint QosGetForOther(int tid, int &level) 3343c3173acSopenharmony_ci{ 3353c3173acSopenharmony_ci int fd; 3363c3173acSopenharmony_ci int ret = 0; 3373c3173acSopenharmony_ci 3383c3173acSopenharmony_ci fd = TrivalOpenQosCtrlNode(); 3393c3173acSopenharmony_ci if (fd < 0) { 3403c3173acSopenharmony_ci return fd; 3413c3173acSopenharmony_ci } 3423c3173acSopenharmony_ci 3433c3173acSopenharmony_ci struct QosCtrlData data; 3443c3173acSopenharmony_ci data.type = static_cast<unsigned int>(QosManipulateType::QOS_GET); 3453c3173acSopenharmony_ci data.pid = tid; 3463c3173acSopenharmony_ci data.qos = -1; 3473c3173acSopenharmony_ci 3483c3173acSopenharmony_ci ret = ioctl(fd, QOS_CTRL_BASIC_OPERATION, &data); 3493c3173acSopenharmony_ci if (ret < 0) { 3503c3173acSopenharmony_ci CONCUR_LOGE("[Interface] task %{public}d get qos failed, errno = %{public}d", tid, errno); 3513c3173acSopenharmony_ci } 3523c3173acSopenharmony_ci level = data.qos; 3533c3173acSopenharmony_ci 3543c3173acSopenharmony_ci close(fd); 3553c3173acSopenharmony_ci return ret; 3563c3173acSopenharmony_ci}