#include "build.h"
#include "conf-files.h"
#include "constants.h"
+#include "cpu-set-util.h"
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
if (n_threads == UINT_MAX) {
/* By default, use a number of worker threads equal the number of online CPUs,
* but clamp it to avoid a probing storm on machines with many CPUs. */
- long ncpus = sysconf(_SC_NPROCESSORS_ONLN);
- if (ncpus < 0) {
- log_warning_errno(errno, "Failed to get number of online CPUs, ignoring: %m");
- ncpus = 1;
- }
-
- n_threads = CLAMP((unsigned)ncpus, 1U, 16U);
+ unsigned n_cpus;
+ r = cpus_online(&n_cpus);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get number of online CPUs, ignoring: %m");
+ n_threads = 1;
+ } else
+ n_threads = CLAMP(n_cpus, 1U, 16U);
}
/* There's no reason to spawn more threads than the modules that need to be loaded */
#include "alloc-util.h"
#include "bitfield.h"
+#include "cgroup-util.h"
#include "cpu-set-util.h"
#include "extract-word.h"
#include "log.h"
*ret = TAKE_STRUCT(c);
return 0;
}
+
+static int cgroup_cpus_effective(unsigned *ret) {
+ int r;
+
+ assert(ret);
+
+ _cleanup_free_ char *root = NULL;
+ r = cg_get_root_path(&root);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to determine root cgroup: %m");
+
+ _cleanup_free_ char *value = NULL;
+ r = cg_get_attribute(root, "cpuset.cpus.effective", &value);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to read cpuset.cpus.effective cgroup attribute: %m");
+
+ _cleanup_(cpu_set_done) CPUSet cpus = {};
+ r = parse_cpu_set(value, &cpus);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to parse cpuset.cpus.effective cgroup attribute: %m");
+
+ *ret = (unsigned) MIN(cpu_set_count(&cpus), UINT_MAX);
+ return 0;
+}
+
+int cpus_online(unsigned *ret) {
+ int r;
+
+ assert(ret);
+
+ /* In order to support containers nicely that have a configured cpuset we'll take the minimum of the
+ * physically reported amount of CPUs and the limit configured for the root cgroup, if there is
+ * any. */
+
+ long sc = sysconf(_SC_NPROCESSORS_ONLN);
+ if (sc < 0)
+ return log_debug_errno(errno, "sysconf(_SC_NPROCESSORS_ONLN) failed: %m");
+
+ unsigned cg, lc = (unsigned) CLAMP((unsigned long) sc, 1U, UINT_MAX);
+ r = cgroup_cpus_effective(&cg);
+ if (r < 0)
+ *ret = lc;
+ else
+ *ret = CLAMP(cg, 1U, lc);
+
+ return 0;
+}
ASSERT_OK(cpu_set_add_range(&c, 0, 8191));
}
+TEST(cpus_online) {
+ unsigned n_cpus = 0;
+ ASSERT_OK(cpus_online(&n_cpus));
+ ASSERT_GE(n_cpus, 1U);
+ log_info("Number of CPUs currently online: %u", n_cpus);
+}
+
DEFINE_TEST_MAIN(LOG_DEBUG);