• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &param)
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> &param, 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> &param)
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> &param)
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> &param)
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