]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: introduce support for setting NUMAMask= to special "all" value
authorMichal Sekletár <msekleta@redhat.com>
Tue, 1 Sep 2020 10:12:32 +0000 (12:12 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 8 Sep 2020 06:16:03 +0000 (08:16 +0200)
Fixes #14113

man/systemd.exec.xml
src/core/load-fragment.c
src/shared/bus-unit-util.c
src/shared/cpu-set-util.c
src/shared/cpu-set-util.h
src/shared/numa-util.c
src/shared/numa-util.h

index 2b53002f78fa1f630b6cc8c431ecebd1b6e7a575..d2279a9b9adc2824996bf04396c7aceef75f6899 100644 (file)
@@ -1042,7 +1042,8 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
 
         <listitem><para>Controls the NUMA node list which will be applied alongside with selected NUMA policy.
         Takes a list of NUMA nodes and has the same syntax as a list of CPUs for <varname>CPUAffinity=</varname>
-        option. Note that the list of NUMA nodes is not required for <option>default</option> and <option>local</option>
+        option or special "all" value which will include all available NUMA nodes in the mask. Note that the list
+        of NUMA nodes is not required for <option>default</option> and <option>local</option>
         policies and for <option>preferred</option> policy we expect a single NUMA node.</para></listitem>
       </varlistentry>
 
index a93f12b27c45a1e8dad1c5e14c2425ef52590419..633c7ca106aad807ea0f883a25d26e0a89d7fbbb 100644 (file)
@@ -1370,10 +1370,18 @@ int config_parse_numa_mask(const char *unit,
         assert(rvalue);
         assert(data);
 
-        r = parse_cpu_set_extend(rvalue, &p->nodes, true, unit, filename, line, lvalue);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse NUMA node mask, ignoring: %s", rvalue);
-                return 0;
+        if (streq(rvalue, "all")) {
+                r = numa_mask_add_all(&p->nodes);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to create NUMA mask representing \"all\" NUMA nodes, ignoring: %m");
+                        return 0;
+                }
+        } else {
+                r = parse_cpu_set_extend(rvalue, &p->nodes, true, unit, filename, line, lvalue);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse NUMA node mask, ignoring: %s", rvalue);
+                        return 0;
+                }
         }
 
         return r;
index b6def087f63ecaca18c0e3a44349c7a1d85fbb07..e579d606c362f786f69675754b0acca16667a9e9 100644 (file)
@@ -1275,9 +1275,15 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
                 _cleanup_free_ uint8_t *array = NULL;
                 size_t allocated;
 
-                r = parse_cpu_set(eq, &nodes);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
+                if (eq && streq(eq, "all")) {
+                        r = numa_mask_add_all(&nodes);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to create NUMA mask representing \"all\" NUMA nodes: %m");
+                } else {
+                        r = parse_cpu_set(eq, &nodes);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
+                }
 
                 r = cpu_set_to_dbus(&nodes, &array, &allocated);
                 if (r < 0)
index 9b9238362f2ff2d27f2fbcf4c4c65ee686c4500f..8779d1d4d306a7af1389405a6a273ac4b01fde9f 100644 (file)
@@ -105,7 +105,7 @@ int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
         return 0;
 }
 
-static int cpu_set_add(CPUSet *cpu_set, unsigned cpu) {
+int cpu_set_add(CPUSet *cpu_set, unsigned cpu) {
         int r;
 
         if (cpu >= 8192)
index a60d4ec41b599e2c04bc5a7a5489bd93f32dfce6..9ec83f69302e68af2ad2a90244d23de8bc74bd98 100644 (file)
@@ -20,6 +20,7 @@ static inline void cpu_set_reset(CPUSet *a) {
 }
 
 int cpu_set_add_all(CPUSet *a, const CPUSet *b);
+int cpu_set_add(CPUSet *a, unsigned cpu);
 
 char* cpu_set_to_string(const CPUSet *a);
 char *cpu_set_to_range_string(const CPUSet *a);
index 187992dc69e5dd32365707fd9e382a3daf326085..3ec8ffc5b267f1d38480808b34274d612b835728 100644 (file)
@@ -5,6 +5,8 @@
 
 #include "alloc-util.h"
 #include "cpu-set-util.h"
+#include "dirent-util.h"
+#include "fd-util.h"
 #include "fileio.h"
 #include "macro.h"
 #include "missing_syscall.h"
@@ -124,6 +126,61 @@ int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *ret) {
         return 0;
 }
 
+static int numa_max_node(void) {
+        _cleanup_closedir_ DIR *d = NULL;
+        struct dirent *de;
+        int r, max_node = 0;
+
+        d = opendir("/sys/devices/system/node");
+        if (!d)
+                return -errno;
+
+        FOREACH_DIRENT(de, d, break) {
+                int node;
+                const char *n;
+
+                (void) dirent_ensure_type(d, de);
+
+                if (de->d_type != DT_DIR)
+                        continue;
+
+                n = startswith(de->d_name, "node");
+                if (!n)
+                        continue;
+
+                r = safe_atoi(n, &node);
+                if (r < 0)
+                        continue;
+
+                if (node > max_node)
+                        max_node = node;
+        }
+
+        return max_node;
+}
+
+int numa_mask_add_all(CPUSet *mask) {
+        int m;
+
+        assert(mask);
+
+        m = numa_max_node();
+        if (m < 0) {
+                log_debug_errno(m, "Failed to determine maximum NUMA node index, assuming 1023: %m");
+                m = 1023; /* CONFIG_NODES_SHIFT is set to 10 on x86_64, i.e. 1024 NUMA nodes in total */
+        }
+
+        for (int i = 0; i <= m; i++) {
+                int r;
+
+                r = cpu_set_add(mask, i);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
 static const char* const mpol_table[] = {
         [MPOL_DEFAULT]    = "default",
         [MPOL_PREFERRED]  = "preferred",
index c99178903b3f7f03f8a9f40bcf61bcccf0c6fa65..2a9ced74e8d40aecca1988222f4245d8ab9a886c 100644 (file)
@@ -29,5 +29,7 @@ static inline void numa_policy_reset(NUMAPolicy *p) {
 int apply_numa_policy(const NUMAPolicy *policy);
 int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *set);
 
+int numa_mask_add_all(CPUSet *mask);
+
 const char* mpol_to_string(int i) _const_;
 int mpol_from_string(const char *s) _pure_;