]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/limits-util.c
0cd59f97acfbf8f9260667a3c1a6400a82c050e5
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include "alloc-util.h"
4 #include "cgroup-util.h"
5 #include "limits-util.h"
6 #include "parse-util.h"
7 #include "process-util.h"
8 #include "procfs-util.h"
9 #include "string-util.h"
11 uint64_t physical_memory(void) {
12 _cleanup_free_
char *root
= NULL
, *value
= NULL
;
18 /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of
21 * In order to support containers nicely that have a configured memory limit we'll take the minimum of the
22 * physically reported amount of memory and the limit configured for the root cgroup, if there is any. */
24 sc
= sysconf(_SC_PHYS_PAGES
);
28 mem
= (uint64_t) sc
* (uint64_t) ps
;
30 r
= cg_get_root_path(&root
);
32 log_debug_errno(r
, "Failed to determine root cgroup, ignoring cgroup memory limit: %m");
38 log_debug_errno(r
, "Failed to determine root unified mode, ignoring cgroup memory limit: %m");
42 r
= cg_get_attribute("memory", root
, "memory.max", &value
);
44 log_debug_errno(r
, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m");
48 if (streq(value
, "max"))
51 r
= cg_get_attribute("memory", root
, "memory.limit_in_bytes", &value
);
53 log_debug_errno(r
, "Failed to read memory.limit_in_bytes cgroup attribute, ignoring cgroup memory limit: %m");
58 r
= safe_atou64(value
, &lim
);
60 log_debug_errno(r
, "Failed to parse cgroup memory limit '%s', ignoring: %m", value
);
63 if (lim
== UINT64_MAX
)
66 /* Make sure the limit is a multiple of our own page size */
73 uint64_t physical_memory_scale(uint64_t v
, uint64_t max
) {
78 /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success
79 * the result is a multiple of the page size (rounds down). */
84 p
= physical_memory() / ps
;
100 uint64_t system_tasks_max(void) {
102 uint64_t a
= TASKS_MAX
, b
= TASKS_MAX
;
103 _cleanup_free_
char *root
= NULL
;
106 /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this
109 * a) the maximum tasks value the kernel allows on this architecture
110 * b) the cgroups pids_max attribute for the system
111 * c) the kernel's configured maximum PID value
113 * And then pick the smallest of the three */
115 r
= procfs_tasks_get_limit(&a
);
117 log_debug_errno(r
, "Failed to read maximum number of tasks from /proc, ignoring: %m");
119 r
= cg_get_root_path(&root
);
121 log_debug_errno(r
, "Failed to determine cgroup root path, ignoring: %m");
123 _cleanup_free_
char *value
= NULL
;
125 r
= cg_get_attribute("pids", root
, "pids.max", &value
);
127 log_debug_errno(r
, "Failed to read pids.max attribute of cgroup root, ignoring: %m");
128 else if (!streq(value
, "max")) {
129 r
= safe_atou64(value
, &b
);
131 log_debug_errno(r
, "Failed to parse pids.max attribute of cgroup root, ignoring: %m");
135 return MIN3(TASKS_MAX
,
136 a
<= 0 ? TASKS_MAX
: a
,
137 b
<= 0 ? TASKS_MAX
: b
);
140 uint64_t system_tasks_max_scale(uint64_t v
, uint64_t max
) {
145 /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages
146 * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */
148 t
= system_tasks_max();
152 if (m
/ t
!= v
) /* overflow? */