1ba5c3796Sopenharmony_ci/* 2ba5c3796Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3ba5c3796Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4ba5c3796Sopenharmony_ci * you may not use this file except in compliance with the License. 5ba5c3796Sopenharmony_ci * You may obtain a copy of the License at 6ba5c3796Sopenharmony_ci * 7ba5c3796Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8ba5c3796Sopenharmony_ci * 9ba5c3796Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10ba5c3796Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11ba5c3796Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ba5c3796Sopenharmony_ci * See the License for the specific language governing permissions and 13ba5c3796Sopenharmony_ci * limitations under the License. 14ba5c3796Sopenharmony_ci */ 15ba5c3796Sopenharmony_ci 16ba5c3796Sopenharmony_ci#include "memmgr_log.h" 17ba5c3796Sopenharmony_ci#include "memmgr_ptr_util.h" 18ba5c3796Sopenharmony_ci#include "parameters.h" 19ba5c3796Sopenharmony_ci#include "kernel_interface.h" 20ba5c3796Sopenharmony_ci#include "nandlife_controller.h" 21ba5c3796Sopenharmony_ci 22ba5c3796Sopenharmony_cinamespace OHOS { 23ba5c3796Sopenharmony_cinamespace Memory { 24ba5c3796Sopenharmony_cinamespace { 25ba5c3796Sopenharmony_ciconst std::string TAG = "NandLifeController"; 26ba5c3796Sopenharmony_ci 27ba5c3796Sopenharmony_ciconstexpr int TIMER_PEROID_MIN = 15; 28ba5c3796Sopenharmony_ciconstexpr int TIMER_PEROID_MS = TIMER_PEROID_MIN * 60 * 1000; 29ba5c3796Sopenharmony_ci 30ba5c3796Sopenharmony_ciconst std::string PARAM_VALUE_ZERO = "0"; 31ba5c3796Sopenharmony_ciconst std::string PARAM_VALUE_ONE = "1"; 32ba5c3796Sopenharmony_ciconst std::string PARAM_VALUE_UNKOWN = "-1"; 33ba5c3796Sopenharmony_ci 34ba5c3796Sopenharmony_ciconst std::string PERMANENTLY_CLOSED_STATUS_PARAM = "persist.resourceschedule.memmgr.eswap.permanently.closed"; 35ba5c3796Sopenharmony_ciconst std::string PERMANENTLY_CLOSED = PARAM_VALUE_ONE; 36ba5c3796Sopenharmony_ciconst std::string NOT_PERMANENTLY_CLOSED = PARAM_VALUE_ZERO; 37ba5c3796Sopenharmony_ci 38ba5c3796Sopenharmony_ciconst std::string MINS_TODAY_PARAM = "persist.resourceschedule.memmgr.eswap.minsToday"; 39ba5c3796Sopenharmony_ci 40ba5c3796Sopenharmony_ciconst std::string SWAP_OUT_KB_TODAY_PARAM = "persist.resourceschedule.memmgr.eswap.swapOutKBToday"; 41ba5c3796Sopenharmony_ci 42ba5c3796Sopenharmony_ciconst std::string MINS_FROM_BIRTH_PARAM = "persist.resourceschedule.memmgr.eswap.minsFromBirth"; 43ba5c3796Sopenharmony_ci 44ba5c3796Sopenharmony_ciconst std::string SWAP_OUT_KB_FROM_BIRTH_PARAM = "persist.resourceschedule.memmgr.eswap.swapOutKBFromBirth"; 45ba5c3796Sopenharmony_ci 46ba5c3796Sopenharmony_ciconst std::string params[] = { 47ba5c3796Sopenharmony_ci PERMANENTLY_CLOSED_STATUS_PARAM, 48ba5c3796Sopenharmony_ci MINS_TODAY_PARAM, 49ba5c3796Sopenharmony_ci SWAP_OUT_KB_TODAY_PARAM, 50ba5c3796Sopenharmony_ci MINS_FROM_BIRTH_PARAM, 51ba5c3796Sopenharmony_ci SWAP_OUT_KB_FROM_BIRTH_PARAM, 52ba5c3796Sopenharmony_ci}; 53ba5c3796Sopenharmony_ci 54ba5c3796Sopenharmony_ciconst std::string PSI_HEALTH_INFO_PATH = "/dev/memcg/memory.eswap_info"; 55ba5c3796Sopenharmony_ciconst std::string SWAP_OUT_SIZE_TAG = "Total Swapout Size"; 56ba5c3796Sopenharmony_ci 57ba5c3796Sopenharmony_ciconst std::string ESWAP_ENABLE_PATH = "/proc/sys/kernel/hyperhold/enable"; 58ba5c3796Sopenharmony_ciconst std::string ENABLE_ESWAP = "enable"; 59ba5c3796Sopenharmony_ciconst std::string DISABLE_ESWAP = "disable"; 60ba5c3796Sopenharmony_ci 61ba5c3796Sopenharmony_ciconstexpr int RETRY_TIMES = 3; 62ba5c3796Sopenharmony_ci} 63ba5c3796Sopenharmony_ci 64ba5c3796Sopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(NandLifeController); 65ba5c3796Sopenharmony_ci 66ba5c3796Sopenharmony_ciNandLifeController::NandLifeController() 67ba5c3796Sopenharmony_ci{ 68ba5c3796Sopenharmony_ci} 69ba5c3796Sopenharmony_ci 70ba5c3796Sopenharmony_cibool NandLifeController::Init() 71ba5c3796Sopenharmony_ci{ 72ba5c3796Sopenharmony_ci if (!GetEventHandler()) { 73ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("init handler failed, nandlife controller cannot set timmer"); 74ba5c3796Sopenharmony_ci return false; 75ba5c3796Sopenharmony_ci } 76ba5c3796Sopenharmony_ci HILOGI("init handler successed"); 77ba5c3796Sopenharmony_ci 78ba5c3796Sopenharmony_ci // read nandlife config from xml, then check and set it. 79ba5c3796Sopenharmony_ci // if the config does not meet the requirements, eswap will be closed temporarily. 80ba5c3796Sopenharmony_ci if (!GetAndValidateNandLifeConfig()) { 81ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("get or validate nandlife config failed, controller will not work properly."); 82ba5c3796Sopenharmony_ci return false; 83ba5c3796Sopenharmony_ci } 84ba5c3796Sopenharmony_ci HILOGI("get and validate nandlife config success. dailyQuotaMB=%{public}llu, totalQuotaMB=%{public}llu", 85ba5c3796Sopenharmony_ci config_.GetDailySwapOutQuotaMb(), config_.GetTotalSwapOutQuotaMb()); 86ba5c3796Sopenharmony_ci if (config_.GetDailySwapOutQuotaMb() == 0 && config_.GetTotalSwapOutQuotaMb() == 0) { 87ba5c3796Sopenharmony_ci HILOGE("will not limit swap-out!"); 88ba5c3796Sopenharmony_ci OpenSwapOutPermanently(); 89ba5c3796Sopenharmony_ci OpenSwapOutTemporarily("not limit swap-out in xml"); 90ba5c3796Sopenharmony_ci return true; 91ba5c3796Sopenharmony_ci } else { 92ba5c3796Sopenharmony_ci DAILY_SWAP_OUT_QUOTA_KB = config_.GetDailySwapOutQuotaMb() * 1024; // 1024: MB to KB 93ba5c3796Sopenharmony_ci TOTAL_SWAP_OUT_QUOTA_KB = config_.GetTotalSwapOutQuotaMb() * 1024; // 1024: MB to KB 94ba5c3796Sopenharmony_ci } 95ba5c3796Sopenharmony_ci 96ba5c3796Sopenharmony_ci if (!LoadNandLifeParam()) { 97ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("load nandlife info file failed, controller will not work properly."); 98ba5c3796Sopenharmony_ci return false; 99ba5c3796Sopenharmony_ci } 100ba5c3796Sopenharmony_ci HILOGI("load nandlife sys param success"); 101ba5c3796Sopenharmony_ci 102ba5c3796Sopenharmony_ci PrintNandLifeParam(); 103ba5c3796Sopenharmony_ci 104ba5c3796Sopenharmony_ci if (IsSwapOutClosedPermently()) { 105ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("swap-out has benn closed permently, nandlife controller no need work!"); 106ba5c3796Sopenharmony_ci return false; 107ba5c3796Sopenharmony_ci } 108ba5c3796Sopenharmony_ci 109ba5c3796Sopenharmony_ci unsigned long long swapOutKBSinceKernelBoot = 0; 110ba5c3796Sopenharmony_ci if (GetSwapOutKBSinceKernelBoot(swapOutKBSinceKernelBoot)) { 111ba5c3796Sopenharmony_ci HILOGI("swapOutKBSinceKernelBoot=%{public}llu KB", swapOutKBSinceKernelBoot); 112ba5c3796Sopenharmony_ci lastSwapOutKB_ = swapOutKBSinceKernelBoot; 113ba5c3796Sopenharmony_ci nowSwapOutKB_ = swapOutKBSinceKernelBoot; 114ba5c3796Sopenharmony_ci } else { 115ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("invalid swapOutKBSinceKernelBoot"); 116ba5c3796Sopenharmony_ci return false; 117ba5c3796Sopenharmony_ci } 118ba5c3796Sopenharmony_ci 119ba5c3796Sopenharmony_ci // start check loop 120ba5c3796Sopenharmony_ci SetTimer(); 121ba5c3796Sopenharmony_ci 122ba5c3796Sopenharmony_ci // check limit 123ba5c3796Sopenharmony_ci if (CheckReachedTotalLimit() || CheckReachedDailyLimit()) { 124ba5c3796Sopenharmony_ci return false; 125ba5c3796Sopenharmony_ci } 126ba5c3796Sopenharmony_ci 127ba5c3796Sopenharmony_ci OpenSwapOutTemporarily("pass all check when init"); 128ba5c3796Sopenharmony_ci return true; 129ba5c3796Sopenharmony_ci} 130ba5c3796Sopenharmony_ci 131ba5c3796Sopenharmony_ci// may throw exception due to number format 132ba5c3796Sopenharmony_ciunsigned long long ReadUnsignedLongLongParam(const std::string ¶mName) 133ba5c3796Sopenharmony_ci{ 134ba5c3796Sopenharmony_ci std::string value = system::GetParameter(paramName, PARAM_VALUE_UNKOWN); 135ba5c3796Sopenharmony_ci if (value == PARAM_VALUE_UNKOWN) { 136ba5c3796Sopenharmony_ci HILOGI("param <%{public}s> not set", paramName.c_str()); 137ba5c3796Sopenharmony_ci } 138ba5c3796Sopenharmony_ci return std::strtoull(value.c_str(), nullptr, 10); // 10:Decimal 139ba5c3796Sopenharmony_ci} 140ba5c3796Sopenharmony_ci 141ba5c3796Sopenharmony_cibool NandLifeController::LoadNandLifeParam() 142ba5c3796Sopenharmony_ci{ 143ba5c3796Sopenharmony_ci minsToday_ = ReadUnsignedLongLongParam(MINS_TODAY_PARAM); 144ba5c3796Sopenharmony_ci if (errno == ERANGE || minsToday_ == ULLONG_MAX) { 145ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] invalid value of minsToday_", iter_); 146ba5c3796Sopenharmony_ci return false; 147ba5c3796Sopenharmony_ci } else { 148ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] minsToday_=%{public}llu", iter_, minsToday_); 149ba5c3796Sopenharmony_ci } 150ba5c3796Sopenharmony_ci 151ba5c3796Sopenharmony_ci swapOutKBToday_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_TODAY_PARAM); 152ba5c3796Sopenharmony_ci if (errno == ERANGE || swapOutKBToday_ == ULLONG_MAX) { 153ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] invalid value of swapOutKBToday_", iter_); 154ba5c3796Sopenharmony_ci return false; 155ba5c3796Sopenharmony_ci } else { 156ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] swapOutKBToday_=%{public}llu", iter_, swapOutKBToday_); 157ba5c3796Sopenharmony_ci } 158ba5c3796Sopenharmony_ci 159ba5c3796Sopenharmony_ci minsSinceBirth_ = ReadUnsignedLongLongParam(MINS_FROM_BIRTH_PARAM); 160ba5c3796Sopenharmony_ci if (errno == ERANGE || minsSinceBirth_ == ULLONG_MAX) { 161ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] invalid value of minsSinceBirth_", iter_); 162ba5c3796Sopenharmony_ci return false; 163ba5c3796Sopenharmony_ci } else { 164ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] minsSinceBirth_=%{public}llu", iter_, minsSinceBirth_); 165ba5c3796Sopenharmony_ci } 166ba5c3796Sopenharmony_ci 167ba5c3796Sopenharmony_ci swapOutKBSinceBirth_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_FROM_BIRTH_PARAM); 168ba5c3796Sopenharmony_ci if (errno == ERANGE || swapOutKBSinceBirth_ == ULLONG_MAX) { 169ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] invalid value of swapOutKBSinceBirth_", iter_); 170ba5c3796Sopenharmony_ci return false; 171ba5c3796Sopenharmony_ci } else { 172ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] swapOutKBSinceBirth_=%{public}llu", iter_, swapOutKBSinceBirth_); 173ba5c3796Sopenharmony_ci } 174ba5c3796Sopenharmony_ci 175ba5c3796Sopenharmony_ci return true; 176ba5c3796Sopenharmony_ci} 177ba5c3796Sopenharmony_ci 178ba5c3796Sopenharmony_civoid NandLifeController::PrintNandLifeParam() 179ba5c3796Sopenharmony_ci{ 180ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] begin print nandlife param-------------", iter_); 181ba5c3796Sopenharmony_ci for (auto param : params) { 182ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] %{public}s=%{public}s", iter_, param.c_str(), 183ba5c3796Sopenharmony_ci system::GetParameter(param, PARAM_VALUE_UNKOWN).c_str()); 184ba5c3796Sopenharmony_ci } 185ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] end print nandlife param --------------", iter_); 186ba5c3796Sopenharmony_ci} 187ba5c3796Sopenharmony_ci 188ba5c3796Sopenharmony_cibool NandLifeController::IsSwapOutClosedPermently() 189ba5c3796Sopenharmony_ci{ 190ba5c3796Sopenharmony_ci return system::GetParameter(PERMANENTLY_CLOSED_STATUS_PARAM, PARAM_VALUE_UNKOWN) == PERMANENTLY_CLOSED; 191ba5c3796Sopenharmony_ci} 192ba5c3796Sopenharmony_ci 193ba5c3796Sopenharmony_cibool NandLifeController::GetAndValidateNandLifeConfig() 194ba5c3796Sopenharmony_ci{ 195ba5c3796Sopenharmony_ci config_ = MemmgrConfigManager::GetInstance().GetNandLifeConfig(); 196ba5c3796Sopenharmony_ci return config_.GetDailySwapOutQuotaMb() >= 0 && config_.GetTotalSwapOutQuotaMb() >=0; 197ba5c3796Sopenharmony_ci} 198ba5c3796Sopenharmony_ci 199ba5c3796Sopenharmony_cibool NandLifeController::GetEventHandler() 200ba5c3796Sopenharmony_ci{ 201ba5c3796Sopenharmony_ci if (handler_ == nullptr) { 202ba5c3796Sopenharmony_ci MAKE_POINTER(handler_, shared, AppExecFwk::EventHandler, "failed to create event handler", return false, 203ba5c3796Sopenharmony_ci AppExecFwk::EventRunner::Create()); 204ba5c3796Sopenharmony_ci } 205ba5c3796Sopenharmony_ci return true; 206ba5c3796Sopenharmony_ci} 207ba5c3796Sopenharmony_ci 208ba5c3796Sopenharmony_cibool NandLifeController::GetSwapOutKBSinceKernelBoot(unsigned long long &ret) 209ba5c3796Sopenharmony_ci{ 210ba5c3796Sopenharmony_ci for (auto i = 0; i < RETRY_TIMES; i ++) { 211ba5c3796Sopenharmony_ci if (KernelInterface::GetInstance().ReadSwapOutKBSinceKernelBoot(PSI_HEALTH_INFO_PATH, SWAP_OUT_SIZE_TAG, ret)) { 212ba5c3796Sopenharmony_ci return true; 213ba5c3796Sopenharmony_ci } 214ba5c3796Sopenharmony_ci } 215ba5c3796Sopenharmony_ci return false; 216ba5c3796Sopenharmony_ci} 217ba5c3796Sopenharmony_ci 218ba5c3796Sopenharmony_civoid NandLifeController::SetTimer() 219ba5c3796Sopenharmony_ci{ 220ba5c3796Sopenharmony_ci // set timer and call CheckSwapOut each TIMER_PEROID_MIN min. 221ba5c3796Sopenharmony_ci handler_->PostTask([this] { this->CheckSwapOut(); }, TIMER_PEROID_MS, AppExecFwk::EventQueue::Priority::HIGH); 222ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] set timer after %{public}d mins", iter_, TIMER_PEROID_MIN); 223ba5c3796Sopenharmony_ci} 224ba5c3796Sopenharmony_ci 225ba5c3796Sopenharmony_cibool NandLifeController::CheckReachedDailyLimit() 226ba5c3796Sopenharmony_ci{ 227ba5c3796Sopenharmony_ci bool reachedDailyLimit = swapOutKBToday_ >= DAILY_SWAP_OUT_QUOTA_KB; 228ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] swapOutKBToday_(%{public}llu) %{public}s DAILY_SWAP_OUT_QUOTA_KB(%{public}llu)", 229ba5c3796Sopenharmony_ci iter_, swapOutKBToday_, (reachedDailyLimit ? ">=" : "<"), DAILY_SWAP_OUT_QUOTA_KB); 230ba5c3796Sopenharmony_ci if (reachedDailyLimit) { 231ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("reach daily limit, close swap-out temporarily!"); 232ba5c3796Sopenharmony_ci } else { 233ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] unreach daily limit, swap-out is still opened!", iter_); 234ba5c3796Sopenharmony_ci } 235ba5c3796Sopenharmony_ci return reachedDailyLimit; 236ba5c3796Sopenharmony_ci} 237ba5c3796Sopenharmony_ci 238ba5c3796Sopenharmony_cibool NandLifeController::CheckReachedTotalLimit() 239ba5c3796Sopenharmony_ci{ 240ba5c3796Sopenharmony_ci bool reachedTotalLimit = swapOutKBSinceBirth_ >= TOTAL_SWAP_OUT_QUOTA_KB; 241ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] swapOutKBSinceBirth_(%{public}llu) %{public}s TOTAL_SWAP_OUT_QUOTA_KB(%{public}llu)", 242ba5c3796Sopenharmony_ci iter_, swapOutKBSinceBirth_, (reachedTotalLimit ? ">=" : "<"), TOTAL_SWAP_OUT_QUOTA_KB); 243ba5c3796Sopenharmony_ci if (reachedTotalLimit) { 244ba5c3796Sopenharmony_ci HILOGE("[%{public}llu] reached total limit, close swap-out forever!", iter_); 245ba5c3796Sopenharmony_ci CloseSwapOutPermanently(); 246ba5c3796Sopenharmony_ci } else { 247ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] unreach total limit!", iter_); 248ba5c3796Sopenharmony_ci } 249ba5c3796Sopenharmony_ci return reachedTotalLimit; 250ba5c3796Sopenharmony_ci} 251ba5c3796Sopenharmony_ci 252ba5c3796Sopenharmony_civoid NandLifeController::CheckSwapOut() 253ba5c3796Sopenharmony_ci{ 254ba5c3796Sopenharmony_ci ++iter_; 255ba5c3796Sopenharmony_ci 256ba5c3796Sopenharmony_ci HILOGE("[%{public}llu] called", iter_); 257ba5c3796Sopenharmony_ci 258ba5c3796Sopenharmony_ci if (IsSwapOutClosedPermently()) { 259ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("swap-out has benn closed permently!"); 260ba5c3796Sopenharmony_ci SetTimer(); 261ba5c3796Sopenharmony_ci return; 262ba5c3796Sopenharmony_ci } 263ba5c3796Sopenharmony_ci 264ba5c3796Sopenharmony_ci PrintNandLifeParam(); 265ba5c3796Sopenharmony_ci 266ba5c3796Sopenharmony_ci minsToday_ += TIMER_PEROID_MIN; 267ba5c3796Sopenharmony_ci minsSinceBirth_ += TIMER_PEROID_MIN; 268ba5c3796Sopenharmony_ci 269ba5c3796Sopenharmony_ci if (GetSwapOutKBSinceKernelBoot(nowSwapOutKB_)) { 270ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] swapOutKBSinceKernelBoot=%{public}llu KB", iter_, nowSwapOutKB_); 271ba5c3796Sopenharmony_ci } else { 272ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("invalid swapOutKBSinceKernelBoot"); 273ba5c3796Sopenharmony_ci SetTimer(); 274ba5c3796Sopenharmony_ci return; 275ba5c3796Sopenharmony_ci } 276ba5c3796Sopenharmony_ci if (nowSwapOutKB_ < lastSwapOutKB_) { 277ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("deltaSwapOutMB < 0"); 278ba5c3796Sopenharmony_ci SetTimer(); 279ba5c3796Sopenharmony_ci return; 280ba5c3796Sopenharmony_ci } 281ba5c3796Sopenharmony_ci unsigned long long increasedSwapOutKB = nowSwapOutKB_ - lastSwapOutKB_; 282ba5c3796Sopenharmony_ci HILOGE("[%{public}llu] lastSwapOutKB_=%{public}llu, nowSwapOutKB_=%{public}llu, increasedSwapOutKB=%{public}llu", 283ba5c3796Sopenharmony_ci iter_, lastSwapOutKB_, nowSwapOutKB_, increasedSwapOutKB); 284ba5c3796Sopenharmony_ci lastSwapOutKB_ = nowSwapOutKB_; 285ba5c3796Sopenharmony_ci swapOutKBToday_ += increasedSwapOutKB; 286ba5c3796Sopenharmony_ci swapOutKBSinceBirth_ += increasedSwapOutKB; 287ba5c3796Sopenharmony_ci 288ba5c3796Sopenharmony_ci CheckReachedDailyLimit(); 289ba5c3796Sopenharmony_ci 290ba5c3796Sopenharmony_ci if (minsToday_ >= 24 * 60) { // 24: a day has 24 hours, 60: one hour has 60 min 291ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] enter a new day", iter_); 292ba5c3796Sopenharmony_ci minsToday_ = 0; 293ba5c3796Sopenharmony_ci swapOutKBToday_ = 0; 294ba5c3796Sopenharmony_ci if (swapOutKBSinceBirth_ < TOTAL_SWAP_OUT_QUOTA_KB) { // swap-out is allowed 295ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] open swap-out since a new day", iter_); 296ba5c3796Sopenharmony_ci OpenSwapOutTemporarily("enter a new day"); 297ba5c3796Sopenharmony_ci } 298ba5c3796Sopenharmony_ci } 299ba5c3796Sopenharmony_ci 300ba5c3796Sopenharmony_ci if (!UpdateNandLifeParam()) { 301ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("UpdateNandLifeParam failed!"); 302ba5c3796Sopenharmony_ci } 303ba5c3796Sopenharmony_ci 304ba5c3796Sopenharmony_ci PrintNandLifeParam(); 305ba5c3796Sopenharmony_ci 306ba5c3796Sopenharmony_ci CheckReachedTotalLimit(); 307ba5c3796Sopenharmony_ci 308ba5c3796Sopenharmony_ci // set next timer 309ba5c3796Sopenharmony_ci SetTimer(); 310ba5c3796Sopenharmony_ci} 311ba5c3796Sopenharmony_ci 312ba5c3796Sopenharmony_cibool NandLifeController::SetParameterRetry(const std::string ¶mName, const std::string ¶mValue, int retryTimes) 313ba5c3796Sopenharmony_ci{ 314ba5c3796Sopenharmony_ci for (auto i = 0; i < retryTimes; i++) { 315ba5c3796Sopenharmony_ci if (system::SetParameter(paramName, paramValue)) { 316ba5c3796Sopenharmony_ci return true; 317ba5c3796Sopenharmony_ci } 318ba5c3796Sopenharmony_ci } 319ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] set [%{public}s] to [%{public}s] failed!", iter_, paramName.c_str(), paramValue.c_str()); 320ba5c3796Sopenharmony_ci return false; 321ba5c3796Sopenharmony_ci} 322ba5c3796Sopenharmony_ci 323ba5c3796Sopenharmony_cibool NandLifeController::UpdateNandLifeParam() 324ba5c3796Sopenharmony_ci{ 325ba5c3796Sopenharmony_ci if (!SetParameterRetry(MINS_TODAY_PARAM, std::to_string(minsToday_), RETRY_TIMES)) { 326ba5c3796Sopenharmony_ci return false; 327ba5c3796Sopenharmony_ci } 328ba5c3796Sopenharmony_ci if (!SetParameterRetry(SWAP_OUT_KB_TODAY_PARAM, std::to_string(swapOutKBToday_), RETRY_TIMES)) { 329ba5c3796Sopenharmony_ci return false; 330ba5c3796Sopenharmony_ci } 331ba5c3796Sopenharmony_ci if (!SetParameterRetry(MINS_FROM_BIRTH_PARAM, std::to_string(minsSinceBirth_), RETRY_TIMES)) { 332ba5c3796Sopenharmony_ci return false; 333ba5c3796Sopenharmony_ci } 334ba5c3796Sopenharmony_ci if (!SetParameterRetry(SWAP_OUT_KB_FROM_BIRTH_PARAM, std::to_string(swapOutKBSinceBirth_), RETRY_TIMES)) { 335ba5c3796Sopenharmony_ci return false; 336ba5c3796Sopenharmony_ci } 337ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] all success!", iter_); 338ba5c3796Sopenharmony_ci return true; 339ba5c3796Sopenharmony_ci} 340ba5c3796Sopenharmony_ci 341ba5c3796Sopenharmony_civoid NandLifeController::OpenSwapOutTemporarily(const std::string &reason) 342ba5c3796Sopenharmony_ci{ 343ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] %{public}s", iter_, reason.c_str()); 344ba5c3796Sopenharmony_ci for (auto i = 0; i < RETRY_TIMES; i++) { 345ba5c3796Sopenharmony_ci if (KernelInterface::GetInstance().EchoToPath(ESWAP_ENABLE_PATH.c_str(), ENABLE_ESWAP.c_str())) { 346ba5c3796Sopenharmony_ci HILOGI("[%{public}llu] open eswap temporarily success!", iter_); 347ba5c3796Sopenharmony_ci return; 348ba5c3796Sopenharmony_ci } 349ba5c3796Sopenharmony_ci } 350ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] open eswap temporarily failed!", iter_); 351ba5c3796Sopenharmony_ci} 352ba5c3796Sopenharmony_ci 353ba5c3796Sopenharmony_civoid NandLifeController::CloseSwapOutTemporarily(const std::string &reason) 354ba5c3796Sopenharmony_ci{ 355ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] %{public}s", iter_, reason.c_str()); 356ba5c3796Sopenharmony_ci for (auto i = 0; i < RETRY_TIMES; i++) { 357ba5c3796Sopenharmony_ci if (KernelInterface::GetInstance().EchoToPath(ESWAP_ENABLE_PATH.c_str(), DISABLE_ESWAP.c_str())) { 358ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] clsoe eswap temporarily success!", iter_); 359ba5c3796Sopenharmony_ci return; 360ba5c3796Sopenharmony_ci } 361ba5c3796Sopenharmony_ci } 362ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] close eswap temporarily failed!", iter_); 363ba5c3796Sopenharmony_ci} 364ba5c3796Sopenharmony_ci 365ba5c3796Sopenharmony_civoid NandLifeController::OpenSwapOutPermanently() 366ba5c3796Sopenharmony_ci{ 367ba5c3796Sopenharmony_ci bool ret = SetParameterRetry(PERMANENTLY_CLOSED_STATUS_PARAM, NOT_PERMANENTLY_CLOSED, RETRY_TIMES); 368ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] open eswap permanently %{public}s!", iter_, ret ? "success" : "failed"); 369ba5c3796Sopenharmony_ci} 370ba5c3796Sopenharmony_ci 371ba5c3796Sopenharmony_civoid NandLifeController::CloseSwapOutPermanently() 372ba5c3796Sopenharmony_ci{ 373ba5c3796Sopenharmony_ci CloseSwapOutTemporarily("CloseSwapOutPermanently close eswap temporarily first!"); 374ba5c3796Sopenharmony_ci bool ret = SetParameterRetry(PERMANENTLY_CLOSED_STATUS_PARAM, PERMANENTLY_CLOSED, RETRY_TIMES); 375ba5c3796Sopenharmony_ci HILOGW("[%{public}llu] close eswap permanently %{public}s!", iter_, ret ? "success" : "failed"); 376ba5c3796Sopenharmony_ci} 377ba5c3796Sopenharmony_ci} // namespace Memory 378ba5c3796Sopenharmony_ci} // namespace OHOS 379