On 19 Oct 2022, at 15:01, Mike Pattrick wrote:

> Previously the minimum thread stack size was always set to 512 kB to
> help accomidate smaller OpenWRT based systems. Often these devices
> don't have a lot of total system memory, so such a limit makes sense.
>
> The default under x86-64 linux is 2MB, this limit is not always enough
> to reach the recursion limits in xlate_resubmit_resource_check(),
> resulting in a segfault instead of a recoverable error. This can happen
> even when the stack size is set up for unlimited expansion when the
> virtaul memory areas of handler threads abut eachother, preventing any
> further expansion.
>
> The solution proposed here is to set a minimum of 4MB on systems with
> more than 4GB of total ram.
>
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2104779
> Signed-off-by: Mike Pattrick <m...@redhat.com>
> ---
>  lib/ovs-thread.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
>  lib/ovs-thread.h |  1 +
>  2 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
> index 78ed3e970..dbe4a036f 100644
> --- a/lib/ovs-thread.c
> +++ b/lib/ovs-thread.c
> @@ -478,10 +478,21 @@ ovs_thread_create(const char *name, void *(*start)(void 
> *), void *arg)
>       * requires approximately 384 kB according to the following analysis:
>       * 
> https://mail.openvswitch.org/pipermail/ovs-dev/2016-January/308592.html
>       *
> -     * We use 512 kB to give us some margin of error. */
> +     * We use at least 512 kB to give us some margin of error.
> +     *
> +     * However, this can cause issues on larger systems with complex
> +     * OpenFlow tables. A default stack size of 2MB can result in segfaults
> +     * if a lot of clones and resubmits are used. So if the system memory
> +     * exceeds some limit then use a 4 MB stack.

Any reason to choose 4G? Asking as users might be asking why after an upgrade I 
use more memory, for example, the microshift project.

I think it would be better to make this configurable on the command line.

I did not research but are there kernel-specific ways to maximise the stack 
distance to allow the stack to easily grow? Guess this is pthread related also.

> +     * */
>      pthread_attr_t attr;
>      pthread_attr_init(&attr);
> -    set_min_stack_size(&attr, 512 * 1024);
> +
> +    if (system_memory() >> 30 > 4) {
> +        set_min_stack_size(&attr, 4096 * 1024);
> +    } else {
> +        set_min_stack_size(&attr, 512 * 1024);
> +    }
>
>      error = pthread_create(&thread, &attr, ovsthread_wrapper, aux);
>      if (error) {
> @@ -680,6 +691,37 @@ count_total_cores(void)
>      return n_cores > 0 ? n_cores : 0;
>  }
>
> +/* Returns the total system memory in bytes, or 0 if the
> + * number cannot be determined. */
> +uint64_t
> +system_memory(void)
> +{
> +    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
> +    static uint64_t memory;
> +
> +    if (ovsthread_once_start(&once)) {
> +#if defined(_WIN32)
> +        MEMORYSTATUSEX statex;
> +
> +        statex.dwLength = sizeof statex;
> +        GlobalMemoryStatusEx(&statex);
> +        memory = statex.ullTotalPhys;
> +#elif defined(__linux__)
> +        long int page_count = sysconf(_SC_PHYS_PAGES);
> +        long int page_size = sysconf(_SC_PAGESIZE);
> +
> +        if (page_count > 0 && page_size > 0) {
> +            memory = page_count * page_size;
> +        } else {
> +            memory = 0;
> +        }

Under Linux there is also the sysinfo() call, but not sure what would be 
preferred.

> +#endif
> +        ovsthread_once_done(&once);
> +    }
> +

Guess on BDS we would return an initialized variable. We probably need a 
wrapper for that also.

> +    return memory;
> +}
> +
>  /* Returns 'true' if current thread is PMD thread. */
>  bool
>  thread_is_pmd(void)
> diff --git a/lib/ovs-thread.h b/lib/ovs-thread.h
> index aac5e19c9..2ce66b721 100644
> --- a/lib/ovs-thread.h
> +++ b/lib/ovs-thread.h
> @@ -523,6 +523,7 @@ bool may_fork(void);
>
>  int count_cpu_cores(void);
>  int count_total_cores(void);
> +uint64_t system_memory(void);
>  bool thread_is_pmd(void);
>
>  #endif /* ovs-thread.h */
> -- 
> 2.31.1
>
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to