diff options
author | Michal Sekletár <msekleta@redhat.com> | 2020-02-17 13:04:08 +0100 |
---|---|---|
committer | Michal Sekletár <msekleta@redhat.com> | 2020-03-16 08:23:18 +0100 |
commit | 1808f76870d8368542f058b99df89cf0a4a2d011 (patch) | |
tree | af6812637836b24733ff90d808da0d05fe1bf6a5 /src/shared | |
parent | NEWS: fix use of tabs instead of spaces for one item (diff) | |
download | systemd-1808f76870d8368542f058b99df89cf0a4a2d011.tar.xz systemd-1808f76870d8368542f058b99df89cf0a4a2d011.zip |
shared: split out NUMA code from cpu-set-util.c to numa-util.c
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/bus-unit-util.c | 1 | ||||
-rw-r--r-- | src/shared/cpu-set-util.c | 87 | ||||
-rw-r--r-- | src/shared/cpu-set-util.h | 27 | ||||
-rw-r--r-- | src/shared/meson.build | 2 | ||||
-rw-r--r-- | src/shared/numa-util.c | 135 | ||||
-rw-r--r-- | src/shared/numa-util.h | 33 |
6 files changed, 171 insertions, 114 deletions
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 28d85944a8..98cf51aeda 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -21,6 +21,7 @@ #include "missing_fs.h" #include "mountpoint-util.h" #include "nsflags.h" +#include "numa-util.h" #include "parse-util.h" #include "process-util.h" #include "rlimit-util.h" diff --git a/src/shared/cpu-set-util.c b/src/shared/cpu-set-util.c index 219314ef58..97c16ebb8c 100644 --- a/src/shared/cpu-set-util.c +++ b/src/shared/cpu-set-util.c @@ -14,11 +14,9 @@ #include "log.h" #include "macro.h" #include "memory-util.h" -#include "missing_syscall.h" #include "parse-util.h" #include "stat-util.h" #include "string-util.h" -#include "string-table.h" #include "strv.h" #include "util.h" @@ -295,88 +293,3 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) { s = (CPUSet) {}; return 0; } - -bool numa_policy_is_valid(const NUMAPolicy *policy) { - assert(policy); - - if (!mpol_is_valid(numa_policy_get_type(policy))) - return false; - - if (!policy->nodes.set && - !IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED)) - return false; - - if (policy->nodes.set && - numa_policy_get_type(policy) == MPOL_PREFERRED && - CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1) - return false; - - return true; -} - -static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) { - unsigned node, bits = 0, ulong_bits; - _cleanup_free_ unsigned long *out = NULL; - - assert(policy); - assert(ret_maxnode); - assert(ret_nodes); - - if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL) || - (numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) { - *ret_nodes = NULL; - *ret_maxnode = 0; - return 0; - } - - bits = policy->nodes.allocated * 8; - ulong_bits = sizeof(unsigned long) * 8; - - out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long))); - if (!out) - return -ENOMEM; - - /* We don't make any assumptions about internal type libc is using to store NUMA node mask. - Hence we need to convert the node mask to the representation expected by set_mempolicy() */ - for (node = 0; node < bits; node++) - if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set)) - out[node / ulong_bits] |= 1ul << (node % ulong_bits); - - *ret_nodes = TAKE_PTR(out); - *ret_maxnode = bits + 1; - return 0; -} - -int apply_numa_policy(const NUMAPolicy *policy) { - int r; - _cleanup_free_ unsigned long *nodes = NULL; - unsigned long maxnode; - - assert(policy); - - if (get_mempolicy(NULL, NULL, 0, 0, 0) < 0 && errno == ENOSYS) - return -EOPNOTSUPP; - - if (!numa_policy_is_valid(policy)) - return -EINVAL; - - r = numa_policy_to_mempolicy(policy, &maxnode, &nodes); - if (r < 0) - return r; - - r = set_mempolicy(numa_policy_get_type(policy), nodes, maxnode); - if (r < 0) - return -errno; - - return 0; -} - -static const char* const mpol_table[] = { - [MPOL_DEFAULT] = "default", - [MPOL_PREFERRED] = "preferred", - [MPOL_BIND] = "bind", - [MPOL_INTERLEAVE] = "interleave", - [MPOL_LOCAL] = "local", -}; - -DEFINE_STRING_TABLE_LOOKUP(mpol, int); diff --git a/src/shared/cpu-set-util.h b/src/shared/cpu-set-util.h index 27812dfd59..a60d4ec41b 100644 --- a/src/shared/cpu-set-util.h +++ b/src/shared/cpu-set-util.h @@ -49,30 +49,3 @@ int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated); int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set); int cpus_in_affinity_mask(void); - -static inline bool mpol_is_valid(int t) { - return t >= MPOL_DEFAULT && t <= MPOL_LOCAL; -} - -typedef struct NUMAPolicy { - /* Always use numa_policy_get_type() to read the value */ - int type; - CPUSet nodes; -} NUMAPolicy; - -bool numa_policy_is_valid(const NUMAPolicy *p); - -static inline int numa_policy_get_type(const NUMAPolicy *p) { - return p->type < 0 ? (p->nodes.set ? MPOL_PREFERRED : -1) : p->type; -} - -static inline void numa_policy_reset(NUMAPolicy *p) { - assert(p); - cpu_set_reset(&p->nodes); - p->type = -1; -} - -int apply_numa_policy(const NUMAPolicy *policy); - -const char* mpol_to_string(int i) _const_; -int mpol_from_string(const char *s) _pure_; diff --git a/src/shared/meson.build b/src/shared/meson.build index fa080f8e62..94174347a1 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -147,6 +147,8 @@ shared_sources = files(''' nscd-flush.h nsflags.c nsflags.h + numa-util.c + numa-util.h openssl-util.h os-util.c os-util.h diff --git a/src/shared/numa-util.c b/src/shared/numa-util.c new file mode 100644 index 0000000000..187992dc69 --- /dev/null +++ b/src/shared/numa-util.c @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include <errno.h> +#include <sched.h> + +#include "alloc-util.h" +#include "cpu-set-util.h" +#include "fileio.h" +#include "macro.h" +#include "missing_syscall.h" +#include "numa-util.h" +#include "stdio-util.h" +#include "string-table.h" + +bool numa_policy_is_valid(const NUMAPolicy *policy) { + assert(policy); + + if (!mpol_is_valid(numa_policy_get_type(policy))) + return false; + + if (!policy->nodes.set && + !IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED)) + return false; + + if (policy->nodes.set && + numa_policy_get_type(policy) == MPOL_PREFERRED && + CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1) + return false; + + return true; +} + +static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) { + unsigned node, bits = 0, ulong_bits; + _cleanup_free_ unsigned long *out = NULL; + + assert(policy); + assert(ret_maxnode); + assert(ret_nodes); + + if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL) || + (numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) { + *ret_nodes = NULL; + *ret_maxnode = 0; + return 0; + } + + bits = policy->nodes.allocated * 8; + ulong_bits = sizeof(unsigned long) * 8; + + out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long))); + if (!out) + return -ENOMEM; + + /* We don't make any assumptions about internal type libc is using to store NUMA node mask. + Hence we need to convert the node mask to the representation expected by set_mempolicy() */ + for (node = 0; node < bits; node++) + if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set)) + out[node / ulong_bits] |= 1ul << (node % ulong_bits); + + *ret_nodes = TAKE_PTR(out); + *ret_maxnode = bits + 1; + return 0; +} + +int apply_numa_policy(const NUMAPolicy *policy) { + int r; + _cleanup_free_ unsigned long *nodes = NULL; + unsigned long maxnode; + + assert(policy); + + if (get_mempolicy(NULL, NULL, 0, 0, 0) < 0 && errno == ENOSYS) + return -EOPNOTSUPP; + + if (!numa_policy_is_valid(policy)) + return -EINVAL; + + r = numa_policy_to_mempolicy(policy, &maxnode, &nodes); + if (r < 0) + return r; + + r = set_mempolicy(numa_policy_get_type(policy), nodes, maxnode); + if (r < 0) + return -errno; + + return 0; +} + +int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *ret) { + int r; + size_t i; + _cleanup_(cpu_set_reset) CPUSet s = {}; + + assert(policy); + assert(ret); + + for (i = 0; i < policy->nodes.allocated * 8; i++) { + _cleanup_free_ char *l = NULL; + char p[STRLEN("/sys/devices/system/node/node//cpulist") + DECIMAL_STR_MAX(size_t) + 1]; + _cleanup_(cpu_set_reset) CPUSet part = {}; + + if (!CPU_ISSET_S(i, policy->nodes.allocated, policy->nodes.set)) + continue; + + xsprintf(p, "/sys/devices/system/node/node%zu/cpulist", i); + + r = read_one_line_file(p, &l); + if (r < 0) + return r; + + r = parse_cpu_set(l, &part); + if (r < 0) + return r; + + r = cpu_set_add_all(&s, &part); + if (r < 0) + return r; + } + + *ret = s; + s = (CPUSet) {}; + + return 0; +} + +static const char* const mpol_table[] = { + [MPOL_DEFAULT] = "default", + [MPOL_PREFERRED] = "preferred", + [MPOL_BIND] = "bind", + [MPOL_INTERLEAVE] = "interleave", + [MPOL_LOCAL] = "local", +}; + +DEFINE_STRING_TABLE_LOOKUP(mpol, int); diff --git a/src/shared/numa-util.h b/src/shared/numa-util.h new file mode 100644 index 0000000000..c99178903b --- /dev/null +++ b/src/shared/numa-util.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "cpu-set-util.h" +#include "missing_syscall.h" + +static inline bool mpol_is_valid(int t) { + return t >= MPOL_DEFAULT && t <= MPOL_LOCAL; +} + +typedef struct NUMAPolicy { + /* Always use numa_policy_get_type() to read the value */ + int type; + CPUSet nodes; +} NUMAPolicy; + +bool numa_policy_is_valid(const NUMAPolicy *p); + +static inline int numa_policy_get_type(const NUMAPolicy *p) { + return p->type < 0 ? (p->nodes.set ? MPOL_PREFERRED : -1) : p->type; +} + +static inline void numa_policy_reset(NUMAPolicy *p) { + assert(p); + cpu_set_reset(&p->nodes); + p->type = -1; +} + +int apply_numa_policy(const NUMAPolicy *policy); +int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *set); + +const char* mpol_to_string(int i) _const_; +int mpol_from_string(const char *s) _pure_; |