libprocessgroup: add support to set aggregate profiles
To support setting multiple profiles with one call. The json format is as below example. "AggregateProfiles": [ ... { "Name": "SCHED_SP_BACKGROUND", "Profiles": [ "HighEnergySaving", "LowIoPriority", "TimerSlackHigh" ] }, ... } Bug: 139521784 Test: SetProfile works as expected Change-Id: Ibe14ed57d5169cafcbcbbdb054df3ed171a2f6a2
This commit is contained in:
parent
4b45eab15b
commit
0b211fa8b3
|
@ -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) {
|
||||
|
|
|
@ -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" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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"];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue