Currently, things like the number of handler and revalidator threads are
calculated based on the number of available CPUs. However, this number
is considered static and only calculated once, hence ignoring events
such as cpus being hotplugged, switched on/off or affinity mask
changing.

This patch makes the number of cpus be calculated every time it's
needed.

As a result of these changes (assuming the patch is backported):
- >=2.16: a change in the cpu affinity immediately reflects on
  the number of threads.
- < 2.16: a change in the cpu affinity will be reflected on
  the number of threads the next time there is a call to
  bridge_reconfigure() (e.g: on the next DB change).

The difference in behavior is because on older versions the thread
number calculation was done on bridge reconfiguration while newer
versions moved this logic down to the dpif layer and is run on
dpif->run() stage.
Considering it has not been a huge problem up to today and that the
cpu change would be reflected sooner or later (e.g the user could
force a recalculation with a simple ovs-vsctl command), I think it
might be OK to leave like that.

Fixes: be15ec48d766 ("lib: Use a more accurate value for CPU count 
(sched_getaffinity).")
Cc: [email protected]
Signed-off-by: Adrian Moreno <[email protected]>
---
 lib/ovs-thread.c | 39 +++++++++++++++++----------------------
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
index 78ed3e970..226c61c27 100644
--- a/lib/ovs-thread.c
+++ b/lib/ovs-thread.c
@@ -627,39 +627,34 @@ ovs_thread_stats_next_bucket(const struct ovsthread_stats 
*stats, size_t i)
 }
 
 
-/* Returns the total number of cores available to this process, or 0 if the
- * number cannot be determined. */
+/* Returns the current total number of cores available to this process, or 0
+ * if the number cannot be determined. */
 int
 count_cpu_cores(void)
 {
-    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
-    static long int n_cores;
+    long int n_cores;
 
-    if (ovsthread_once_start(&once)) {
 #ifndef _WIN32
-        n_cores = sysconf(_SC_NPROCESSORS_ONLN);
+    n_cores = sysconf(_SC_NPROCESSORS_ONLN);
+#else
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo(&sysinfo);
+    n_cores = sysinfo.dwNumberOfProcessors;
+#endif
 #ifdef __linux__
-        if (n_cores > 0) {
-            cpu_set_t *set = CPU_ALLOC(n_cores);
+    if (n_cores > 0) {
+        cpu_set_t *set = CPU_ALLOC(n_cores);
 
-            if (set) {
-                size_t size = CPU_ALLOC_SIZE(n_cores);
+        if (set) {
+            size_t size = CPU_ALLOC_SIZE(n_cores);
 
-                if (!sched_getaffinity(0, size, set)) {
-                    n_cores = CPU_COUNT_S(size, set);
-                }
-                CPU_FREE(set);
+            if (!sched_getaffinity(0, size, set)) {
+                n_cores = CPU_COUNT_S(size, set);
             }
+            CPU_FREE(set);
         }
-#endif
-#else
-        SYSTEM_INFO sysinfo;
-        GetSystemInfo(&sysinfo);
-        n_cores = sysinfo.dwNumberOfProcessors;
-#endif
-        ovsthread_once_done(&once);
     }
-
+#endif
     return n_cores > 0 ? n_cores : 0;
 }
 
-- 
2.37.3

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to