[ovs-dev] [PATCH 2/2] lib: Determine cpu core count with /proc/cpuinfo
Joe Stringer
joestringer at nicira.com
Thu Dec 5 23:42:21 UTC 2013
On systems that provide /proc/cpuinfo similar to Linux on x86, this
should allow us to choose a better default value for the number of
upcall handler threads---in particular, it avoids counting hyper-thread
cores. If /proc/cpuinfo cannot be parsed for any reason, fall back to
using sysconf().
Signed-off-by: Joe Stringer <joestringer at nicira.com>
---
lib/ovs-thread.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 2 deletions(-)
diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
index 02436e5..f800d7d 100644
--- a/lib/ovs-thread.c
+++ b/lib/ovs-thread.c
@@ -310,12 +310,76 @@ may_fork(void)
return !must_not_fork;
}
+/* Parses /proc/cpuinfo for the total number of physical cores on this system
+ * across all CPU packages, not counting hyper-threads.
+ *
+ * Sets *n_cores to the total number of cores on this system, or 0 if the
+ * number cannot be determined. */
+static void
+parse_cpuinfo(long int *n_cores)
+{
+ static const char file_name[] = "/proc/cpuinfo";
+ char line[128];
+ uint64_t cpu = 0; /* Support up to 64 CPU packages on a single system. */
+ long int cores = 0;
+ FILE *stream;
+
+ stream = fopen(file_name, "r");
+ if (!stream) {
+ VLOG_WARN("%s: open failed (%s)", file_name, ovs_strerror(errno));
+ return;
+ }
+
+ while (fgets(line, sizeof line, stream)) {
+ unsigned int id;
+
+ /* Find the next CPU package. */
+ if (ovs_scan(line, "physical id%*[^:]: %u", &id)) {
+ if (id > 63) {
+ VLOG_WARN("Counted over 64 CPU packages on this system. "
+ "Parsing %s for core count may be inaccurate.",
+ file_name);
+ cores = 0;
+ break;
+ }
+
+ if (cpu & (1 << id)) {
+ /* We've already counted this package's cores. */
+ continue;
+ }
+ cpu |= 1 << id;
+
+ /* Find the number of cores for this package. */
+ while (fgets(line, sizeof line, stream)) {
+ int count;
+
+ if (ovs_scan(line, "cpu cores%*[^:]: %u", &count)) {
+ cores += count;
+ break;
+ }
+ }
+ }
+ }
+ fclose(stream);
+
+ *n_cores = cores;
+}
+
/* Returns the total number of cores on this system, or 0 if the number cannot
- * be determined. */
+ * be determined.
+ *
+ * Tries not to count hyper-threads, but may be inaccurate - particularly on
+ * platforms that do not provide /proc/cpuinfo, but also if /proc/cpuinfo is
+ * formatted different to the layout that parse_cpuinfo() expects. */
unsigned int
count_cpu_cores(void)
{
- long int n_cores = sysconf(_SC_NPROCESSORS_ONLN);
+ long int n_cores;
+
+ parse_cpuinfo(&n_cores);
+ if (!n_cores) {
+ n_cores = sysconf(_SC_NPROCESSORS_ONLN);
+ }
return n_cores > 0 ? n_cores : 0;
}
--
1.7.9.5
More information about the dev
mailing list