[ovs-dev] [PATCH ovn] northd: Add config option to specify # of threads

Numan Siddique numans at ovn.org
Wed Jul 14 21:54:52 UTC 2021


On Wed, Jul 7, 2021 at 3:15 AM Fabrizio D'Angelo <fdangelo at redhat.com> wrote:
>
> Uses northd database to specify number of threads that should be used
> when lflow parallel computation is enabled.
>
> Example:
>     ovn-nbctl set NB_Global . options:num_parallel_threads=16
>
> Reported at:
>     https://bugzilla.redhat.com/show_bug.cgi?id=1975345
>
> Signed-off-by: Fabrizio D'Angelo <fdangelo at redhat.com>

Hi Fabrizio,

Thanks for the patch.

I tested this patch and I don't think it is working as expected.
Mainly because of the way ovn-parallel-hmap.c
sets up the pools.

When ovn-northd is started, it calls ovn_can_parallelize_hashes()
first and this sets up the worker pools
by calling setup_worker_pools().

The function setup_worker_pools() is never called later because of
atomic_compare_exchange_strong()
present in ovn_can_parallelize_hashes() and ovn_add_worker_pool().

I think unfortunately it requires some fixes there so that when the
number of threads is configured later, it takes
into effect.  Right now it doesn't.

I think ovn_can_parallelize_hashes() should not try to setup the pool
size, instead it should check if ovn-northd
can do parallelization or not based on the ovs_numa_get_n_cores() and
ovs_numa_get_n_numas().
And if force is set, it should enable parallel processing.

Would you mind taking another look at the functions -
setup_worker_pools(), ovn_can_parallelize_hashes()
and ovn_add_worker_pool()  ?  So that we can enable or disable
parallelization dynamically
and also override the pool size with your newly added option -
num_parallel_threads.

Thanks
Numan

> ---
>  lib/ovn-parallel-hmap.c | 12 ++++++------
>  lib/ovn-parallel-hmap.h |  5 +++--
>  northd/ovn-northd.c     |  7 ++++++-
>  ovn-nb.xml              | 10 ++++++++++
>  4 files changed, 25 insertions(+), 9 deletions(-)
>
> diff --git a/lib/ovn-parallel-hmap.c b/lib/ovn-parallel-hmap.c
> index b8c7ac786..cae0b3110 100644
> --- a/lib/ovn-parallel-hmap.c
> +++ b/lib/ovn-parallel-hmap.c
> @@ -62,7 +62,7 @@ static int pool_size;
>  static int sembase;
>
>  static void worker_pool_hook(void *aux OVS_UNUSED);
> -static void setup_worker_pools(bool force);
> +static void setup_worker_pools(bool force, unsigned int thread_num);
>  static void merge_list_results(struct worker_pool *pool OVS_UNUSED,
>                                 void *fin_result, void *result_frags,
>                                 int index);
> @@ -86,14 +86,14 @@ ovn_can_parallelize_hashes(bool force_parallel)
>              &test,
>              true)) {
>          ovs_mutex_lock(&init_mutex);
> -        setup_worker_pools(force_parallel);
> +        setup_worker_pools(force_parallel, 0);
>          ovs_mutex_unlock(&init_mutex);
>      }
>      return can_parallelize;
>  }
>
>  struct worker_pool *
> -ovn_add_worker_pool(void *(*start)(void *))
> +ovn_add_worker_pool(void *(*start)(void *), unsigned int thread_num)

I'd suggest renaming the parameter from 'thread_num' to 'num_threads'.

Thanks
Numan

>  {
>      struct worker_pool *new_pool = NULL;
>      struct worker_control *new_control;
> @@ -109,7 +109,7 @@ ovn_add_worker_pool(void *(*start)(void *))
>              &test,
>              true)) {
>          ovs_mutex_lock(&init_mutex);
> -        setup_worker_pools(false);
> +        setup_worker_pools(false, thread_num);
>          ovs_mutex_unlock(&init_mutex);
>      }
>
> @@ -401,14 +401,14 @@ worker_pool_hook(void *aux OVS_UNUSED) {
>  }
>
>  static void
> -setup_worker_pools(bool force) {
> +setup_worker_pools(bool force, unsigned int thread_num) {
>      int cores, nodes;
>
>      nodes = ovs_numa_get_n_numas();
>      if (nodes == OVS_NUMA_UNSPEC || nodes <= 0) {
>          nodes = 1;
>      }
> -    cores = ovs_numa_get_n_cores();
> +    cores = thread_num ? thread_num : ovs_numa_get_n_cores();
>
>      /* If there is no NUMA config, use 4 cores.
>       * If there is NUMA config use half the cores on
> diff --git a/lib/ovn-parallel-hmap.h b/lib/ovn-parallel-hmap.h
> index 0af8914c4..9637a273d 100644
> --- a/lib/ovn-parallel-hmap.h
> +++ b/lib/ovn-parallel-hmap.h
> @@ -95,7 +95,8 @@ struct worker_pool {
>  /* Add a worker pool for thread function start() which expects a pointer to
>   * a worker_control structure as an argument. */
>
> -struct worker_pool *ovn_add_worker_pool(void *(*start)(void *));
> +struct worker_pool *ovn_add_worker_pool(void *(*start)(void *),
> +                                        unsigned int thread_num);
>
>  /* Setting this to true will make all processing threads exit */
>
> @@ -265,7 +266,7 @@ bool ovn_can_parallelize_hashes(bool force_parallel);
>
>  #define stop_parallel_processing() ovn_stop_parallel_processing()
>
> -#define add_worker_pool(start) ovn_add_worker_pool(start)
> +#define add_worker_pool(start, thread_num) ovn_add_worker_pool(start, thread_num)
>
>  #define fast_hmap_size_for(hmap, size) ovn_fast_hmap_size_for(hmap, size)
>
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index 570c6a3ef..ffefac361 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -4153,6 +4153,7 @@ ovn_lflow_init(struct ovn_lflow *lflow, struct ovn_datapath *od,
>   * logical datapath only by creating a datapath group. */
>  static bool use_logical_dp_groups = false;
>  static bool use_parallel_build = true;
> +static unsigned int num_parallel_threads;
>
>  static struct hashrow_locks lflow_locks;
>
> @@ -12219,7 +12220,8 @@ init_lflows_thread_pool(void)
>      int index;
>
>      if (!pool_init_done) {
> -        struct worker_pool *pool = add_worker_pool(build_lflows_thread);
> +        struct worker_pool *pool = add_worker_pool(build_lflows_thread,
> +                                                   num_parallel_threads);
>          pool_init_done = true;
>          if (pool) {
>              build_lflows_pool = xmalloc(sizeof(*build_lflows_pool));
> @@ -13456,6 +13458,9 @@ ovnnb_db_run(struct northd_context *ctx,
>          (smap_get_bool(&nb->options, "use_parallel_build", false) &&
>           ovn_can_parallelize_hashes(false));
>
> +    num_parallel_threads =
> +        smap_get_uint(&nb->options, "num_parallel_threads", 0);
> +
>      use_logical_dp_groups = smap_get_bool(&nb->options,
>                                            "use_logical_dp_groups", false);
>      use_ct_inv_match = smap_get_bool(&nb->options,
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 36a77097c..d5bfb7ece 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -226,6 +226,16 @@
>            The default value is <code>false</code>.
>          </p>
>        </column>
> +      <column name="options" key="num_parallel_threads">
> +        <p>
> +          Manually specify the number of threads to be used for parallel
> +          logical flow computation.
> +        </p>
> +        <p>
> +          The number of threads utilized will be determined by the number
> +          of vCPUs on the system if this value is not specified.
> +        </p>
> +      </column>
>
>        <column name="options" key="ignore_lsp_down">
>          <p>
> --
> 2.31.1
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>


More information about the dev mailing list