core: introduce support for setting NUMAMask= to special "all" value

Fixes #14113
This commit is contained in:
Michal Sekletár 2020-09-01 12:12:32 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent 6743a1caf4
commit 332d387f47
7 changed files with 84 additions and 9 deletions

View 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>

View 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;

View 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)

View 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)

View 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);

View 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",

View 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_;