• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cerrno>
16 #include <cstring>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <array>
22 #include "eu/qos_interface.h"
23 #include "dfx/log/ffrt_log_api.h"
24 #include "eu/osattr_manager.h"
25 
26 namespace ffrt {
27 const int fd_buffer_len = 20;
28 
CheckSchedAttrPara(const std::string & name,int min,int max,int paraValue)29 bool OSAttrManager::CheckSchedAttrPara(const std::string &name, int min, int max, int paraValue)
30 {
31     if (paraValue < min || paraValue > max) {
32         FFRT_LOGE("OSAttrManager::CheckAttrPara para %s is invalid", name.c_str());
33         return false;
34     }
35     return true;
36 }
37 
UpdateSchedAttr(const QoS & qos,ffrt_os_sched_attr * attr)38 int OSAttrManager::UpdateSchedAttr(const QoS& qos, ffrt_os_sched_attr *attr)
39 {
40     FFRT_LOGI("OSAttrManager::UpdateSchedAttr start qos[%d] attr.lat_nice[%d] attr.cpumap[0x%s] attr.u_min[%d]\
41         attr.shares[%d]", qos(), attr->latency_nice, attr->cpumap, attr->uclamp_min, attr->shares);
42     if (qos() <= qos_max) {
43         FFRT_LOGE("qos[%d] attr update is not supported.\n", qos());
44         return -1;
45     }
46 
47     struct SchedParaCheckInfo {
48         std::string paraName;
49         int min;
50         int max;
51         int paraValue;
52     };
53 
54     std::vector<SchedParaCheckInfo> checkInfo {
55         { "share",        CGROUP_SHARES_MIN,    CGROUP_SHARES_MAX,     attr->shares},
56         { "latencynice",  CGROUP_LAT_NICE_MIN,  CGROUP_LAT_NICE_MAX,   attr->latency_nice},
57         { "uclampmin",    CGROUP_UCLAMP_MIN,    CGROUP_UCLAMP_MAX,     attr->uclamp_min},
58         { "uclampmax",    CGROUP_UCLAMP_MIN,    CGROUP_UCLAMP_MAX,     attr->uclamp_max},
59         { "vipprio",      CGROUP_VIPPRIO_MIN,   CGROUP_VIPPRIO_MAX,    attr->vip_prio},
60     };
61 
62     for (const auto &tmpPara : checkInfo) {
63         if (!CheckSchedAttrPara(tmpPara.paraName, tmpPara.min, tmpPara.max, tmpPara.paraValue)) {
64             return -1;
65         }
66     }
67 
68     SetCGroupCtlPara(cpuSharesNode, attr->shares);
69     SetCGroupCtlPara(cpuLatencyniceNode, attr->latency_nice);
70     SetCGroupCtlPara(cpuUclampminNode, attr->uclamp_min);
71     SetCGroupCtlPara(cpuUclampmaxNode, attr->uclamp_max);
72     SetCGroupCtlPara(cpuvipprioNode, attr->vip_prio);
73     SetCGroupSetPara(cpuMapNode, static_cast<std::string>(attr->cpumap));
74     return 0;
75 }
76 
SetCGroupCtlPara(const std::string & name,int32_t value)77 void OSAttrManager::SetCGroupCtlPara(const std::string &name, int32_t value)
78 {
79     const std::string filename = cpuctlGroupIvePath + name;
80     SetCGroupPara(filename, value);
81 }
82 
SetCGroupSetPara(const std::string & name,const std::string & value)83 void OSAttrManager::SetCGroupSetPara(const std::string &name, const std::string &value)
84 {
85     const std::string filename = cpusetGroupIvePath + name;
86     SetCGroupPara(filename, value);
87 }
88 
SetTidToCGroup(int32_t pid)89 void OSAttrManager::SetTidToCGroup(int32_t pid)
90 {
91     SetTidToCGroupPrivate(cpuctlGroupIvePath + cpuThreadNode, pid);
92     SetTidToCGroupPrivate(cpusetGroupIvePath + cpuThreadNode, pid);
93 }
94 
SetTidToCGroupPrivate(const std::string & filename,int32_t pid)95 void OSAttrManager::SetTidToCGroupPrivate(const std::string &filename, int32_t pid)
96 {
97     constexpr int32_t maxThreadId = 0xffff;
98     if (pid <= 0 || pid >= maxThreadId) {
99         FFRT_LOGE("[cgroup_ctrl] invalid pid[%d]\n", pid);
100         return;
101     }
102     SetCGroupPara(filename, pid);
103 }
104 
105 template <typename T>
SetCGroupPara(const std::string & filename,T & value)106 void OSAttrManager::SetCGroupPara(const std::string &filename, T& value)
107 {
108     char filePath[PATH_MAX_LENS] = {0};
109     if (filename.empty()) {
110         FFRT_LOGE("[cgroup_ctrl] invalid para, filename is empty");
111         return;
112     }
113 
114     if ((strlen(filename.c_str()) > PATH_MAX_LENS) || (realpath(filename.c_str(), filePath) == nullptr)) {
115         FFRT_LOGE("[cgroup_ctrl] invalid file path:%s, error:%s\n", filename.c_str(), strerror(errno));
116         return;
117     }
118 
119     int32_t fd = open(filePath, O_RDWR);
120     if (fd < 0) {
121         FFRT_LOGE("[cgroup_ctrl] fail to open filePath:%s", filePath);
122         return;
123     }
124 
125     std::string valueStr;
126     if constexpr (std::is_same<T, int32_t>::value) {
127         valueStr = std::to_string(value);
128     } else if constexpr (std::is_same<T, const std::string>::value) {
129         valueStr = value;
130     } else {
131         FFRT_LOGE("[cgroup_ctrl] invalid value type\n");
132         close(fd);
133         return;
134     }
135 
136     int32_t ret = write(fd, valueStr.c_str(), valueStr.size());
137     if (ret < 0) {
138         FFRT_LOGE("[cgroup_ctrl] fail to write path:%s valueStr:%s to fd:%d, errno:%d",
139             filePath, valueStr.c_str(), fd, errno);
140         close(fd);
141         return;
142     }
143 
144     const uint32_t bufferLen = fd_buffer_len;
145     std::array<char, bufferLen> buffer {};
146     int32_t count = read(fd, buffer.data(), bufferLen);
147     if (count <= 0) {
148         FFRT_LOGE("[cgroup_ctrl] fail to read value:%s to fd:%d, errno:%d", buffer.data(), fd, errno);
149     } else {
150         FFRT_LOGI("[cgroup_ctrl] success to read %s buffer:%s", filePath, buffer.data());
151     }
152     close(fd);
153 }
154 } // namespace ffrt