Merge "libprocessgroup: add support to set aggregate profiles"
am: 3e71c06d90
Change-Id: I3ac80fa3f458d0609d29f5cf1aeab457ad65afce
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 7c191be..7b6dde2 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -117,43 +117,11 @@
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 74a39cd..608f007 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 578f0d3..1de4395 100644
--- a/libprocessgroup/profiles/task_profiles.proto
+++ b/libprocessgroup/profiles/task_profiles.proto
@@ -18,10 +18,11 @@
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 @@
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 c83df1a..6b0ab87 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -46,34 +46,17 @@
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 @@
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 aee5f0c..9447f86 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -268,6 +268,26 @@
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 @@
}
}
- 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 @@
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 @@
}
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 891d5b5..9f2308c 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -154,6 +154,19 @@
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 @@
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();