From a7bec3ebbc7cb4e86f2eea9b4b7e4610362c3c5c Mon Sep 17 00:00:00 2001 From: ChenJie Date: Mon, 20 Jun 2022 22:30:37 +0800 Subject: [PATCH 1/8] feat: add nandlife controller Signed-off-by: ChenJie --- README_zh.md | 8 + bundle.json | 6 +- common/include/kernel_interface.h | 1 + common/include/memmgr_config_manager.h | 11 +- common/src/kernel_interface.cpp | 57 +++ common/src/memmgr_config_manager.cpp | 52 +++ profile/BUILD.gn | 7 + profile/memmgr.para | 18 + profile/memmgr_config.xml | 4 + services/memmgrservice/BUILD.gn | 3 + .../nandlife_controller/nandlife_controller.h | 71 ++++ .../memmgrservice/src/mem_mgr_service.cpp | 4 + .../nandlife_controller.cpp | 356 ++++++++++++++++++ test/BUILD.gn | 17 + .../phone/nandlife_controller_test.cpp | 61 +++ 15 files changed, 673 insertions(+), 3 deletions(-) create mode 100644 profile/memmgr.para create mode 100644 services/memmgrservice/include/nandlife_controller/nandlife_controller.h create mode 100644 services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp create mode 100644 test/unittest/phone/nandlife_controller_test.cpp diff --git a/README_zh.md b/README_zh.md index 3fe893f..6399ac7 100644 --- a/README_zh.md +++ b/README_zh.md @@ -140,6 +140,10 @@ xml样例: + + 50 + 199 + 功能参考: @@ -180,6 +184,10 @@ Memmgr Memmgr相关配置 0<=ub_zram2ufs_ratio<=100 0<=refault_threshold<=100 killConfig: 内存查杀相关配置 + nandlife: 寿命管控相关配置 + dailySwapOutQuotaMB:每日换出量限制(单位MB),应为正数 + totalSwapOutQuotaMB:总换出量限制(单位MB),应为正数 + 两者同时设为0,代表放开换出量限制。厂商可根据器件容量等规格参数,设置合适的值。 ## 相关仓 diff --git a/bundle.json b/bundle.json index 0c1df2d..6573b16 100644 --- a/bundle.json +++ b/bundle.json @@ -29,7 +29,8 @@ "libhisysevent", "libaccountkits", "os_account_innerkits", - "bgtaskmgr_innerkits" + "bgtaskmgr_innerkits", + "syspara" ], "third_party": [] }, @@ -38,7 +39,8 @@ "//foundation/resourceschedule/memmgr/sa_profile:memmgr_sa_profile", "//foundation/resourceschedule/memmgr/services/memmgrservice:memmgrservice", "//foundation/resourceschedule/memmgr/services/memmgrservice:memmgrservice_init", - "//foundation/resourceschedule/memmgr/profile:memmgr_config" + "//foundation/resourceschedule/memmgr/profile:memmgr_config", + "//foundation/resourceschedule/memmgr/profile:memmgr.para" ], "inner_kits": [ { diff --git a/common/include/kernel_interface.h b/common/include/kernel_interface.h index 8e56f5e..3f3a895 100644 --- a/common/include/kernel_interface.h +++ b/common/include/kernel_interface.h @@ -73,6 +73,7 @@ public: int KillOneProcessByPid(int pid); bool GetAllProcPids(std::vector& pids); bool GetUidByPid(unsigned int pid, unsigned int& uid); + bool ReadSwapOutKBSinceKernelBoot(const std::string &path, const std::string &tagStr, unsigned long long &ret); static const std::string ROOT_PROC_PATH; static const std::string MEMCG_BASE_PATH; diff --git a/common/include/memmgr_config_manager.h b/common/include/memmgr_config_manager.h index 73d48c8..616951a 100644 --- a/common/include/memmgr_config_manager.h +++ b/common/include/memmgr_config_manager.h @@ -54,6 +54,12 @@ public: std::set killalbeSystemApps_; }; +class NandLifeConfig { +public: + int DAILY_SWAP_OUT_QUOTA_MB; + int TOTAL_SWAP_OUT_QUOTA_MB; +}; + class ReclaimRatiosConfig { public: int minScore; @@ -89,7 +95,8 @@ public: std::shared_ptr GetSystemMemoryLevelConfig(); const ReclaimRatiosConfigSet GetReclaimRatiosConfigSet(); const ReclaimPriorityConfig& GetReclaimPriorityConfig(); - const KillLevelsMap& GetKillLevelsMap(); + const KillLevelsMap& GetKillLevelsMap(); + const NandLifeConfig& GetNandLifeConfig(); private: void InitDefaultConfig(); @@ -100,6 +107,7 @@ private: bool ParseSystemMemoryLevelConfig(const xmlNodePtr &rootNodePtr); bool ParseReclaimPriorityConfig(const xmlNodePtr &rootNodePtr); bool ParseReclaimPriorityKillableSystemAppsConfig(const xmlNodePtr &rootNodePtr); + bool ParseNandLifeConfig(const xmlNodePtr &rootNodePtr); bool GetModuleParam(const xmlNodePtr &currNodePtr, std::map ¶m); void SetIntParam(std::map ¶m, std::string key, int &dst); void SetUnsignedIntParam(std::map ¶m, std::string key, unsigned int &dst); @@ -116,6 +124,7 @@ private: KillLevelsMap killLevelsMap_; ReclaimRatiosConfigSet reclaimRatiosConfigSet_; ReclaimPriorityConfig reclaimPriorityConfig_; + NandLifeConfig nandLifeConfig_; void AddReclaimRatiosConfigToSet(std::shared_ptr reclaimRatiosConfig); void ClearReclaimRatiosConfigSet(); MemmgrConfigManager(); diff --git a/common/src/kernel_interface.cpp b/common/src/kernel_interface.cpp index cedb742..faea484 100644 --- a/common/src/kernel_interface.cpp +++ b/common/src/kernel_interface.cpp @@ -382,5 +382,62 @@ bool KernelInterface::GetUidByPid(unsigned int pid, unsigned int& uid) } return true; } + +bool KernelInterface::ReadSwapOutKBSinceKernelBoot(const std::string &path, const std::string &tagStr, + unsigned long long &ret) +{ + std::string contentStr; + if (!ReadFromFile(path, contentStr)) { + return false; + } + char *contentPtr = new char[contentStr.size() + 1]; + if (contentPtr == nullptr) { + HILOGE("alloc buffer fail"); + return false; + } + if (strcpy_s(contentPtr, contentStr.size() + 1, contentStr.c_str()) != EOK) { + HILOGE("copy fail"); + return false; + } + char *restPtr; + char *line = strtok_r(contentPtr, "\n", &restPtr); + do { + std::string lineStr(line); + + size_t i = 0; + for (; i < strlen(line); i++) { + if (line[i] == ':') { + break; + } + } + if (i >= strlen(line) - 2) { // 2: no : in the line or : is at end of line + line = strtok_r(NULL, "\n", &restPtr); + continue; + } + std::string tag = lineStr.substr(0, i); + if (tag == tagStr) { + std::string value = lineStr.substr(i + 1); + std::istringstream iss(value); + std::string sizeStr, unitStr; + iss >> sizeStr >> unitStr; + try { + ret = std::strtoull(sizeStr.c_str(), nullptr, 10); // 10:Decimal + return true; + } catch (...) { + HILOGE("parse [%{public}s] to unsigned long long error!", sizeStr.c_str()); + return false; + } + } + + line = strtok_r(NULL, "\n", &restPtr); + } while (line); + if (restPtr) { + delete [] restPtr; + } + if (contentPtr) { + delete [] contentPtr; + } + return false; +} } // namespace Memory } // namespace OHOS diff --git a/common/src/memmgr_config_manager.cpp b/common/src/memmgr_config_manager.cpp index 7a7880d..4ccd314 100644 --- a/common/src/memmgr_config_manager.cpp +++ b/common/src/memmgr_config_manager.cpp @@ -136,12 +136,64 @@ bool MemmgrConfigManager::ParseXmlRootNode(const xmlNodePtr &rootNodePtr) ParseReclaimPriorityConfig(currNode); continue; } + if (name.compare("nandlife") == 0) { + ParseNandLifeConfig(currNode); + continue; + } HILOGW("unknown node :<%{public}s>", name.c_str()); return false; } return true; } +const NandLifeConfig &MemmgrConfigManager::GetNandLifeConfig() +{ + return nandLifeConfig_; +} + +bool ParseUnsignedLongLongContent(const xmlNodePtr &rootNodePtr, unsigned long long &value) +{ + try { + auto contentPtr = xmlNodeGetContent(rootNodePtr); + std::string valueStr; + if (contentPtr != nullptr) { + valueStr = std::string(reinterpret_cast(contentPtr)); + xmlFree(contentPtr); + value = std::strtoull(valueStr.c_str(), NULL, 10); // 10:Decimal + return true; + } + } catch (...) { + return false; + } + return false; +} + +bool MemmgrConfigManager::ParseNandLifeConfig(const xmlNodePtr &rootNodePtr) +{ + if (!CheckNode(rootNodePtr) || !HasChild(rootNodePtr)) { + return true; + } + for (xmlNodePtr currNode = rootNodePtr->xmlChildrenNode; currNode != nullptr; currNode = currNode->next) { + std::string key = std::string(reinterpret_cast(currNode->name)); + if (key == "dailySwapOutQuotaMB") { + if (!ParseUnsignedLongLongContent(currNode, nandLifeConfig_.daily_swap_out_quota_mb)) { + HILOGE("parse key :<%{public}s> error", key.c_str()); + return false; + } + HILOGI("daily_swap_out_quota_mb=%{public}llu", nandLifeConfig_.daily_swap_out_quota_mb); + } else if (key == "totalSwapOutQuotaMB") { + if (!ParseUnsignedLongLongContent(currNode, nandLifeConfig_.total_swap_out_quota_mb)) { + HILOGE("parse key :<%{public}s> error", key.c_str()); + return false; + } + HILOGI("total_swap_out_quota_mb=%{public}llu", nandLifeConfig_.total_swap_out_quota_mb); + } else { + HILOGW("unknown key :<%{public}s>", key.c_str()); + } + } + return true; +} + const ReclaimPriorityConfig& MemmgrConfigManager::GetReclaimPriorityConfig() { return reclaimPriorityConfig_; diff --git a/profile/BUILD.gn b/profile/BUILD.gn index e480f64..63b3116 100644 --- a/profile/BUILD.gn +++ b/profile/BUILD.gn @@ -20,3 +20,10 @@ ohos_prebuilt_etc("memmgr_config") { part_name = "${memmgr_part_name}" module_install_dir = "etc/memmgr" } + +ohos_prebuilt_etc("memmgr.para") { + source = "memmgr.para" + subsystem_name = "${memmgr_subsystem_name}" + part_name = "${memmgr_part_name}" + module_install_dir = "etc/param" +} diff --git a/profile/memmgr.para b/profile/memmgr.para new file mode 100644 index 0000000..d0b4a9a --- /dev/null +++ b/profile/memmgr.para @@ -0,0 +1,18 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +persist.sys.eswap.permanently.closed=0 +persist.sys.eswap.minsToday=0 +persist.sys.eswap.swapOutKBToday=0 +persist.sys.eswap.minsFromBirth=0 +persist.sys.eswap.swapOutKBFromBirth=0 \ No newline at end of file diff --git a/profile/memmgr_config.xml b/profile/memmgr_config.xml index 4143570..b69fb4f 100644 --- a/profile/memmgr_config.xml +++ b/profile/memmgr_config.xml @@ -47,4 +47,8 @@ 0 + + 0 + 0 + diff --git a/services/memmgrservice/BUILD.gn b/services/memmgrservice/BUILD.gn index 4c780eb..f1a89fe 100644 --- a/services/memmgrservice/BUILD.gn +++ b/services/memmgrservice/BUILD.gn @@ -36,6 +36,7 @@ config("memory_memmgr_config") { "${memgr_innerkits_path}/include", "include/event/", "include/memory_level_manager/", + "include/nandlife_controller", "include/reclaim_priority_manager/", "include/kill_strategy_manager/", "include/reclaim_strategy_manager/", @@ -62,6 +63,7 @@ ohos_shared_library("memmgrservice") { "src/mem_mgr_service.cpp", "src/mem_mgr_stub.cpp", "src/memory_level_manager/memory_level_manager.cpp", + "src/nandlife_controller/nandlife_controller.cpp", "src/reclaim_priority_manager/account_bundle_info.cpp", "src/reclaim_priority_manager/account_priority_info.cpp", "src/reclaim_priority_manager/bundle_priority_info.cpp", @@ -97,6 +99,7 @@ ohos_shared_library("memmgrservice") { "os_account:os_account_innerkits", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", + "startup_l2:syspara", ] part_name = "${memmgr_part_name}" diff --git a/services/memmgrservice/include/nandlife_controller/nandlife_controller.h b/services/memmgrservice/include/nandlife_controller/nandlife_controller.h new file mode 100644 index 0000000..97d0b5f --- /dev/null +++ b/services/memmgrservice/include/nandlife_controller/nandlife_controller.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_MEMORY_MEMMGR_NANDLIFE_CONTROLLER_H +#define OHOS_MEMORY_MEMMGR_NANDLIFE_CONTROLLER_H + +#include "single_instance.h" +#include "event_handler.h" +#include "memmgr_config_manager.h" + +namespace OHOS { +namespace Memory { +class NandLifeController { + DECLARE_SINGLE_INSTANCE_BASE(NandLifeController); + +public: + bool Init(); +private: + std::shared_ptr handler_; + NandLifeConfig config_; + std::function timerFunc_; + + unsigned long long DAILY_SWAP_OUT_QUOTA_KB; + unsigned long long TOTAL_SWAP_OUT_QUOTA_KB; + + unsigned long long lastSwapOutKB_ = 0; + unsigned long long nowSwapOutKB_ = 0; + + unsigned long long minsToday_ = 0; + unsigned long long swapOutKBToday_ = 0; + + unsigned long long minsSinceBirth_ = 0; + unsigned long long swapOutKBSinceBirth_ = 0; + + unsigned long long iter = 0; + + NandLifeController(); + bool GetEventHandler(); + bool IsNandLifeParamExist(); + void PrintNandLifeParam(); + bool LoadNandLifeParam(); + bool IsSwapOutClosedPermently(); + bool GetAndValidateNandLifeConfig(); + void SetTimer(); + void CheckSwapOut(); + bool GetSwapOutKBSinceKernelBoot(unsigned long long &ret); + bool CheckDailyLimit(); + bool CheckTotalLimit(); + bool SetParameterRetry(const std::string ¶mName, const std::string ¶mValue, int retryTimes); + bool UpdateNandLifeParam(); + + void OpenSwapOutTemporarily(); + void CloseSwapOutTemporarily(const std::string &reason); + void OpenSwapOutPermanently(); + void CloseSwapOutPermanently(); +}; +} // namespace Memory +} // namespace OHOS +#endif // OHOS_MEMORY_MEMMGR_NANDLIFE_CONTROLLER_H diff --git a/services/memmgrservice/src/mem_mgr_service.cpp b/services/memmgrservice/src/mem_mgr_service.cpp index e858662..67381c5 100644 --- a/services/memmgrservice/src/mem_mgr_service.cpp +++ b/services/memmgrservice/src/mem_mgr_service.cpp @@ -18,6 +18,7 @@ #include "system_ability_definition.h" #include "memmgr_config_manager.h" #include "mem_mgr_event_center.h" +#include "nandlife_controller.h" #include "reclaim_priority_manager.h" #include "reclaim_strategy_manager.h" #include "multi_account_manager.h" @@ -61,6 +62,9 @@ bool MemMgrService::Init() HILOGE("MemMgrEventCenter init failed"); return false; } + + // init nandlife controller + NandLifeController::GetInstance().Init(); HILOGI("init successed"); return true; } diff --git a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp new file mode 100644 index 0000000..9c8aa72 --- /dev/null +++ b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "memmgr_log.h" +#include "memmgr_ptr_util.h" +#include "parameters.h" +#include "kernel_interface.h" +#include "nandlife_controller.h" + +namespace OHOS { +namespace Memory { +namespace { +const std::string TAG = "NandLifeController"; +const int TIMER_PEROID_MIN = 15; +const int TIMER_PEROID_MS = TIMER_PEROID_MIN * 60 * 1000; + +const std::string PARAM_VALUE_ZERO = "0"; +const std::string PARAM_VALUE_ONE = "1"; +const std::string PARAM_VALUE_UNKOWN = "--"; + +const std::string PERMANENTLY_CLOSED_STATUS_PARAM = "persist.sys.eswap.permanently.closed"; +const std::string PERMANENTLY_CLOSED = PARAM_VALUE_ONE; +const std::string NOT_PERMANENTLY_CLOSED = PARAM_VALUE_ZERO; + +const std::string MINS_TODAY_PARAM = "persist.sys.eswap.minsToday"; + +const std::string SWAP_OUT_KB_TODAY_PARAM = "persist.sys.eswap.swapOutKBToday"; + +const std::string MINS_FROM_BIRTH_PARAM = "persist.sys.eswap.minsFromBirth"; + +const std::string SWAP_OUT_KB_FROM_BIRTH_PARAM = "persist.sys.eswap.swapOutKBFromBirth"; + +const std::string params[] = { + PERMANENTLY_CLOSED_STATUS_PARAM, + MINS_TODAY_PARAM, + SWAP_OUT_KB_TODAY_PARAM, + MINS_FROM_BIRTH_PARAM, + SWAP_OUT_KB_FROM_BIRTH_PARAM, +}; + +const std::string PSI_HEALTH_INFO_PATH = "/dev/memcg/memory.psi_health_info"; +const std::string SWAP_OUT_SIZE_TAG = "Total Swapout Size"; + +const std::string ESWAP_ENABLE_PATH = "/proc/sys/kernel/hyperhold/enable"; +const std::string ENABLE_ESWAP = "enable"; +const std::string DISABLE_ESWAP = "disable"; + +const int RETRY_TIMES = 3; +} + +IMPLEMENT_SINGLE_INSTANCE(NandLifeController); + +NandLifeController::NandLifeController() +{ + timerFunc_ = std::bind(&NandLifeController::CheckSwapOut, this); +} + +bool NandLifeController::Init() +{ + HILOGE("called"); + if (!GetEventHandler()) { + CloseSwapOutTemporarily("init handler failed, nandlife controller cannot set timmer"); + return false; + } + HILOGI("init handler successed"); + + if (!LoadNandLifeParam()) { + CloseSwapOutTemporarily("load nandlife info file failed, controller will not work properly."); + return false; + } + + PrintNandLifeParam(); + + if (IsSwapOutClosedPermently()) { + CloseSwapOutTemporarily("swap-out has benn closed permently, nandlife controller no need work!"); + return false; + } + + // read nandlife config from xml, then check and set it. + // if the config does not meet the requirements, eswap will be closed temporarily. + if (!GetAndValidateNandLifeConfig()) { + CloseSwapOutTemporarily("get or validate nandlife config failed, controller will not work properly."); + return false; + } + HILOGI("get and validate nandlife config success. dailyQuotaMB=%{public}d, totalQuotaMB=%{public}d", + config_.DAILY_SWAP_OUT_QUOTA_MB, config_.TOTAL_SWAP_OUT_QUOTA_MB); + if (config_.DAILY_SWAP_OUT_QUOTA_MB == 0 && config_.TOTAL_SWAP_OUT_QUOTA_MB == 0) { + HILOGE("will not limit swap-out!"); + OpenSwapOutPermanently(); + OpenSwapOutTemporarily(); + return true; + } else { + DAILY_SWAP_OUT_QUOTA_KB = config_.DAILY_SWAP_OUT_QUOTA_MB * 1024; // 1024: MB to KB + TOTAL_SWAP_OUT_QUOTA_KB = config_.TOTAL_SWAP_OUT_QUOTA_MB * 1024; // 1024: MB to KB + } + + if (CheckTotalLimit()) { + return false; + } + + // check daily limit + CheckDailyLimit(); + + unsigned long long swapOutKBSinceKernelBoot = 0; + if (GetSwapOutKBSinceKernelBoot(swapOutKBSinceKernelBoot)) { + HILOGI("swapOutKBSinceKernelBoot=%{public}llu KB", swapOutKBSinceKernelBoot); + lastSwapOutKB_ = swapOutKBSinceKernelBoot; + nowSwapOutKB_ = swapOutKBSinceKernelBoot; + } else { + CloseSwapOutTemporarily("invalid swapOutKBSinceKernelBoot"); + return false; + } + + HILOGI("pass all check"); + OpenSwapOutTemporarily(); + + SetTimer(); + return true; +} + +// may throw exception due to number format +unsigned long long ReadUnsignedLongLongParam(std::string paramName) +{ + std::string value = system::GetParameter(paramName, PARAM_VALUE_UNKOWN); + if (value == PARAM_VALUE_UNKOWN) { + HILOGI("param <%s> not set", paramName.c_str()); + } + return std::strtoull(value.c_str(), NULL, 10); // 10:Decimal +} + +bool NandLifeController::LoadNandLifeParam() +{ + try { + minsToday_ = ReadUnsignedLongLongParam(MINS_TODAY_PARAM); + swapOutKBToday_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_TODAY_PARAM); + minsSinceBirth_ = ReadUnsignedLongLongParam(MINS_FROM_BIRTH_PARAM); + swapOutKBSinceBirth_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_FROM_BIRTH_PARAM); + } catch (...) { + HILOGE("some error occured!"); + return false; + } + return true; +} + +void NandLifeController::PrintNandLifeParam() +{ + HILOGI("[%{public}llu] begin print nandlife param-------------", iter); + for (auto param : params) { + HILOGI("[%{public}llu] %{public}s=%{public}s", iter, param.c_str(), + system::GetParameter(param, PARAM_VALUE_UNKOWN).c_str()); + } + HILOGI("[%{public}llu] end print nandlife param --------------", iter); +} + +bool NandLifeController::IsSwapOutClosedPermently() +{ + return system::GetParameter(PERMANENTLY_CLOSED_STATUS_PARAM, PARAM_VALUE_UNKOWN) == PERMANENTLY_CLOSED; +} + +bool NandLifeController::GetAndValidateNandLifeConfig() +{ + config_ = MemmgrConfigManager::GetInstance().GetNandLifeConfig(); + return config_.DAILY_SWAP_OUT_QUOTA_MB >= 0 && config_.TOTAL_SWAP_OUT_QUOTA_MB >=0; +} + +bool NandLifeController::GetEventHandler() +{ + if (handler_ == nullptr) { + MAKE_POINTER(handler_, shared, AppExecFwk::EventHandler, "failed to create event handler", return false, + AppExecFwk::EventRunner::Create()); + } + return true; +} + +bool NandLifeController::GetSwapOutKBSinceKernelBoot(unsigned long long &ret) +{ + for (auto i = 0; i < RETRY_TIMES; i ++) { + if (KernelInterface::GetInstance().ReadSwapOutKBSinceKernelBoot(PSI_HEALTH_INFO_PATH, SWAP_OUT_SIZE_TAG, ret)) { + return true; + } + } + return false; +} + +void NandLifeController::SetTimer() +{ + // set timer and call CheckSwapOut each TIMER_PEROID_MIN min. + handler_->PostTask(timerFunc_, TIMER_PEROID_MS, AppExecFwk::EventQueue::Priority::HIGH); + HILOGI("[%{public}llu] set timer after %{public}d mins", iter, TIMER_PEROID_MIN); +} + +bool NandLifeController::CheckDailyLimit() +{ + bool reachedDailyLimit = swapOutKBToday_ >= DAILY_SWAP_OUT_QUOTA_KB; + HILOGI("[%{public}llu] swapOutKBToday_(%{public}llu) %{public}s DAILY_SWAP_OUT_QUOTA_KB(%{public}llu)", + iter, swapOutKBToday_, (reachedDailyLimit ? ">=" : "<"), DAILY_SWAP_OUT_QUOTA_KB); + if (reachedDailyLimit) { + CloseSwapOutTemporarily("reach daily limit, close swap-out temporarily!"); + } else { + HILOGI("[%{public}llu] unreach daily limit, swap-out is stil opened!", iter); + } + return reachedDailyLimit; +} + +bool NandLifeController::CheckTotalLimit() +{ + bool reachedTotalLimit = swapOutKBSinceBirth_ >= TOTAL_SWAP_OUT_QUOTA_KB; + HILOGI("[%{public}llu] swapOutKBSinceBirth_(%{public}llu) %{public}s TOTAL_SWAP_OUT_QUOTA_KB(%{public}llu)", + iter, swapOutKBSinceBirth_, (reachedTotalLimit ? ">=" : "<"), TOTAL_SWAP_OUT_QUOTA_KB); + if (reachedTotalLimit) { + HILOGE("[%{public}llu] reached total limit, close swap-out forever!", iter); + CloseSwapOutPermanently(); + } else { + HILOGI("[%{public}llu] unreach total limit!", iter); + } + return reachedTotalLimit; +} + +void NandLifeController::CheckSwapOut() +{ + ++iter; + + HILOGE("[%{public}llu] called", iter); + + if (IsSwapOutClosedPermently()) { + CloseSwapOutTemporarily("swap-out has benn closed permently, nandlife controller no need work!"); + return; + } + + PrintNandLifeParam(); + + minsToday_ += TIMER_PEROID_MIN; + minsSinceBirth_ += TIMER_PEROID_MIN; + + if (GetSwapOutKBSinceKernelBoot(nowSwapOutKB_)) { + HILOGI("[%{public}llu] swapOutKBSinceKernelBoot=%{public}llu KB", iter, nowSwapOutKB_); + } else { + CloseSwapOutTemporarily("invalid swapOutKBSinceKernelBoot"); + SetTimer(); + return; + } + if (nowSwapOutKB_ < lastSwapOutKB_) { + CloseSwapOutTemporarily("deltaSwapOutMB < 0"); + SetTimer(); + return; + } + unsigned long long increasedSwapOutKB = nowSwapOutKB_ - lastSwapOutKB_; + HILOGE("[%{public}llu] lastSwapOutKB_=%{public}llu, nowSwapOutKB_=%{public}llu, increasedSwapOutKB=%{public}llu", + iter, lastSwapOutKB_, nowSwapOutKB_, increasedSwapOutKB); + lastSwapOutKB_ = nowSwapOutKB_; + swapOutKBToday_ += increasedSwapOutKB; + swapOutKBSinceBirth_ += increasedSwapOutKB; + + CheckDailyLimit(); + + if (minsToday_ >= 24 * 60) { // 24: a day has 24 hours, 60: one hour has 60 min + HILOGI("[%{public}llu] enter a new day", iter); + minsToday_ = 0; + swapOutKBToday_ = 0; + if (swapOutKBSinceBirth_ < TOTAL_SWAP_OUT_QUOTA_KB) { // swap-out is allowed + OpenSwapOutTemporarily(); + } + } + + if (!UpdateNandLifeParam()) { + CloseSwapOutTemporarily("UpdateNandLifeParam failed!"); + } + + PrintNandLifeParam(); + + if (CheckTotalLimit()) { + return; + } + + // set next timer + SetTimer(); +} + +bool NandLifeController::SetParameterRetry(const std::string ¶mName, const std::string ¶mValue, int retryTimes) +{ + for (auto i = 0; i < retryTimes; i++) { + if (system::SetParameter(paramName, paramValue)) { + return true; + } + } + HILOGW("[%{public}llu] set [%{public}s] to [%{public}s] failed!", iter, paramName.c_str(), paramValue.c_str()); + return false; +} + +bool NandLifeController::UpdateNandLifeParam() +{ + if (!SetParameterRetry(MINS_TODAY_PARAM, std::to_string(minsToday_), RETRY_TIMES)) { + return false; + } + if (!SetParameterRetry(SWAP_OUT_KB_TODAY_PARAM, std::to_string(swapOutKBToday_), RETRY_TIMES)) { + return false; + } + if (!SetParameterRetry(MINS_FROM_BIRTH_PARAM, std::to_string(minsSinceBirth_), RETRY_TIMES)) { + return false; + } + if (!SetParameterRetry(SWAP_OUT_KB_FROM_BIRTH_PARAM, std::to_string(swapOutKBSinceBirth_), RETRY_TIMES)) { + return false; + } + HILOGW("[%{public}llu] all success!", iter); + return true; +} + +void NandLifeController::OpenSwapOutTemporarily() +{ + for (auto i = 0; i < RETRY_TIMES; i++) { + if (KernelInterface::GetInstance().EchoToPath(ESWAP_ENABLE_PATH.c_str(), ENABLE_ESWAP.c_str())) { + HILOGI("[%{public}llu] open eswap temporarily success!", iter); + return; + } + } + HILOGW("[%{public}llu] open eswap temporarily failed!", iter); +} + +void NandLifeController::CloseSwapOutTemporarily(const std::string &reason) +{ + HILOGW("[%{public}llu] %{public}s", iter, reason.c_str()); + for (auto i = 0; i < RETRY_TIMES; i++) { + if (KernelInterface::GetInstance().EchoToPath(ESWAP_ENABLE_PATH.c_str(), DISABLE_ESWAP.c_str())) { + HILOGW("[%{public}llu] clsoe eswap temporarily success!", iter); + return; + } + } + HILOGW("[%{public}llu] close eswap temporarily failed!", iter); +} + +void NandLifeController::OpenSwapOutPermanently() +{ + bool ret = SetParameterRetry(PERMANENTLY_CLOSED_STATUS_PARAM, NOT_PERMANENTLY_CLOSED, RETRY_TIMES); + HILOGW("[%{public}llu] open eswap permanently %{public}s!", iter, ret ? "success" : "failed"); +} + +void NandLifeController::CloseSwapOutPermanently() +{ + CloseSwapOutTemporarily("CloseSwapOutPermanently close eswap temporarily first!"); + bool ret = SetParameterRetry(PERMANENTLY_CLOSED_STATUS_PARAM, PERMANENTLY_CLOSED, RETRY_TIMES); + HILOGW("[%{public}llu] close eswap permanently %{public}s!", iter, ret ? "success" : "failed"); +} +} // namespace Memory +} // namespace OHOS diff --git a/test/BUILD.gn b/test/BUILD.gn index 1952ea3..7cb8940 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -134,6 +134,22 @@ ohos_unittest("multi_account_manager_test") { subsystem_name = "resourceschedule" } +ohos_unittest("nandlife_controller_test") { + module_out_path = module_output_path + configs = memmgr_service_configs + + sources = [ "unittest/phone/nandlife_controller_test.cpp" ] + + deps = memmgr_deps + if (is_standard_system) { + external_deps = memmgr_external_deps + public_deps = memmgr_public_deps + } + + part_name = "memmgr" + subsystem_name = "resourceschedule" +} + ohos_unittest("reclaim_strategy_manager_test") { module_out_path = module_output_path configs = memmgr_service_configs @@ -208,6 +224,7 @@ group("memmgr_unittest") { ":memcg_test", ":memmgr_config_manager_test", ":multi_account_manager_test", + ":nandlife_controller_test", ":reclaim_priority_manager_test", ":reclaim_strategy_manager_test", ":user_memcg_test", diff --git a/test/unittest/phone/nandlife_controller_test.cpp b/test/unittest/phone/nandlife_controller_test.cpp new file mode 100644 index 0000000..e963ee3 --- /dev/null +++ b/test/unittest/phone/nandlife_controller_test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gtest/gtest.h" + +#include "utils.h" + +#define private public +#define protected public +#include "nandlife_controller.h" +#undef private +#undef protected + +namespace OHOS { +namespace Memory { +using namespace testing; +using namespace testing::ext; + +class NandLifeControllerTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void NandLifeControllerTest::SetUpTestCase() +{ +} + +void NandLifeControllerTest::TearDownTestCase() +{ +} + +void NandLifeControllerTest::SetUp() +{ +} + +void NandLifeControllerTest::TearDown() +{ +} + +HWTEST_F(NandLifeControllerTest, GetSwapOutKBSinceKernelBootTest, TestSize.Level1) +{ + unsigned long long swapOutKBSinceKernelBoot = 0; + EXPECT_EQ(NandLifeController::GetInstance().GetSwapOutKBSinceKernelBoot(swapOutKBSinceKernelBoot), true); +} +} // namespace Memory +} // namespace OHOS \ No newline at end of file -- Gitee From c32116a803515f31a5b1ae43df12f4128072beb0 Mon Sep 17 00:00:00 2001 From: ChenJie Date: Tue, 21 Jun 2022 09:19:47 +0800 Subject: [PATCH 2/8] update Signed-off-by: ChenJie --- common/include/memmgr_config_manager.h | 6 +++--- common/src/memmgr_config_manager.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/include/memmgr_config_manager.h b/common/include/memmgr_config_manager.h index 616951a..fc6c4e3 100644 --- a/common/include/memmgr_config_manager.h +++ b/common/include/memmgr_config_manager.h @@ -56,8 +56,8 @@ public: class NandLifeConfig { public: - int DAILY_SWAP_OUT_QUOTA_MB; - int TOTAL_SWAP_OUT_QUOTA_MB; + unsigned long long daily_swap_out_quota_mb; + unsigned long long total_swap_out_quota_mb; }; class ReclaimRatiosConfig { @@ -95,7 +95,7 @@ public: std::shared_ptr GetSystemMemoryLevelConfig(); const ReclaimRatiosConfigSet GetReclaimRatiosConfigSet(); const ReclaimPriorityConfig& GetReclaimPriorityConfig(); - const KillLevelsMap& GetKillLevelsMap(); + const KillLevelsMap& GetKillLevelsMap(); const NandLifeConfig& GetNandLifeConfig(); private: diff --git a/common/src/memmgr_config_manager.cpp b/common/src/memmgr_config_manager.cpp index 4ccd314..ee6ec57 100644 --- a/common/src/memmgr_config_manager.cpp +++ b/common/src/memmgr_config_manager.cpp @@ -159,7 +159,7 @@ bool ParseUnsignedLongLongContent(const xmlNodePtr &rootNodePtr, unsigned long l if (contentPtr != nullptr) { valueStr = std::string(reinterpret_cast(contentPtr)); xmlFree(contentPtr); - value = std::strtoull(valueStr.c_str(), NULL, 10); // 10:Decimal + value = std::strtoull(valueStr.c_str(), nullptr, 10); // 10:Decimal return true; } } catch (...) { -- Gitee From d4293d76f85367aca38cb745824012b1d317c031 Mon Sep 17 00:00:00 2001 From: ChenJie Date: Tue, 21 Jun 2022 09:50:35 +0800 Subject: [PATCH 3/8] update Signed-off-by: ChenJie --- .../nandlife_controller.cpp | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp index 9c8aa72..2c93711 100644 --- a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp +++ b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp @@ -23,8 +23,9 @@ namespace OHOS { namespace Memory { namespace { const std::string TAG = "NandLifeController"; -const int TIMER_PEROID_MIN = 15; -const int TIMER_PEROID_MS = TIMER_PEROID_MIN * 60 * 1000; + +constexpr int TIMER_PEROID_MIN = 15; +constexpr int TIMER_PEROID_MS = TIMER_PEROID_MIN * 60 * 1000; const std::string PARAM_VALUE_ZERO = "0"; const std::string PARAM_VALUE_ONE = "1"; @@ -50,14 +51,14 @@ const std::string params[] = { SWAP_OUT_KB_FROM_BIRTH_PARAM, }; -const std::string PSI_HEALTH_INFO_PATH = "/dev/memcg/memory.psi_health_info"; +const std::string PSI_HEALTH_INFO_PATH = "/dev/memcg/memory.eswap_info"; const std::string SWAP_OUT_SIZE_TAG = "Total Swapout Size"; const std::string ESWAP_ENABLE_PATH = "/proc/sys/kernel/hyperhold/enable"; const std::string ENABLE_ESWAP = "enable"; const std::string DISABLE_ESWAP = "disable"; -const int RETRY_TIMES = 3; +constexpr int RETRY_TIMES = 3; } IMPLEMENT_SINGLE_INSTANCE(NandLifeController); @@ -94,16 +95,16 @@ bool NandLifeController::Init() CloseSwapOutTemporarily("get or validate nandlife config failed, controller will not work properly."); return false; } - HILOGI("get and validate nandlife config success. dailyQuotaMB=%{public}d, totalQuotaMB=%{public}d", - config_.DAILY_SWAP_OUT_QUOTA_MB, config_.TOTAL_SWAP_OUT_QUOTA_MB); - if (config_.DAILY_SWAP_OUT_QUOTA_MB == 0 && config_.TOTAL_SWAP_OUT_QUOTA_MB == 0) { + HILOGI("get and validate nandlife config success. dailyQuotaMB=%{public}llu, totalQuotaMB=%{public}llu", + config_.daily_swap_out_quota_mb, config_.total_swap_out_quota_mb); + if (config_.daily_swap_out_quota_mb == 0 && config_.total_swap_out_quota_mb == 0) { HILOGE("will not limit swap-out!"); OpenSwapOutPermanently(); OpenSwapOutTemporarily(); return true; } else { - DAILY_SWAP_OUT_QUOTA_KB = config_.DAILY_SWAP_OUT_QUOTA_MB * 1024; // 1024: MB to KB - TOTAL_SWAP_OUT_QUOTA_KB = config_.TOTAL_SWAP_OUT_QUOTA_MB * 1024; // 1024: MB to KB + DAILY_SWAP_OUT_QUOTA_KB = config_.daily_swap_out_quota_mb * 1024; // 1024: MB to KB + TOTAL_SWAP_OUT_QUOTA_KB = config_.total_swap_out_quota_mb * 1024; // 1024: MB to KB } if (CheckTotalLimit()) { @@ -172,7 +173,7 @@ bool NandLifeController::IsSwapOutClosedPermently() bool NandLifeController::GetAndValidateNandLifeConfig() { config_ = MemmgrConfigManager::GetInstance().GetNandLifeConfig(); - return config_.DAILY_SWAP_OUT_QUOTA_MB >= 0 && config_.TOTAL_SWAP_OUT_QUOTA_MB >=0; + return config_.daily_swap_out_quota_mb >= 0 && config_.total_swap_out_quota_mb >=0; } bool NandLifeController::GetEventHandler() @@ -265,11 +266,12 @@ void NandLifeController::CheckSwapOut() CheckDailyLimit(); - if (minsToday_ >= 24 * 60) { // 24: a day has 24 hours, 60: one hour has 60 min + if (minsToday_ >= 12 * 60) { // 24: a day has 24 hours, 60: one hour has 60 min HILOGI("[%{public}llu] enter a new day", iter); minsToday_ = 0; swapOutKBToday_ = 0; if (swapOutKBSinceBirth_ < TOTAL_SWAP_OUT_QUOTA_KB) { // swap-out is allowed + HILOGI("[%{public}llu] open swap-out since a new day", iter); OpenSwapOutTemporarily(); } } -- Gitee From 208e4856d4dfac59ed6ddcc492962945c371bd18 Mon Sep 17 00:00:00 2001 From: ChenJie Date: Tue, 21 Jun 2022 10:09:21 +0800 Subject: [PATCH 4/8] update Signed-off-by: ChenJie --- .../src/nandlife_controller/nandlife_controller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp index 2c93711..11c7dec 100644 --- a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp +++ b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp @@ -266,7 +266,7 @@ void NandLifeController::CheckSwapOut() CheckDailyLimit(); - if (minsToday_ >= 12 * 60) { // 24: a day has 24 hours, 60: one hour has 60 min + if (minsToday_ >= 24 * 60) { // 24: a day has 24 hours, 60: one hour has 60 min HILOGI("[%{public}llu] enter a new day", iter); minsToday_ = 0; swapOutKBToday_ = 0; -- Gitee From 74b56f76fbb1fecdbfd9ad0a58119ab84ba33ad7 Mon Sep 17 00:00:00 2001 From: ChenJie Date: Tue, 21 Jun 2022 14:48:00 +0800 Subject: [PATCH 5/8] update Signed-off-by: ChenJie --- .../src/nandlife_controller/nandlife_controller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp index 11c7dec..57d6c0e 100644 --- a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp +++ b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp @@ -236,7 +236,8 @@ void NandLifeController::CheckSwapOut() HILOGE("[%{public}llu] called", iter); if (IsSwapOutClosedPermently()) { - CloseSwapOutTemporarily("swap-out has benn closed permently, nandlife controller no need work!"); + CloseSwapOutTemporarily("swap-out has benn closed permently!"); + SetTimer(); return; } -- Gitee From f46301dd63da4743758d8bab64db2f4a801ea9ea Mon Sep 17 00:00:00 2001 From: ChenJie Date: Wed, 22 Jun 2022 19:04:58 +0800 Subject: [PATCH 6/8] update Signed-off-by: ChenJie --- .../nandlife_controller/nandlife_controller.h | 6 +- .../nandlife_controller.cpp | 103 +++++++++++------- 2 files changed, 69 insertions(+), 40 deletions(-) diff --git a/services/memmgrservice/include/nandlife_controller/nandlife_controller.h b/services/memmgrservice/include/nandlife_controller/nandlife_controller.h index 97d0b5f..b68e8fc 100644 --- a/services/memmgrservice/include/nandlife_controller/nandlife_controller.h +++ b/services/memmgrservice/include/nandlife_controller/nandlife_controller.h @@ -56,12 +56,12 @@ private: void SetTimer(); void CheckSwapOut(); bool GetSwapOutKBSinceKernelBoot(unsigned long long &ret); - bool CheckDailyLimit(); - bool CheckTotalLimit(); + bool CheckReachedDailyLimit(); + bool CheckReachedTotalLimit(); bool SetParameterRetry(const std::string ¶mName, const std::string ¶mValue, int retryTimes); bool UpdateNandLifeParam(); - void OpenSwapOutTemporarily(); + void OpenSwapOutTemporarily(const std::string &reason); void CloseSwapOutTemporarily(const std::string &reason); void OpenSwapOutPermanently(); void CloseSwapOutPermanently(); diff --git a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp index 57d6c0e..dcbd8e9 100644 --- a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp +++ b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp @@ -29,7 +29,7 @@ constexpr int TIMER_PEROID_MS = TIMER_PEROID_MIN * 60 * 1000; const std::string PARAM_VALUE_ZERO = "0"; const std::string PARAM_VALUE_ONE = "1"; -const std::string PARAM_VALUE_UNKOWN = "--"; +const std::string PARAM_VALUE_UNKOWN = "-1"; const std::string PERMANENTLY_CLOSED_STATUS_PARAM = "persist.sys.eswap.permanently.closed"; const std::string PERMANENTLY_CLOSED = PARAM_VALUE_ONE; @@ -77,18 +77,6 @@ bool NandLifeController::Init() } HILOGI("init handler successed"); - if (!LoadNandLifeParam()) { - CloseSwapOutTemporarily("load nandlife info file failed, controller will not work properly."); - return false; - } - - PrintNandLifeParam(); - - if (IsSwapOutClosedPermently()) { - CloseSwapOutTemporarily("swap-out has benn closed permently, nandlife controller no need work!"); - return false; - } - // read nandlife config from xml, then check and set it. // if the config does not meet the requirements, eswap will be closed temporarily. if (!GetAndValidateNandLifeConfig()) { @@ -100,19 +88,25 @@ bool NandLifeController::Init() if (config_.daily_swap_out_quota_mb == 0 && config_.total_swap_out_quota_mb == 0) { HILOGE("will not limit swap-out!"); OpenSwapOutPermanently(); - OpenSwapOutTemporarily(); + OpenSwapOutTemporarily("not limit swap-out in xml"); return true; } else { DAILY_SWAP_OUT_QUOTA_KB = config_.daily_swap_out_quota_mb * 1024; // 1024: MB to KB TOTAL_SWAP_OUT_QUOTA_KB = config_.total_swap_out_quota_mb * 1024; // 1024: MB to KB } - if (CheckTotalLimit()) { + if (!LoadNandLifeParam()) { + CloseSwapOutTemporarily("load nandlife info file failed, controller will not work properly."); return false; } + HILOGI("load nandlife sys param success"); - // check daily limit - CheckDailyLimit(); + PrintNandLifeParam(); + + if (IsSwapOutClosedPermently()) { + CloseSwapOutTemporarily("swap-out has benn closed permently, nandlife controller no need work!"); + return false; + } unsigned long long swapOutKBSinceKernelBoot = 0; if (GetSwapOutKBSinceKernelBoot(swapOutKBSinceKernelBoot)) { @@ -124,34 +118,70 @@ bool NandLifeController::Init() return false; } + // check total limit + if (CheckReachedTotalLimit()) { + SetTimer(); + return false; + } + + // check daily limit + if (CheckReachedDailyLimit()) { + SetTimer(); + return false; + } + HILOGI("pass all check"); - OpenSwapOutTemporarily(); + OpenSwapOutTemporarily("pass all check when init"); SetTimer(); return true; } // may throw exception due to number format -unsigned long long ReadUnsignedLongLongParam(std::string paramName) +unsigned long long ReadUnsignedLongLongParam(const std::string ¶mName) { std::string value = system::GetParameter(paramName, PARAM_VALUE_UNKOWN); if (value == PARAM_VALUE_UNKOWN) { - HILOGI("param <%s> not set", paramName.c_str()); + HILOGI("param <%{public}s> not set", paramName.c_str()); } - return std::strtoull(value.c_str(), NULL, 10); // 10:Decimal + return std::strtoull(value.c_str(), nullptr, 10); // 10:Decimal } bool NandLifeController::LoadNandLifeParam() { - try { - minsToday_ = ReadUnsignedLongLongParam(MINS_TODAY_PARAM); - swapOutKBToday_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_TODAY_PARAM); - minsSinceBirth_ = ReadUnsignedLongLongParam(MINS_FROM_BIRTH_PARAM); - swapOutKBSinceBirth_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_FROM_BIRTH_PARAM); - } catch (...) { - HILOGE("some error occured!"); + minsToday_ = ReadUnsignedLongLongParam(MINS_TODAY_PARAM); + if (errno == ERANGE || minsToday_ == ULLONG_MAX) { + HILOGI("[%{public}llu] invalid value of minsToday_", iter); + return false; + } else { + HILOGI("[%{public}llu] minsToday_=%{public}llu", iter, minsToday_); + } + + + swapOutKBToday_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_TODAY_PARAM); + if (errno == ERANGE || swapOutKBToday_ == ULLONG_MAX) { + HILOGI("[%{public}llu] invalid value of swapOutKBToday_", iter); + return false; + } else { + HILOGI("[%{public}llu] swapOutKBToday_=%{public}llu", iter, swapOutKBToday_); + } + + minsSinceBirth_ = ReadUnsignedLongLongParam(MINS_FROM_BIRTH_PARAM); + if (errno == ERANGE || minsSinceBirth_ == ULLONG_MAX) { + HILOGI("[%{public}llu] invalid value of minsSinceBirth_", iter); + return false; + } else { + HILOGI("[%{public}llu] minsSinceBirth_=%{public}llu", iter, minsSinceBirth_); + } + + swapOutKBSinceBirth_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_FROM_BIRTH_PARAM); + if (errno == ERANGE || swapOutKBSinceBirth_ == ULLONG_MAX) { + HILOGI("[%{public}llu] invalid value of swapOutKBSinceBirth_", iter); return false; + } else { + HILOGI("[%{public}llu] swapOutKBSinceBirth_=%{public}llu", iter, swapOutKBSinceBirth_); } + return true; } @@ -202,7 +232,7 @@ void NandLifeController::SetTimer() HILOGI("[%{public}llu] set timer after %{public}d mins", iter, TIMER_PEROID_MIN); } -bool NandLifeController::CheckDailyLimit() +bool NandLifeController::CheckReachedDailyLimit() { bool reachedDailyLimit = swapOutKBToday_ >= DAILY_SWAP_OUT_QUOTA_KB; HILOGI("[%{public}llu] swapOutKBToday_(%{public}llu) %{public}s DAILY_SWAP_OUT_QUOTA_KB(%{public}llu)", @@ -210,12 +240,12 @@ bool NandLifeController::CheckDailyLimit() if (reachedDailyLimit) { CloseSwapOutTemporarily("reach daily limit, close swap-out temporarily!"); } else { - HILOGI("[%{public}llu] unreach daily limit, swap-out is stil opened!", iter); + HILOGI("[%{public}llu] unreach daily limit, swap-out is still opened!", iter); } return reachedDailyLimit; } -bool NandLifeController::CheckTotalLimit() +bool NandLifeController::CheckReachedTotalLimit() { bool reachedTotalLimit = swapOutKBSinceBirth_ >= TOTAL_SWAP_OUT_QUOTA_KB; HILOGI("[%{public}llu] swapOutKBSinceBirth_(%{public}llu) %{public}s TOTAL_SWAP_OUT_QUOTA_KB(%{public}llu)", @@ -265,7 +295,7 @@ void NandLifeController::CheckSwapOut() swapOutKBToday_ += increasedSwapOutKB; swapOutKBSinceBirth_ += increasedSwapOutKB; - CheckDailyLimit(); + CheckReachedDailyLimit(); if (minsToday_ >= 24 * 60) { // 24: a day has 24 hours, 60: one hour has 60 min HILOGI("[%{public}llu] enter a new day", iter); @@ -273,7 +303,7 @@ void NandLifeController::CheckSwapOut() swapOutKBToday_ = 0; if (swapOutKBSinceBirth_ < TOTAL_SWAP_OUT_QUOTA_KB) { // swap-out is allowed HILOGI("[%{public}llu] open swap-out since a new day", iter); - OpenSwapOutTemporarily(); + OpenSwapOutTemporarily("enter a new day"); } } @@ -283,9 +313,7 @@ void NandLifeController::CheckSwapOut() PrintNandLifeParam(); - if (CheckTotalLimit()) { - return; - } + CheckReachedTotalLimit(); // set next timer SetTimer(); @@ -320,8 +348,9 @@ bool NandLifeController::UpdateNandLifeParam() return true; } -void NandLifeController::OpenSwapOutTemporarily() +void NandLifeController::OpenSwapOutTemporarily(const std::string &reason) { + HILOGW("[%{public}llu] %{public}s", iter, reason.c_str()); for (auto i = 0; i < RETRY_TIMES; i++) { if (KernelInterface::GetInstance().EchoToPath(ESWAP_ENABLE_PATH.c_str(), ENABLE_ESWAP.c_str())) { HILOGI("[%{public}llu] open eswap temporarily success!", iter); -- Gitee From e744c1fe08288810a9c44b7d494b031cf9bd5792 Mon Sep 17 00:00:00 2001 From: ChenJie Date: Wed, 22 Jun 2022 19:10:12 +0800 Subject: [PATCH 7/8] update Signed-off-by: ChenJie --- .../src/nandlife_controller/nandlife_controller.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp index dcbd8e9..f41fdec 100644 --- a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp +++ b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp @@ -77,8 +77,6 @@ bool NandLifeController::Init() } HILOGI("init handler successed"); - // read nandlife config from xml, then check and set it. - // if the config does not meet the requirements, eswap will be closed temporarily. if (!GetAndValidateNandLifeConfig()) { CloseSwapOutTemporarily("get or validate nandlife config failed, controller will not work properly."); return false; @@ -132,7 +130,6 @@ bool NandLifeController::Init() HILOGI("pass all check"); OpenSwapOutTemporarily("pass all check when init"); - SetTimer(); return true; } @@ -157,7 +154,6 @@ bool NandLifeController::LoadNandLifeParam() HILOGI("[%{public}llu] minsToday_=%{public}llu", iter, minsToday_); } - swapOutKBToday_ = ReadUnsignedLongLongParam(SWAP_OUT_KB_TODAY_PARAM); if (errno == ERANGE || swapOutKBToday_ == ULLONG_MAX) { HILOGI("[%{public}llu] invalid value of swapOutKBToday_", iter); -- Gitee From a51f2b3c3a85e2f05162dbf8f5fa10347fab3a2c Mon Sep 17 00:00:00 2001 From: ChenJie Date: Wed, 22 Jun 2022 19:45:07 +0800 Subject: [PATCH 8/8] update Signed-off-by: ChenJie --- .../src/nandlife_controller/nandlife_controller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp index f41fdec..0e553ad 100644 --- a/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp +++ b/services/memmgrservice/src/nandlife_controller/nandlife_controller.cpp @@ -70,13 +70,14 @@ NandLifeController::NandLifeController() bool NandLifeController::Init() { - HILOGE("called"); if (!GetEventHandler()) { CloseSwapOutTemporarily("init handler failed, nandlife controller cannot set timmer"); return false; } HILOGI("init handler successed"); + // read nandlife config from xml, then check and set it. + // if the config does not meet the requirements, eswap will be closed temporarily. if (!GetAndValidateNandLifeConfig()) { CloseSwapOutTemporarily("get or validate nandlife config failed, controller will not work properly."); return false; @@ -128,7 +129,6 @@ bool NandLifeController::Init() return false; } - HILOGI("pass all check"); OpenSwapOutTemporarily("pass all check when init"); SetTimer(); return true; -- Gitee