[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