diff options
| -rw-r--r-- | libprocessgroup/processgroup.cpp | 36 | ||||
| -rw-r--r-- | libprocessgroup/profiles/task_profiles.json | 48 | ||||
| -rw-r--r-- | libprocessgroup/profiles/task_profiles.proto | 9 | ||||
| -rw-r--r-- | libprocessgroup/sched_policy.cpp | 49 | ||||
| -rw-r--r-- | libprocessgroup/task_profiles.cpp | 93 | ||||
| -rw-r--r-- | libprocessgroup/task_profiles.h | 18 |
6 files changed, 173 insertions, 80 deletions
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp index 7c191be1b..7b6dde2fc 100644 --- a/libprocessgroup/processgroup.cpp +++ b/libprocessgroup/processgroup.cpp @@ -117,43 +117,11 @@ void DropTaskProfilesResourceCaching() { bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles, bool use_fd_cache) { - const TaskProfiles& tp = TaskProfiles::GetInstance(); - - for (const auto& name : profiles) { - TaskProfile* profile = tp.GetProfile(name); - if (profile != nullptr) { - if (use_fd_cache) { - profile->EnableResourceCaching(); - } - if (!profile->ExecuteForProcess(uid, pid)) { - PLOG(WARNING) << "Failed to apply " << name << " process profile"; - } - } else { - PLOG(WARNING) << "Failed to find " << name << "process profile"; - } - } - - return true; + return TaskProfiles::GetInstance().SetProcessProfiles(uid, pid, profiles, use_fd_cache); } bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache) { - const TaskProfiles& tp = TaskProfiles::GetInstance(); - - for (const auto& name : profiles) { - TaskProfile* profile = tp.GetProfile(name); - if (profile != nullptr) { - if (use_fd_cache) { - profile->EnableResourceCaching(); - } - if (!profile->ExecuteForTask(tid)) { - PLOG(WARNING) << "Failed to apply " << name << " task profile"; - } - } else { - PLOG(WARNING) << "Failed to find " << name << "task profile"; - } - } - - return true; + return TaskProfiles::GetInstance().SetTaskProfiles(tid, profiles, use_fd_cache); } static std::string ConvertUidToPath(const char* cgroup, uid_t uid) { diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json index 74a39cd1a..608f0071e 100644 --- a/libprocessgroup/profiles/task_profiles.json +++ b/libprocessgroup/profiles/task_profiles.json @@ -15,7 +15,6 @@ "Controller": "cpuset", "File": "top-app/cpus" }, - { "Name": "MemLimit", "Controller": "memory", @@ -494,5 +493,52 @@ } ] } + ], + + "AggregateProfiles": [ + { + "Name": "SCHED_SP_DEFAULT", + "Profiles": [ "TimerSlackNormal" ] + }, + { + "Name": "SCHED_SP_BACKGROUND", + "Profiles": [ "HighEnergySaving", "LowIoPriority", "TimerSlackHigh" ] + }, + { + "Name": "SCHED_SP_FOREGROUND", + "Profiles": [ "HighPerformance", "HighIoPriority", "TimerSlackNormal" ] + }, + { + "Name": "SCHED_SP_TOP_APP", + "Profiles": [ "MaxPerformance", "MaxIoPriority", "TimerSlackNormal" ] + }, + { + "Name": "SCHED_SP_RT_APP", + "Profiles": [ "RealtimePerformance", "MaxIoPriority", "TimerSlackNormal" ] + }, + { + "Name": "CPUSET_SP_DEFAULT", + "Profiles": [ "TimerSlackNormal" ] + }, + { + "Name": "CPUSET_SP_BACKGROUND", + "Profiles": [ "HighEnergySaving", "ProcessCapacityLow", "LowIoPriority", "TimerSlackHigh" ] + }, + { + "Name": "CPUSET_SP_FOREGROUND", + "Profiles": [ "HighPerformance", "ProcessCapacityHigh", "HighIoPriority", "TimerSlackNormal" ] + }, + { + "Name": "CPUSET_SP_TOP_APP", + "Profiles": [ "MaxPerformance", "ProcessCapacityMax", "MaxIoPriority", "TimerSlackNormal" ] + }, + { + "Name": "CPUSET_SP_SYSTEM", + "Profiles": [ "ServiceCapacityLow", "TimerSlackNormal" ] + }, + { + "Name": "CPUSET_SP_RESTRICTED", + "Profiles": [ "ServiceCapacityRestricted", "TimerSlackNormal" ] + } ] } diff --git a/libprocessgroup/profiles/task_profiles.proto b/libprocessgroup/profiles/task_profiles.proto index 578f0d3c1..1de4395e9 100644 --- a/libprocessgroup/profiles/task_profiles.proto +++ b/libprocessgroup/profiles/task_profiles.proto @@ -18,10 +18,11 @@ syntax = "proto3"; package android.profiles; -// Next: 3 +// Next: 4 message TaskProfiles { repeated Attribute attributes = 1 [json_name = "Attributes"]; repeated Profile profiles = 2 [json_name = "Profiles"]; + repeated AggregateProfiles aggregateprofiles = 3 [json_name = "AggregateProfiles"]; } // Next: 4 @@ -42,3 +43,9 @@ message Action { string name = 1 [json_name = "Name"]; map<string, string> params = 2 [json_name = "Params"]; } + +// Next: 3 +message AggregateProfiles { + string name = 1 [json_name = "Name"]; + repeated string profiles = 2 [json_name = "Profiles"]; +} diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp index c83df1aa6..6b0ab87aa 100644 --- a/libprocessgroup/sched_policy.cpp +++ b/libprocessgroup/sched_policy.cpp @@ -46,34 +46,17 @@ int set_cpuset_policy(int tid, SchedPolicy policy) { switch (policy) { case SP_BACKGROUND: - return SetTaskProfiles(tid, - {"HighEnergySaving", "ProcessCapacityLow", "LowIoPriority", - "TimerSlackHigh"}, - true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"CPUSET_SP_BACKGROUND"}, true) ? 0 : -1; case SP_FOREGROUND: case SP_AUDIO_APP: case SP_AUDIO_SYS: - return SetTaskProfiles(tid, - {"HighPerformance", "ProcessCapacityHigh", "HighIoPriority", - "TimerSlackNormal"}, - true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"CPUSET_SP_FOREGROUND"}, true) ? 0 : -1; case SP_TOP_APP: - return SetTaskProfiles(tid, - {"MaxPerformance", "ProcessCapacityMax", "MaxIoPriority", - "TimerSlackNormal"}, - true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"CPUSET_SP_TOP_APP"}, true) ? 0 : -1; case SP_SYSTEM: - return SetTaskProfiles(tid, {"ServiceCapacityLow", "TimerSlackNormal"}, true) ? 0 : -1; + return SetTaskProfiles(tid, {"CPUSET_SP_SYSTEM"}, true) ? 0 : -1; case SP_RESTRICTED: - return SetTaskProfiles(tid, {"ServiceCapacityRestricted", "TimerSlackNormal"}, true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"CPUSET_SP_RESTRICTED"}, true) ? 0 : -1; default: break; } @@ -134,29 +117,17 @@ int set_sched_policy(int tid, SchedPolicy policy) { switch (policy) { case SP_BACKGROUND: - return SetTaskProfiles(tid, {"HighEnergySaving", "LowIoPriority", "TimerSlackHigh"}, - true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND"}, true) ? 0 : -1; case SP_FOREGROUND: case SP_AUDIO_APP: case SP_AUDIO_SYS: - return SetTaskProfiles(tid, {"HighPerformance", "HighIoPriority", "TimerSlackNormal"}, - true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"SCHED_SP_FOREGROUND"}, true) ? 0 : -1; case SP_TOP_APP: - return SetTaskProfiles(tid, {"MaxPerformance", "MaxIoPriority", "TimerSlackNormal"}, - true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"SCHED_SP_TOP_APP"}, true) ? 0 : -1; case SP_RT_APP: - return SetTaskProfiles( - tid, {"RealtimePerformance", "MaxIoPriority", "TimerSlackNormal"}, true) - ? 0 - : -1; + return SetTaskProfiles(tid, {"SCHED_SP_RT_APP"}, true) ? 0 : -1; default: - return SetTaskProfiles(tid, {"TimerSlackNormal"}, true) ? 0 : -1; + return SetTaskProfiles(tid, {"SCHED_SP_DEFAULT"}, true) ? 0 : -1; } return 0; diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp index aee5f0cce..9447f864b 100644 --- a/libprocessgroup/task_profiles.cpp +++ b/libprocessgroup/task_profiles.cpp @@ -268,6 +268,26 @@ bool SetCgroupAction::ExecuteForTask(int tid) const { return true; } +bool ApplyProfileAction::ExecuteForProcess(uid_t uid, pid_t pid) const { + for (const auto& profile : profiles_) { + profile->EnableResourceCaching(); + if (!profile->ExecuteForProcess(uid, pid)) { + PLOG(WARNING) << "ExecuteForProcess failed for aggregate profile"; + } + } + return true; +} + +bool ApplyProfileAction::ExecuteForTask(int tid) const { + for (const auto& profile : profiles_) { + profile->EnableResourceCaching(); + if (!profile->ExecuteForTask(tid)) { + PLOG(WARNING) << "ExecuteForTask failed for aggregate profile"; + } + } + return true; +} + bool TaskProfile::ExecuteForProcess(uid_t uid, pid_t pid) const { for (const auto& element : elements_) { if (!element->ExecuteForProcess(uid, pid)) { @@ -373,15 +393,13 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) { } } - std::map<std::string, std::string> params; - const Json::Value& profiles_val = root["Profiles"]; for (Json::Value::ArrayIndex i = 0; i < profiles_val.size(); ++i) { const Json::Value& profile_val = profiles_val[i]; std::string profile_name = profile_val["Name"].asString(); const Json::Value& actions = profile_val["Actions"]; - auto profile = std::make_unique<TaskProfile>(); + auto profile = std::make_shared<TaskProfile>(); for (Json::Value::ArrayIndex act_idx = 0; act_idx < actions.size(); ++act_idx) { const Json::Value& action_val = actions[act_idx]; @@ -440,7 +458,38 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) { LOG(WARNING) << "Unknown profile action: " << action_name; } } - profiles_[profile_name] = std::move(profile); + profiles_[profile_name] = profile; + } + + const Json::Value& aggregateprofiles_val = root["AggregateProfiles"]; + for (Json::Value::ArrayIndex i = 0; i < aggregateprofiles_val.size(); ++i) { + const Json::Value& aggregateprofile_val = aggregateprofiles_val[i]; + + std::string aggregateprofile_name = aggregateprofile_val["Name"].asString(); + const Json::Value& aggregateprofiles = aggregateprofile_val["Profiles"]; + std::vector<std::shared_ptr<TaskProfile>> profiles; + bool ret = true; + + for (Json::Value::ArrayIndex pf_idx = 0; pf_idx < aggregateprofiles.size(); ++pf_idx) { + std::string profile_name = aggregateprofiles[pf_idx].asString(); + + if (profile_name == aggregateprofile_name) { + LOG(WARNING) << "AggregateProfiles: recursive profile name: " << profile_name; + ret = false; + break; + } else if (profiles_.find(profile_name) == profiles_.end()) { + LOG(WARNING) << "AggregateProfiles: undefined profile name: " << profile_name; + ret = false; + break; + } else { + profiles.push_back(profiles_[profile_name]); + } + } + if (ret) { + auto profile = std::make_shared<TaskProfile>(); + profile->Add(std::make_unique<ApplyProfileAction>(profiles)); + profiles_[aggregateprofile_name] = profile; + } } return true; @@ -463,3 +512,39 @@ const ProfileAttribute* TaskProfiles::GetAttribute(const std::string& name) cons } return nullptr; } + +bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid, + const std::vector<std::string>& profiles, bool use_fd_cache) { + for (const auto& name : profiles) { + TaskProfile* profile = GetProfile(name); + if (profile != nullptr) { + if (use_fd_cache) { + profile->EnableResourceCaching(); + } + if (!profile->ExecuteForProcess(uid, pid)) { + PLOG(WARNING) << "Failed to apply " << name << " process profile"; + } + } else { + PLOG(WARNING) << "Failed to find " << name << "process profile"; + } + } + return true; +} + +bool TaskProfiles::SetTaskProfiles(int tid, const std::vector<std::string>& profiles, + bool use_fd_cache) { + for (const auto& name : profiles) { + TaskProfile* profile = GetProfile(name); + if (profile != nullptr) { + if (use_fd_cache) { + profile->EnableResourceCaching(); + } + if (!profile->ExecuteForTask(tid)) { + PLOG(WARNING) << "Failed to apply " << name << " task profile"; + } + } else { + PLOG(WARNING) << "Failed to find " << name << "task profile"; + } + } + return true; +} diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h index 891d5b56a..9f2308c64 100644 --- a/libprocessgroup/task_profiles.h +++ b/libprocessgroup/task_profiles.h @@ -154,6 +154,19 @@ class TaskProfile { std::vector<std::unique_ptr<ProfileAction>> elements_; }; +// Set aggregate profile element +class ApplyProfileAction : public ProfileAction { + public: + ApplyProfileAction(const std::vector<std::shared_ptr<TaskProfile>>& profiles) + : profiles_(profiles) {} + + virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const; + virtual bool ExecuteForTask(int tid) const; + + private: + std::vector<std::shared_ptr<TaskProfile>> profiles_; +}; + class TaskProfiles { public: // Should be used by all users @@ -162,9 +175,12 @@ class TaskProfiles { TaskProfile* GetProfile(const std::string& name) const; const ProfileAttribute* GetAttribute(const std::string& name) const; void DropResourceCaching() const; + bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles, + bool use_fd_cache); + bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache); private: - std::map<std::string, std::unique_ptr<TaskProfile>> profiles_; + std::map<std::string, std::shared_ptr<TaskProfile>> profiles_; std::map<std::string, std::unique_ptr<ProfileAttribute>> attributes_; TaskProfiles(); |
