diff mbox series

[ovs-dev,1/2] ovs-thread: Detect changes in cpu affinity

Message ID 20220826132754.360124-2-amorenoz@redhat.com
State Superseded
Headers show
Series Detect changes in cpu affinity | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Adrian Moreno Aug. 26, 2022, 1:27 p.m. UTC
It might be OK to consider the total number of online CPUs as a static
value (although certain platforms do support CPU hot-plugging and CPUs
can get disabled).
However, it's much more likely that ovs-vswitchd's CPU affinity mask
is modified dynamically.

Fix cpu calculation to detect changes in CPU affinity dynamically.

Fixes: be15ec48d766 ("lib: Use a more accurate value for CPU count (sched_getaffinity).")
Cc: david.marchand@redhat.com
Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
---
 lib/ovs-thread.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

Comments

David Marchand Aug. 29, 2022, 9:32 a.m. UTC | #1
On Fri, Aug 26, 2022 at 3:28 PM Adrian Moreno <amorenoz@redhat.com> wrote:
>
> It might be OK to consider the total number of online CPUs as a static
> value (although certain platforms do support CPU hot-plugging and CPUs
> can get disabled).
> However, it's much more likely that ovs-vswitchd's CPU affinity mask
> is modified dynamically.
>
> Fix cpu calculation to detect changes in CPU affinity dynamically.
>
> Fixes: be15ec48d766 ("lib: Use a more accurate value for CPU count (sched_getaffinity).")
> Cc: david.marchand@redhat.com
> Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
> ---
>  lib/ovs-thread.c | 36 +++++++++++++++++++-----------------
>  1 file changed, 19 insertions(+), 17 deletions(-)
>
> diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
> index 78ed3e970..0e52a0da7 100644
> --- a/lib/ovs-thread.c
> +++ b/lib/ovs-thread.c
> @@ -633,33 +633,35 @@ int
>  count_cpu_cores(void)
>  {
>      static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
> -    static long int n_cores;
> +    static long int n_total_cores;
> +    long int n_cores;
>
>      if (ovsthread_once_start(&once)) {
>  #ifndef _WIN32
> -        n_cores = sysconf(_SC_NPROCESSORS_ONLN);
> -#ifdef __linux__
> -        if (n_cores > 0) {
> -            cpu_set_t *set = CPU_ALLOC(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);
> -            }
> -        }
> -#endif
> +        n_total_cores = sysconf(_SC_NPROCESSORS_ONLN);
>  #else
>          SYSTEM_INFO sysinfo;
>          GetSystemInfo(&sysinfo);
> -        n_cores = sysinfo.dwNumberOfProcessors;
> +        n_total_cores = sysinfo.dwNumberOfProcessors;
>  #endif
>          ovsthread_once_done(&once);
>      }
>
> +    n_cores = n_total_cores;
> +#ifdef __linux__
> +    if (n_cores > 0) {
> +        cpu_set_t *set = CPU_ALLOC(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);
> +        }
> +    }
> +#endif
>      return n_cores > 0 ? n_cores : 0;
>  }

If we are changing this helper to provide the *current* core count for
Linux, I would have it behave the same for all OS.
And the simpler might be to drop the once check and the static
qualifier on n_cores.
WDYT?
Adrian Moreno Aug. 29, 2022, 10:29 a.m. UTC | #2
Thanks for the review David!

On 8/29/22 11:32, David Marchand wrote:
> On Fri, Aug 26, 2022 at 3:28 PM Adrian Moreno <amorenoz@redhat.com> wrote:
>>
>> It might be OK to consider the total number of online CPUs as a static
>> value (although certain platforms do support CPU hot-plugging and CPUs
>> can get disabled).
>> However, it's much more likely that ovs-vswitchd's CPU affinity mask
>> is modified dynamically.
>>
>> Fix cpu calculation to detect changes in CPU affinity dynamically.
>>
>> Fixes: be15ec48d766 ("lib: Use a more accurate value for CPU count (sched_getaffinity).")
>> Cc: david.marchand@redhat.com
>> Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
>> ---
>>   lib/ovs-thread.c | 36 +++++++++++++++++++-----------------
>>   1 file changed, 19 insertions(+), 17 deletions(-)
>>
>> diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
>> index 78ed3e970..0e52a0da7 100644
>> --- a/lib/ovs-thread.c
>> +++ b/lib/ovs-thread.c
>> @@ -633,33 +633,35 @@ int
>>   count_cpu_cores(void)
>>   {
>>       static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
>> -    static long int n_cores;
>> +    static long int n_total_cores;
>> +    long int n_cores;
>>
>>       if (ovsthread_once_start(&once)) {
>>   #ifndef _WIN32
>> -        n_cores = sysconf(_SC_NPROCESSORS_ONLN);
>> -#ifdef __linux__
>> -        if (n_cores > 0) {
>> -            cpu_set_t *set = CPU_ALLOC(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);
>> -            }
>> -        }
>> -#endif
>> +        n_total_cores = sysconf(_SC_NPROCESSORS_ONLN);
>>   #else
>>           SYSTEM_INFO sysinfo;
>>           GetSystemInfo(&sysinfo);
>> -        n_cores = sysinfo.dwNumberOfProcessors;
>> +        n_total_cores = sysinfo.dwNumberOfProcessors;
>>   #endif
>>           ovsthread_once_done(&once);
>>       }
>>
>> +    n_cores = n_total_cores;
>> +#ifdef __linux__
>> +    if (n_cores > 0) {
>> +        cpu_set_t *set = CPU_ALLOC(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);
>> +        }
>> +    }
>> +#endif
>>       return n_cores > 0 ? n_cores : 0;
>>   }
> 
> If we are changing this helper to provide the *current* core count for
> Linux, I would have it behave the same for all OS.
> And the simpler might be to drop the once check and the static
> qualifier on n_cores.
> WDYT?
> 

Yes, I did consider it. I don't have a very strong opinion about it. I ended up 
laying towards keeping the static qualifier on other OSs because the chances a 
CPU is hotplugged or disabled/enabled at runtime are very low compared to those 
of the affinity mask being changed. Cost-wise, even though this is run on every 
bridge loop iteration I don't think it's very expensive. All in all, I ended up 
preferring not enabling what seems to me as almost-useless behavior vs cross-OS 
homogenization.

But again, If you do think it's better to keep behavior homogeneous or see a 
use-case where _SC_NPROCESSORS_ONLN are likely to change, I'll update the patch.

BTW, I did notice that, in the function added later on (count_total_cores) by 
Michael Santana, _SC_NPROCESSORS_CONF was used. Michael, do you have any issues 
with changing it to _SC_NPROCESSORS_ONLN?

Thanks.
diff mbox series

Patch

diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
index 78ed3e970..0e52a0da7 100644
--- a/lib/ovs-thread.c
+++ b/lib/ovs-thread.c
@@ -633,33 +633,35 @@  int
 count_cpu_cores(void)
 {
     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
-    static long int n_cores;
+    static long int n_total_cores;
+    long int n_cores;
 
     if (ovsthread_once_start(&once)) {
 #ifndef _WIN32
-        n_cores = sysconf(_SC_NPROCESSORS_ONLN);
-#ifdef __linux__
-        if (n_cores > 0) {
-            cpu_set_t *set = CPU_ALLOC(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);
-            }
-        }
-#endif
+        n_total_cores = sysconf(_SC_NPROCESSORS_ONLN);
 #else
         SYSTEM_INFO sysinfo;
         GetSystemInfo(&sysinfo);
-        n_cores = sysinfo.dwNumberOfProcessors;
+        n_total_cores = sysinfo.dwNumberOfProcessors;
 #endif
         ovsthread_once_done(&once);
     }
 
+    n_cores = n_total_cores;
+#ifdef __linux__
+    if (n_cores > 0) {
+        cpu_set_t *set = CPU_ALLOC(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);
+        }
+    }
+#endif
     return n_cores > 0 ? n_cores : 0;
 }