mirror of
https://github.com/systemd/systemd.git
synced 2024-11-24 02:33:36 +08:00
core: introduce support for setting NUMAMask= to special "all" value
Fixes #14113
This commit is contained in:
parent
6743a1caf4
commit
332d387f47
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user