Merge "Add support for memcg v2 attributes"
This commit is contained in:
commit
1f34b28356
4 changed files with 51 additions and 10 deletions
|
@ -15,21 +15,48 @@
|
|||
"Controller": "cpuset",
|
||||
"File": "top-app/cpus"
|
||||
},
|
||||
{
|
||||
"Name": "MemStats",
|
||||
"Controller": "memory",
|
||||
"File": "memory.stat"
|
||||
},
|
||||
{
|
||||
"Name": "MemLimit",
|
||||
"Controller": "memory",
|
||||
"File": "memory.limit_in_bytes"
|
||||
"File": "memory.limit_in_bytes",
|
||||
"FileV2": "memory.max"
|
||||
},
|
||||
{
|
||||
"Name": "MemSoftLimit",
|
||||
"Controller": "memory",
|
||||
"File": "memory.soft_limit_in_bytes"
|
||||
"File": "memory.soft_limit_in_bytes",
|
||||
"FileV2": "memory.low"
|
||||
},
|
||||
{
|
||||
"Name": "MemSwappiness",
|
||||
"Controller": "memory",
|
||||
"File": "memory.swappiness"
|
||||
},
|
||||
{
|
||||
"Name": "MemUsage",
|
||||
"Controller": "memory",
|
||||
"File": "memory.usage_in_bytes"
|
||||
},
|
||||
{
|
||||
"Name": "MemAndSwapUsage",
|
||||
"Controller": "memory",
|
||||
"File": "memory.memsw.usage_in_bytes"
|
||||
},
|
||||
{
|
||||
"Name": "MemPressureLevel",
|
||||
"Controller": "memory",
|
||||
"File": "memory.pressure_level"
|
||||
},
|
||||
{
|
||||
"Name": "MemCgroupEventControl",
|
||||
"Controller": "memory",
|
||||
"File": "cgroup.event_control"
|
||||
},
|
||||
{
|
||||
"Name": "UClampMin",
|
||||
"Controller": "cpu",
|
||||
|
|
|
@ -25,12 +25,13 @@ message TaskProfiles {
|
|||
repeated AggregateProfiles aggregateprofiles = 3 [json_name = "AggregateProfiles"];
|
||||
}
|
||||
|
||||
// Next: 5
|
||||
// Next: 6
|
||||
message Attribute {
|
||||
string name = 1 [json_name = "Name"];
|
||||
string controller = 2 [json_name = "Controller"];
|
||||
string file = 3 [json_name = "File"];
|
||||
string optional = 4 [json_name = "Optional"];
|
||||
string filev2 = 4 [json_name = "FileV2"];
|
||||
string optional = 5 [json_name = "Optional"];
|
||||
}
|
||||
|
||||
// Next: 3
|
||||
|
|
|
@ -129,11 +129,12 @@ bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
const std::string& file_name =
|
||||
controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_;
|
||||
if (subgroup.empty()) {
|
||||
*path = StringPrintf("%s/%s", controller()->path(), file_name_.c_str());
|
||||
*path = StringPrintf("%s/%s", controller()->path(), file_name.c_str());
|
||||
} else {
|
||||
*path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(),
|
||||
file_name_.c_str());
|
||||
*path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(), file_name.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -633,12 +634,19 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) {
|
|||
std::string name = attr[i]["Name"].asString();
|
||||
std::string controller_name = attr[i]["Controller"].asString();
|
||||
std::string file_attr = attr[i]["File"].asString();
|
||||
std::string file_v2_attr = attr[i]["FileV2"].asString();
|
||||
|
||||
if (!file_v2_attr.empty() && file_attr.empty()) {
|
||||
LOG(ERROR) << "Attribute " << name << " has FileV2 but no File property";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto controller = cg_map.FindController(controller_name);
|
||||
if (controller.HasValue()) {
|
||||
auto iter = attributes_.find(name);
|
||||
if (iter == attributes_.end()) {
|
||||
attributes_[name] = std::make_unique<ProfileAttribute>(controller, file_attr);
|
||||
attributes_[name] =
|
||||
std::make_unique<ProfileAttribute>(controller, file_attr, file_v2_attr);
|
||||
} else {
|
||||
iter->second->Reset(controller, file_attr);
|
||||
}
|
||||
|
|
|
@ -37,8 +37,12 @@ class IProfileAttribute {
|
|||
|
||||
class ProfileAttribute : public IProfileAttribute {
|
||||
public:
|
||||
ProfileAttribute(const CgroupController& controller, const std::string& file_name)
|
||||
: controller_(controller), file_name_(file_name) {}
|
||||
// Cgroup attributes may have different names in the v1 and v2 hierarchies. If `file_v2_name` is
|
||||
// not empty, `file_name` is the name for the v1 hierarchy and `file_v2_name` is the name for
|
||||
// the v2 hierarchy. If `file_v2_name` is empty, `file_name` is used for both hierarchies.
|
||||
ProfileAttribute(const CgroupController& controller, const std::string& file_name,
|
||||
const std::string& file_v2_name)
|
||||
: controller_(controller), file_name_(file_name), file_v2_name_(file_v2_name) {}
|
||||
~ProfileAttribute() = default;
|
||||
|
||||
const CgroupController* controller() const override { return &controller_; }
|
||||
|
@ -50,6 +54,7 @@ class ProfileAttribute : public IProfileAttribute {
|
|||
private:
|
||||
CgroupController controller_;
|
||||
std::string file_name_;
|
||||
std::string file_v2_name_;
|
||||
};
|
||||
|
||||
// Abstract profile element
|
||||
|
|
Loading…
Reference in a new issue