chiark / gitweb /
logind: update empty and "infinity" handling for [User]TasksMax (#3835)
authorTejun Heo <htejun@fb.com>
Fri, 19 Aug 2016 02:57:53 +0000 (22:57 -0400)
committerSven Eden <yamakuzure@gmx.net>
Wed, 5 Jul 2017 06:50:52 +0000 (08:50 +0200)
The parsing functions for [User]TasksMax were inconsistent.  Empty string and
"infinity" were interpreted as no limit for TasksMax but not accepted for
UserTasksMax.  Update them so that they're consistent with other knobs.

* Empty string indicates the default value.
* "infinity" indicates no limit.

While at it, replace opencoded (uint64_t) -1 with CGROUP_LIMIT_MAX in TasksMax
handling.

v2: Update empty string to indicate the default value as suggested by Zbigniew
    JÄ™drzejewski-Szmek.

v3: Fixed empty UserTasksMax handling.

src/basic/cgroup-util.h
src/core/cgroup.c
src/login/logind-user.c

index 0255e2850b94c87d0c67ca4aa4a814462a409c0f..5f3152995e253b1a4e3182d5a5747733ee8430df 100644 (file)
@@ -114,6 +114,10 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
 }
 #endif // 0
 
+/* Default resource limits */
+#define DEFAULT_TASKS_MAX_PERCENTAGE            15U /* 15% of PIDs, 4915 on default settings */
+#define DEFAULT_USER_TASKS_MAX_PERCENTAGE       33U /* 33% of PIDs, 10813 on default settings */
+
 /*
  * General rules:
  *
@@ -238,7 +242,7 @@ bool cg_ns_supported(void);
 #endif // 0
 
 #if 0 /// UNNEEDED by elogind
-int cg_all_unified(void);
+int cg_unified(void);
 void cg_unified_flush(void);
 
 bool cg_is_unified_wanted(void);
index 16045c2d5dce758ea8a3dfa3d243acbd7e0c76a2..e55b54633e2b7fdce71733a52400c57e9fb976ab 100644 (file)
@@ -666,7 +666,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
                 bool has_weight = cgroup_context_has_cpu_weight(c);
                 bool has_shares = cgroup_context_has_cpu_shares(c);
 
-                if (cg_all_unified() > 0) {
+                if (cg_unified() > 0) {
                         uint64_t weight;
 
                         if (has_weight)
@@ -847,7 +847,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
         }
 
         if ((mask & CGROUP_MASK_MEMORY) && !is_root) {
-                if (cg_all_unified() > 0) {
+                if (cg_unified() > 0) {
                         uint64_t max = c->memory_max;
 
                         if (cgroup_context_has_unified_memory_config(c))
@@ -954,7 +954,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
 
         if ((mask & CGROUP_MASK_PIDS) && !is_root) {
 
-                if (c->tasks_max != (uint64_t) -1) {
+                if (c->tasks_max != CGROUP_LIMIT_MAX) {
                         char buf[DECIMAL_STR_MAX(uint64_t) + 2];
 
                         sprintf(buf, "%" PRIu64 "\n", c->tasks_max);
@@ -1021,7 +1021,7 @@ CGroupMask unit_get_own_mask(Unit *u) {
                 e = unit_get_exec_context(u);
                 if (!e ||
                     exec_context_maintains_privileges(e) ||
-                    cg_all_unified() > 0)
+                    cg_unified() > 0)
                         return _CGROUP_MASK_ALL;
         }
 
@@ -1247,7 +1247,7 @@ int unit_watch_cgroup(Unit *u) {
                 return 0;
 
         /* Only applies to the unified hierarchy */
-        r = cg_all_unified();
+        r = cg_unified();
         if (r < 0)
                 return log_unit_error_errno(u, r, "Failed detect whether the unified hierarchy is used: %m");
         if (r == 0)
@@ -1526,8 +1526,6 @@ void unit_prune_cgroup(Unit *u) {
         if (!u->cgroup_path)
                 return;
 
-        (void) unit_get_cpu_usage(u, NULL); /* Cache the last CPU usage value before we destroy the cgroup */
-
         is_root_slice = unit_has_name(u, SPECIAL_ROOT_SLICE);
 
         r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !is_root_slice);
@@ -1649,7 +1647,7 @@ int unit_watch_all_pids(Unit *u) {
         if (!u->cgroup_path)
                 return -ENOENT;
 
-        if (cg_all_unified() > 0) /* On unified we can use proper notifications */
+        if (cg_unified() > 0) /* On unified we can use proper notifications */
                 return 0;
 
         return unit_watch_pids_in_path(u, u->cgroup_path);
@@ -1764,7 +1762,7 @@ int manager_setup_cgroup(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Cannot find cgroup mount point: %m");
 
-        unified = cg_all_unified();
+        unified = cg_unified();
         if (unified < 0)
                 return log_error_errno(r, "Couldn't determine if we are running in the unified hierarchy: %m");
         if (unified > 0)
@@ -2006,7 +2004,7 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
         if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
                 return -ENODATA;
 
-        if (cg_all_unified() <= 0)
+        if (cg_unified() <= 0)
                 r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
         else
                 r = cg_get_attribute("memory", u->cgroup_path, "memory.current", &v);
@@ -2051,7 +2049,7 @@ static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
         if (!u->cgroup_path)
                 return -ENODATA;
 
-        if (cg_all_unified() > 0) {
+        if (cg_unified() > 0) {
                 const char *keys[] = { "usage_usec", NULL };
                 _cleanup_free_ char *val = NULL;
                 uint64_t us;
@@ -2091,21 +2089,7 @@ int unit_get_cpu_usage(Unit *u, nsec_t *ret) {
         nsec_t ns;
         int r;
 
-        assert(u);
-
-        /* Retrieve the current CPU usage counter. This will subtract the CPU counter taken when the unit was
-         * started. If the cgroup has been removed already, returns the last cached value. To cache the value, simply
-         * call this function with a NULL return value. */
-
         r = unit_get_cpu_usage_raw(u, &ns);
-        if (r == -ENODATA && u->cpu_usage_last != NSEC_INFINITY) {
-                /* If we can't get the CPU usage anymore (because the cgroup was already removed, for example), use our
-                 * cached value. */
-
-                if (ret)
-                        *ret = u->cpu_usage_last;
-                return 0;
-        }
         if (r < 0)
                 return r;
 
@@ -2114,10 +2098,7 @@ int unit_get_cpu_usage(Unit *u, nsec_t *ret) {
         else
                 ns = 0;
 
-        u->cpu_usage_last = ns;
-        if (ret)
-                *ret = ns;
-
+        *ret = ns;
         return 0;
 }
 
@@ -2127,8 +2108,6 @@ int unit_reset_cpu_usage(Unit *u) {
 
         assert(u);
 
-        u->cpu_usage_last = NSEC_INFINITY;
-
         r = unit_get_cpu_usage_raw(u, &ns);
         if (r < 0) {
                 u->cpu_usage_base = 0;
index cd198c8d2623205ae116448897cff284e1ca4710..8a84a8f80d5accd2fb62c971a1bfb1eefc48f497 100644 (file)
@@ -942,7 +942,17 @@ int config_parse_user_tasks_max(
         assert(rvalue);
         assert(data);
 
-        /* First, try to parse as percentage */
+        if (isempty(rvalue)) {
+                *m = system_tasks_max_scale(DEFAULT_USER_TASKS_MAX_PERCENTAGE, 100U);
+                return 0;
+        }
+
+        if (streq(rvalue, "infinity")) {
+                *m = CGROUP_LIMIT_MAX;
+                return 0;
+        }
+
+        /* Try to parse as percentage */
         r = parse_percent(rvalue);
         if (r >= 0)
                 k = system_tasks_max_scale(r, 100U);