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 <unistd.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include "eu/qos_interface.h"
19 #include "eu/osattr_manager.h"
20 
21 namespace ffrt {
CheckSchedAttrPara(const std::string & name,int min,int max,int paraValue)22 bool OSAttrManager::CheckSchedAttrPara(const std::string &name, int min, int max, int paraValue)
23 {
24     if (paraValue < min || paraValue > max) {
25         FFRT_LOGE("OSAttrManager::CheckAttrPara para %s is invalid", name.c_str());
26         return false;
27     }
28     return true;
29 }
30 
UpdateSchedAttr(const QoS & qos,ffrt_os_sched_attr * attr)31 int OSAttrManager::UpdateSchedAttr(const QoS& qos, ffrt_os_sched_attr *attr)
32 {
33     FFRT_LOGI("OSAttrManager::UpdateSchedAttr start qos[%d] attr.lat_nice[%d] attr.cpumap[0x%s] attr.u_min[%d]\
34         attr.shares[%d]", qos(), attr->latency_nice, attr->cpumap, attr->uclamp_min, attr->shares);
35     if (GetFuncQosMax() == nullptr) {
36         FFRT_LOGE("FuncQosMap has not regist");
37         return -1;
38     }
39     if (qos() != GetFuncQosMax()() - 1) {
40         FFRT_LOGE("qos[%d] attr update is not supported.\n", qos());
41         return -1;
42     }
43 
44     struct SchedParaCheckInfo {
45         std::string paraName;
46         int min;
47         int max;
48         int paraValue;
49     };
50 
51     std::vector<SchedParaCheckInfo> checkInfo {
52         { "share",        CGROUP_SHARES_MIN,    CGROUP_SHARES_MAX,     attr->shares},
53         { "latencynice",  CGROUP_LAT_NICE_MIN,  CGROUP_LAT_NICE_MAX,   attr->latency_nice},
54         { "uclampmin",    CGROUP_UCLAMP_MIN,    CGROUP_UCLAMP_MAX,     attr->uclamp_min},
55         { "uclampmax",    CGROUP_UCLAMP_MIN,    CGROUP_UCLAMP_MAX,     attr->uclamp_max},
56         { "vipprio",      CGROUP_VIPPRIO_MIN,   CGROUP_VIPPRIO_MAX,    attr->vip_prio},
57     };
58 
59     for (const auto &tmpPara : checkInfo) {
60         if (!CheckSchedAttrPara(tmpPara.paraName, tmpPara.min, tmpPara.max, tmpPara.paraValue)) {
61             return -1;
62         }
63     }
64 
65     SetCGroupCtlPara(cpuSharesNode, attr->shares);
66     SetCGroupCtlPara(cpuUclampminNode, attr->uclamp_min);
67     SetCGroupCtlPara(cpuUclampmaxNode, attr->uclamp_max);
68 #ifndef OHOS_STANDARD_SYSTEM
69     SetCGroupCtlPara(cpuLatencyniceNode, attr->latency_nice);
70     SetCGroupCtlPara(cpuvipprioNode, attr->vip_prio);
71 #endif
72     SetCGroupSetPara(cpuMapNode, static_cast<std::string>(attr->cpumap));
73     return 0;
74 }
75 
SetCGroupCtlPara(const std::string & name,int32_t value)76 void OSAttrManager::SetCGroupCtlPara(const std::string &name, int32_t value)
77 {
78     const std::string filename = cpuctlGroupIvePath + name;
79     SetCGroupPara(filename, value);
80 }
81 
SetCGroupSetPara(const std::string & name,const std::string & value)82 void OSAttrManager::SetCGroupSetPara(const std::string &name, const std::string &value)
83 {
84     const std::string filename = cpusetGroupIvePath + name;
85     SetCGroupPara(filename, value);
86 }
87 
SetTidToCGroup(int32_t pid)88 void OSAttrManager::SetTidToCGroup(int32_t pid)
89 {
90     SetTidToCGroupPrivate(cpuctlGroupIvePath + cpuThreadNode, pid);
91     SetTidToCGroupPrivate(cpusetGroupIvePath + cpuThreadNode, pid);
92 }
93 
SetTidToCGroupPrivate(const std::string & filename,int32_t pid)94 void OSAttrManager::SetTidToCGroupPrivate(const std::string &filename, int32_t pid)
95 {
96     constexpr int32_t maxThreadId = 0xffff;
97     if (pid <= 0 || pid >= maxThreadId) {
98         FFRT_LOGE("[cgroup_ctrl] invalid pid[%d]\n", pid);
99         return;
100     }
101     SetCGroupPara(filename, pid);
102 }
103 } // namespace ffrt
104