in src/oomd/CgroupContext.cpp [371:405]
std::optional<int64_t> CgroupContext::getMemoryProtection(Error* err) const {
if (cgroup_.isRoot()) {
return current_usage(err);
}
auto parent_cgroup = cgroup_.getParent();
if (parent_cgroup.isRoot()) {
// We're at a top level cgroup where P(cgrp) == R(cgrp)
return rawProtection(*this, err);
}
auto parent_ctx = ctx_.addToCacheAndGet(parent_cgroup);
if (!parent_ctx) {
if (err) {
*err = Error::INVALID_CGROUP;
}
return std::nullopt;
}
std::unordered_set<CgroupPath> sibling_cgroups;
std::vector<OomdContext::ConstCgroupContextRef> siblings;
if (auto children = parent_ctx->get().children(err)) {
for (const auto& name : *children) {
sibling_cgroups.insert(parent_cgroup.getChild(name));
}
siblings = ctx_.addToCacheAndGet(sibling_cgroups);
} else {
return std::nullopt;
}
int64_t protection_sum = 0;
for (auto sibling_ctx : siblings) {
protection_sum += rawProtection(sibling_ctx).value_or(0);
}
return normalizedProtection(*this, *parent_ctx, protection_sum, err);
}