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 "memmgr_log.h"
17 #include "reclaim_strategy_constants.h"
18 #include "memcg_mgr.h"
19
20 namespace OHOS {
21 namespace Memory {
22 namespace {
23 const std::string TAG = "MemcgMgr";
24 } // namespace
25
26 IMPLEMENT_SINGLE_INSTANCE(MemcgMgr);
27
MemcgMgr()28 MemcgMgr::MemcgMgr()
29 {
30 rootMemcg_ = new (std::nothrow) Memcg();
31 if (rootMemcg_ == nullptr) {
32 HILOGE("new obj failed!");
33 }
34 }
35
~MemcgMgr()36 MemcgMgr::~MemcgMgr()
37 {
38 delete rootMemcg_;
39 rootMemcg_ = nullptr;
40 while (!userMemcgsMap_.empty()) {
41 auto iter = userMemcgsMap_.begin();
42 delete iter->second;
43 iter->second = nullptr;
44 userMemcgsMap_.erase(iter);
45 }
46 }
47
GetRootMemcg() const48 Memcg* MemcgMgr::GetRootMemcg() const
49 {
50 return rootMemcg_;
51 }
52
SetRootMemcgPara()53 bool MemcgMgr::SetRootMemcgPara()
54 {
55 if (!rootMemcg_ || !rootMemcg_->reclaimRatios_) {
56 HILOGE("rootMemcg nullptr");
57 return false;
58 }
59 rootMemcg_->SetScore(APP_SCORE);
60 rootMemcg_->SetReclaimRatios(ROOT_MEMCG_MEM_2_ZRAM_RATIO,
61 ROOT_MEMCG_ZRAM_2_UFS_RATIO, ROOT_MEMCG_REFAULT_THRESHOLD);
62 bool ret = rootMemcg_->SetScoreAndReclaimRatiosToKernel();
63 HILOGI("Init rootMemcg reclaim retios success");
64 return ret;
65 }
66
GetUserMemcg(unsigned int userId)67 UserMemcg* MemcgMgr::GetUserMemcg(unsigned int userId)
68 {
69 std::map<int, UserMemcg*>::iterator it = userMemcgsMap_.find(userId);
70 if (it == userMemcgsMap_.end()) {
71 return nullptr;
72 }
73 return it->second;
74 }
75
AddUserMemcg(unsigned int userId)76 UserMemcg* MemcgMgr::AddUserMemcg(unsigned int userId)
77 {
78 HILOGI("userId=%{public}u", userId);
79 UserMemcg* memcg = new (std::nothrow) UserMemcg(userId);
80 if (memcg == nullptr) {
81 HILOGE("new obj failed!");
82 return nullptr;
83 }
84 userMemcgsMap_.insert(std::make_pair(userId, memcg));
85 memcg->CreateMemcgDir();
86 return memcg;
87 }
88
RemoveUserMemcg(unsigned int userId)89 bool MemcgMgr::RemoveUserMemcg(unsigned int userId)
90 {
91 HILOGI("userId=%{public}u", userId);
92 UserMemcg* memcg = GetUserMemcg(userId);
93 if (memcg == nullptr) {
94 HILOGI("account %{public}u not exist. cannot remove", userId);
95 return false;
96 }
97 memcg->RemoveMemcgDir();
98 userMemcgsMap_.erase(userId);
99 delete memcg;
100 memcg = nullptr;
101 return GetUserMemcg(userId) == nullptr;
102 }
103
UpdateMemcgScoreAndReclaimRatios(unsigned int userId,int score,const ReclaimRatios & ratios)104 bool MemcgMgr::UpdateMemcgScoreAndReclaimRatios(unsigned int userId, int score, const ReclaimRatios& ratios)
105 {
106 UserMemcg* memcg = GetUserMemcg(userId);
107 if (memcg == nullptr) {
108 HILOGI("account %{public}u not exist. cannot update score and ratios", userId);
109 return false;
110 }
111 HILOGI("update reclaim retios userId=%{public}u score=%{public}d, %{public}s",
112 userId, score, ratios.ToString().c_str());
113 memcg->SetScore(score);
114 return memcg->SetReclaimRatios(ratios) && memcg->SetScoreAndReclaimRatiosToKernel();
115 }
116
AddProcToMemcg(unsigned int pid,unsigned int userId)117 bool MemcgMgr::AddProcToMemcg(unsigned int pid, unsigned int userId)
118 {
119 HILOGI("pid=%{public}u userId=%{public}u", pid, userId);
120 UserMemcg* memcg = GetUserMemcg(userId);
121 if (memcg == nullptr) { // new user
122 HILOGI("no such user. go create %{public}u", userId);
123 memcg = AddUserMemcg(userId);
124 }
125 if (memcg == nullptr) {
126 HILOGE("AddUserMemcg failed %{public}u", userId);
127 return false;
128 }
129 return memcg->AddProc(pid); // add pid to memcg
130 }
131
SwapInMemcg(unsigned int userId)132 bool MemcgMgr::SwapInMemcg(unsigned int userId)
133 {
134 UserMemcg* memcg = GetUserMemcg(userId);
135 if (memcg == nullptr) { // no such user
136 return false;
137 }
138 return memcg->SwapIn();
139 }
140
GetMemcgSwapInfo(unsigned int userId)141 SwapInfo* MemcgMgr::GetMemcgSwapInfo(unsigned int userId)
142 {
143 UserMemcg* memcg = GetUserMemcg(userId);
144 if (memcg == nullptr) { // no such user
145 return nullptr;
146 }
147 memcg->UpdateSwapInfoFromKernel();
148 return memcg->swapInfo_;
149 }
150
GetMemcgMemInfo(unsigned int userId)151 MemInfo* MemcgMgr::GetMemcgMemInfo(unsigned int userId)
152 {
153 UserMemcg* memcg = GetUserMemcg(userId);
154 if (memcg == nullptr) { // no such user
155 return nullptr;
156 }
157 memcg->UpdateMemInfoFromKernel();
158 return memcg->memInfo_;
159 }
160 } // namespace Memory
161 } // namespace OHOS
162