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 #include <fstream>
17 #include <kernel_interface.h>
18
19 #include "memmgr_log.h"
20 #include "memmgr_config_manager.h"
21
22 namespace OHOS {
23 namespace Memory {
24 namespace {
25 const std::string TAG = "MemmgrConfigManager";
26 const std::string XML_PATH = "/etc/xml/";
27 const std::string MEMCG_PATH = KernelInterface::MEMCG_BASE_PATH;
28 } // namespace
29 IMPLEMENT_SINGLE_INSTANCE(MemmgrConfigManager);
30
Init()31 bool MemmgrConfigManager::Init()
32 {
33 ReadParamFromXml();
34 WriteReclaimRatiosConfigToKernel();
35 return this->XmlLoaded;
36 }
37
MemmgrConfigManager()38 MemmgrConfigManager::MemmgrConfigManager()
39 {
40 }
41
~MemmgrConfigManager()42 MemmgrConfigManager::~MemmgrConfigManager()
43 {
44 }
45
AvailBufferSize(int availBuffer,int minAvailBuffer,int highAvailBuffer,int swapReserve)46 AvailBufferSize::AvailBufferSize(int availBuffer, int minAvailBuffer, int highAvailBuffer, int swapReserve)
47 : availBuffer(availBuffer),
48 minAvailBuffer(minAvailBuffer),
49 highAvailBuffer(highAvailBuffer),
50 swapReserve(swapReserve) {};
ReclaimRatiosConfig(int minScore,int maxScore,int mem2zramRatio,int zran2ufsRation,int refaultThreshold)51 ReclaimRatiosConfig::ReclaimRatiosConfig(int minScore, int maxScore, int mem2zramRatio, int zran2ufsRation,
52 int refaultThreshold) : minScore(minScore), maxScore(maxScore), mem2zramRatio(mem2zramRatio),
53 zran2ufsRation(zran2ufsRation), refaultThreshold(refaultThreshold)
54 {
55 }
56
GetXmlLoaded()57 bool MemmgrConfigManager::GetXmlLoaded()
58 {
59 return this->XmlLoaded;
60 }
61
ClearExistConfig()62 void MemmgrConfigManager::ClearExistConfig()
63 {
64 ClearReclaimRatiosConfigSet();
65 }
66
ReadParamFromXml()67 bool MemmgrConfigManager::ReadParamFromXml()
68 {
69 std::string path = KernelInterface::GetInstance().JoinPath(XML_PATH, "memmgr_config.xml");
70 HILOGI(":%{public}s", path.c_str());
71 if (!CheckPathExist(path.c_str())) {
72 HILOGE("bad profile path! path:%{public}s", path.c_str());
73 return false;
74 }
75 std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(
76 xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc);
77 if (docPtr == nullptr) {
78 HILOGE("xmlReadFile error!");
79 return false;
80 }
81 ClearExistConfig();
82 xmlNodePtr rootNodePtr = xmlDocGetRootElement(docPtr.get());
83 XmlLoaded = ParseXmlRootNode(rootNodePtr);
84 return XmlLoaded;
85 }
86
ParseXmlRootNode(const xmlNodePtr & rootNodePtr)87 bool MemmgrConfigManager::ParseXmlRootNode(const xmlNodePtr &rootNodePtr)
88 {
89 for (xmlNodePtr currNode = rootNodePtr->xmlChildrenNode; currNode != nullptr; currNode = currNode->next) {
90 std::string name = std::string(reinterpret_cast<const char *>(currNode->name));
91 if (name.compare("reclaimConfig") == 0) {
92 ParseReclaimConfig(currNode);
93 continue;
94 }
95 if (name.compare("killConfig") == 0) {
96 ParseKillConfig(currNode);
97 continue;
98 }
99 HILOGW("unknow node :<%{public}s>", name.c_str());
100 return false;
101 }
102 return true;
103 }
104
ParseKillConfig(const xmlNodePtr & rootNodePtr)105 bool MemmgrConfigManager::ParseKillConfig(const xmlNodePtr &rootNodePtr)
106 {
107 return true;
108 }
109
ParseReclaimConfig(const xmlNodePtr & rootNodePtr)110 bool MemmgrConfigManager::ParseReclaimConfig(const xmlNodePtr &rootNodePtr)
111 {
112 if (!CheckNode(rootNodePtr) || !HasChild(rootNodePtr)) {
113 return true;
114 }
115 for (xmlNodePtr currNode = rootNodePtr->xmlChildrenNode; currNode != nullptr; currNode = currNode->next) {
116 std::map<std::string, std::string> param;
117 GetModuleParam(currNode, param);
118 SetReclaimParam(currNode, param);
119 }
120 return true;
121 }
122
GetModuleParam(const xmlNodePtr & rootNodePtr,std::map<std::string,std::string> & param)123 bool MemmgrConfigManager::GetModuleParam(const xmlNodePtr &rootNodePtr, std::map<std::string, std::string> ¶m)
124 {
125 for (xmlNodePtr currNode = rootNodePtr->xmlChildrenNode; currNode != nullptr; currNode = currNode->next) {
126 if (!CheckNode(currNode)) {
127 return false;
128 }
129 std::string key = std::string(reinterpret_cast<const char *>(currNode->name));
130 auto contentPtr = xmlNodeGetContent(currNode);
131 std::string value;
132 if (contentPtr != nullptr) {
133 value = std::string(reinterpret_cast<char *>(contentPtr));
134 xmlFree(contentPtr);
135 }
136 param.insert(std::pair<std::string, std::string>(key, value));
137 HILOGI("key:<%{public}s>, value:<%{public}s>", key.c_str(), value.c_str());
138 }
139 return true;
140 }
141
SetIntParam(std::map<std::string,std::string> & param,std::string key,int * dst)142 void MemmgrConfigManager::SetIntParam(std::map<std::string, std::string> ¶m, std::string key, int* dst)
143 {
144 std::map<std::string, std::string>::iterator iter = param.find(key);
145 if (iter != param.end()) {
146 char *endptr;
147 int val = strtol(iter->second.c_str(), &endptr, 10);
148 if (*endptr == '\0') {
149 *dst = val;
150 }
151 return;
152 }
153 HILOGW("find param failed key:<%{public}s>", key.c_str());
154 }
155
SetReclaimParam(const xmlNodePtr & currNodePtr,std::map<std::string,std::string> & param)156 bool MemmgrConfigManager::SetReclaimParam(const xmlNodePtr &currNodePtr,
157 std::map<std::string, std::string> ¶m)
158 {
159 std::string name = std::string(reinterpret_cast<const char *>(currNodePtr->name));
160 if (name.compare("availbuffer") == 0) {
161 return SetAvailBufferConfig(param);
162 }
163 if (name.compare("ZswapdParam") == 0) {
164 return SetZswapdParamConfig(param);
165 }
166 HILOGW("unknow node :<%{public}s>", name.c_str());
167 return false;
168 }
169
SetAvailBufferConfig(std::map<std::string,std::string> & param)170 bool MemmgrConfigManager::SetAvailBufferConfig(std::map<std::string, std::string> ¶m)
171 {
172 int availBuffer = AVAIL_BUFFER; // default availBuffer 800MB
173 int minAvailBuffer = MIN_AVAIL_BUFFER; // default minAvailBuffer 750MB
174 int highAvailBuffer = HIGH_AVAIL_BUFFER; // default highAvailBuffer 850MB
175 int swapReserve = SWAP_RESERVE; // default swapReserve 200MB
176
177 SetIntParam(param, "availBuffer", &availBuffer);
178 SetIntParam(param, "minAvailBuffer", &minAvailBuffer);
179 SetIntParam(param, "highAvailBuffer", &highAvailBuffer);
180 SetIntParam(param, "swapReserve", &swapReserve);
181 delete this->availBufferSize;
182 this->availBufferSize = new AvailBufferSize(availBuffer, minAvailBuffer, highAvailBuffer, swapReserve);
183 return true;
184 }
185
SetZswapdParamConfig(std::map<std::string,std::string> & param)186 bool MemmgrConfigManager::SetZswapdParamConfig(std::map<std::string, std::string> ¶m)
187 {
188 std::map<std::string, std::string>::iterator iter;
189 int minScore = RECLAIM_PRIORITY_MIN;
190 int maxScore = RECLAIM_PRIORITY_MAX; // default maxAppscore 1000
191 int mem2zramRatio = MEMCG_MEM_2_ZRAM_RATIO; // default mem2zramRatio 40%
192 int zran2ufsRation = MEMCG_ZRAM_2_UFS_RATIO;
193 int refaultThreshold = MEMCG_REFAULT_THRESHOLD;
194
195 SetIntParam(param, "minScore", &minScore);
196 SetIntParam(param, "maxScore", &maxScore);
197 SetIntParam(param, "mem2zramRatio", &mem2zramRatio);
198 SetIntParam(param, "zran2ufsRation", &zran2ufsRation);
199 SetIntParam(param, "refaultThreshold", &refaultThreshold);
200
201 ReclaimRatiosConfig *reclaimRatiosConfig =
202 new ReclaimRatiosConfig(minScore, maxScore, mem2zramRatio, zran2ufsRation, refaultThreshold);
203 AddReclaimRatiosConfigToSet(reclaimRatiosConfig);
204 return true;
205 }
206
CheckNode(const xmlNodePtr & nodePtr)207 bool MemmgrConfigManager::CheckNode(const xmlNodePtr &nodePtr)
208 {
209 if (nodePtr != nullptr && nodePtr->name != nullptr &&
210 (nodePtr->type == XML_ELEMENT_NODE || nodePtr->type == XML_TEXT_NODE)) {
211 return true;
212 }
213 return false;
214 }
215
CheckPathExist(const char * path)216 bool MemmgrConfigManager::CheckPathExist(const char *path)
217 {
218 std::ifstream profileStream(path);
219 return profileStream.good();
220 }
221
HasChild(const xmlNodePtr & rootNodePtr)222 bool MemmgrConfigManager::HasChild(const xmlNodePtr &rootNodePtr)
223 {
224 return xmlChildElementCount(rootNodePtr) > 0;
225 }
226
AddReclaimRatiosConfigToSet(ReclaimRatiosConfig * reclaimRatiosConfig)227 void MemmgrConfigManager::AddReclaimRatiosConfigToSet(ReclaimRatiosConfig *reclaimRatiosConfig)
228 {
229 this->reclaimRatiosConfigSet.insert(reclaimRatiosConfig);
230 }
231
ClearReclaimRatiosConfigSet()232 void MemmgrConfigManager::ClearReclaimRatiosConfigSet()
233 {
234 for (auto i = reclaimRatiosConfigSet.begin(); i != reclaimRatiosConfigSet.end(); ++i) {
235 delete *i;
236 }
237 this->reclaimRatiosConfigSet.clear();
238 }
239
WriteReclaimRatiosConfigToKernel()240 bool MemmgrConfigManager::WriteReclaimRatiosConfigToKernel()
241 {
242 std::string path = KernelInterface::GetInstance().JoinPath(MEMCG_PATH, "memory.zswapd_memcgs_param");
243 std::string content;
244 int paramNum = this->reclaimRatiosConfigSet.size();
245 content += std::to_string(paramNum);
246 for (auto i = reclaimRatiosConfigSet.begin(); i != reclaimRatiosConfigSet.end(); ++i) {
247 content += " " + std::to_string((*i)->minScore);
248 content += " " + std::to_string((*i)->maxScore);
249 content += " " + std::to_string((*i)->mem2zramRatio);
250 content += " " + std::to_string((*i)->zran2ufsRation);
251 content += " " + std::to_string((*i)->refaultThreshold);
252 }
253 return KernelInterface::GetInstance().WriteToFile(path, content, false);
254 }
255
GetAvailBufferSize()256 AvailBufferSize *MemmgrConfigManager::GetAvailBufferSize()
257 {
258 return this->availBufferSize;
259 }
260
GetReclaimRatiosConfigSet()261 const MemmgrConfigManager::ReclaimRatiosConfigSet MemmgrConfigManager::GetReclaimRatiosConfigSet()
262 {
263 return this->reclaimRatiosConfigSet;
264 }
265 } // namespace Memory
266 } // namespace OHOS
267