summaryrefslogtreecommitdiffstats
path: root/src/core/cgroup.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-01-03 21:38:06 +0100
committerGitHub <noreply@github.com>2024-01-03 21:38:06 +0100
commit82a1597778906226f6f57e15542fde7b23e73a2e (patch)
tree172148ea5abc0edfa44451bb60628b048f4d8fee /src/core/cgroup.c
parentlogind: don't setup idle session watch for lock-screen and greeter (diff)
parentcgroup: Restrict effective limits with global resource provision (diff)
downloadsystemd-82a1597778906226f6f57e15542fde7b23e73a2e.tar.xz
systemd-82a1597778906226f6f57e15542fde7b23e73a2e.zip
Merge pull request #28797 from Werkov/eff_limits
Add MemoryMaxEffective=, MemoryHighEffective= and TasksMaxEff… …ective= properties
Diffstat (limited to 'src/core/cgroup.c')
-rw-r--r--src/core/cgroup.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 311a4197aa..411f59d55d 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -4555,6 +4555,57 @@ int unit_get_ip_accounting(
return r;
}
+static uint64_t unit_get_effective_limit_one(Unit *u, CGroupLimitType type) {
+ CGroupContext *cc;
+
+ assert(u);
+ assert(UNIT_HAS_CGROUP_CONTEXT(u));
+
+ if (unit_has_name(u, SPECIAL_ROOT_SLICE))
+ switch (type) {
+ case CGROUP_LIMIT_MEMORY_MAX:
+ case CGROUP_LIMIT_MEMORY_HIGH:
+ return physical_memory();
+ case CGROUP_LIMIT_TASKS_MAX:
+ return system_tasks_max();
+ default:
+ assert_not_reached();
+ }
+
+ cc = unit_get_cgroup_context(u);
+ switch (type) {
+ /* Note: on legacy/hybrid hierarchies memory_max stays CGROUP_LIMIT_MAX unless configured
+ * explicitly. Effective value of MemoryLimit= (cgroup v1) is not implemented. */
+ case CGROUP_LIMIT_MEMORY_MAX:
+ return cc->memory_max;
+ case CGROUP_LIMIT_MEMORY_HIGH:
+ return cc->memory_high;
+ case CGROUP_LIMIT_TASKS_MAX:
+ return cgroup_tasks_max_resolve(&cc->tasks_max);
+ default:
+ assert_not_reached();
+ }
+}
+
+int unit_get_effective_limit(Unit *u, CGroupLimitType type, uint64_t *ret) {
+ uint64_t infimum;
+
+ assert(u);
+ assert(ret);
+ assert(type >= 0);
+ assert(type < _CGROUP_LIMIT_TYPE_MAX);
+
+ if (!UNIT_HAS_CGROUP_CONTEXT(u))
+ return -EINVAL;
+
+ infimum = unit_get_effective_limit_one(u, type);
+ for (Unit *slice = UNIT_GET_SLICE(u); slice; slice = UNIT_GET_SLICE(slice))
+ infimum = MIN(infimum, unit_get_effective_limit_one(slice, type));
+
+ *ret = infimum;
+ return 0;
+}
+
static int unit_get_io_accounting_raw(Unit *u, uint64_t ret[static _CGROUP_IO_ACCOUNTING_METRIC_MAX]) {
static const char *const field_names[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
[CGROUP_IO_READ_BYTES] = "rbytes=",
@@ -4975,3 +5026,11 @@ static const char* const cgroup_memory_accounting_metric_table[_CGROUP_MEMORY_AC
};
DEFINE_STRING_TABLE_LOOKUP(cgroup_memory_accounting_metric, CGroupMemoryAccountingMetric);
+
+static const char *const cgroup_limit_type_table[_CGROUP_LIMIT_TYPE_MAX] = {
+ [CGROUP_LIMIT_MEMORY_MAX] = "EffectiveMemoryMax",
+ [CGROUP_LIMIT_MEMORY_HIGH] = "EffectiveMemoryHigh",
+ [CGROUP_LIMIT_TASKS_MAX] = "EffectiveTasksMax",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(cgroup_limit_type, CGroupLimitType);