Filling arrays of switches and routers for load balancers one-by-one is not very efficient. Copying them in bulk allows to save a noticeable amount of time in setups with large load balancer groups.
Signed-off-by: Ilya Maximets <[email protected]> --- lib/lb.c | 16 ++++++++++------ lib/lb.h | 8 ++++---- northd/northd.c | 41 +++++++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/lib/lb.c b/lib/lb.c index 7b0ed1abe..fe6070a40 100644 --- a/lib/lb.c +++ b/lib/lb.c @@ -239,23 +239,27 @@ ovn_northd_lb_find(struct hmap *lbs, const struct uuid *uuid) } void -ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, struct ovn_datapath *od) +ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, size_t n, + struct ovn_datapath **ods) { - if (lb->n_allocated_nb_lr == lb->n_nb_lr) { + while (lb->n_allocated_nb_lr <= lb->n_nb_lr + n) { lb->nb_lr = x2nrealloc(lb->nb_lr, &lb->n_allocated_nb_lr, sizeof *lb->nb_lr); } - lb->nb_lr[lb->n_nb_lr++] = od; + memcpy(&lb->nb_lr[lb->n_nb_lr], ods, n * sizeof *ods); + lb->n_nb_lr += n; } void -ovn_northd_lb_add_ls(struct ovn_northd_lb *lb, struct ovn_datapath *od) +ovn_northd_lb_add_ls(struct ovn_northd_lb *lb, size_t n, + struct ovn_datapath **ods) { - if (lb->n_allocated_nb_ls == lb->n_nb_ls) { + while (lb->n_allocated_nb_ls <= lb->n_nb_ls + n) { lb->nb_ls = x2nrealloc(lb->nb_ls, &lb->n_allocated_nb_ls, sizeof *lb->nb_ls); } - lb->nb_ls[lb->n_nb_ls++] = od; + memcpy(&lb->nb_ls[lb->n_nb_ls], ods, n * sizeof *ods); + lb->n_nb_ls += n; } void diff --git a/lib/lb.h b/lib/lb.h index 832ed31fb..d7bc28e18 100644 --- a/lib/lb.h +++ b/lib/lb.h @@ -88,10 +88,10 @@ struct ovn_northd_lb_backend { struct ovn_northd_lb *ovn_northd_lb_create(const struct nbrec_load_balancer *); struct ovn_northd_lb * ovn_northd_lb_find(struct hmap *, const struct uuid *); void ovn_northd_lb_destroy(struct ovn_northd_lb *); -void -ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, struct ovn_datapath *od); -void -ovn_northd_lb_add_ls(struct ovn_northd_lb *lb, struct ovn_datapath *od); +void ovn_northd_lb_add_lr(struct ovn_northd_lb *lb, size_t n, + struct ovn_datapath **ods); +void ovn_northd_lb_add_ls(struct ovn_northd_lb *lb, size_t n, + struct ovn_datapath **ods); struct ovn_controller_lb { const struct sbrec_load_balancer *slb; /* May be NULL. */ diff --git a/northd/northd.c b/northd/northd.c index b66843581..c202d27d5 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -3845,7 +3845,9 @@ struct ovn_lb_group { struct hmap_node hmap_node; struct uuid uuid; size_t n; - struct ovn_northd_lb *lbs[]; + struct ovn_northd_lb **lbs; + size_t n_od; + struct ovn_datapath **ods; }; static struct ovn_lb_group * @@ -3883,12 +3885,11 @@ build_lbs(struct northd_input *input_data, struct hmap *datapaths, NBREC_LOAD_BALANCER_GROUP_TABLE_FOR_EACH (nbrec_lb_group, input_data->nbrec_load_balancer_group_table) { - size_t size = sizeof *lb_group + - nbrec_lb_group->n_load_balancer * sizeof(struct ovn_northd_lb *); - - lb_group = xzalloc(size); + lb_group = xzalloc(sizeof *lb_group); lb_group->uuid = nbrec_lb_group->header_.uuid; lb_group->n = nbrec_lb_group->n_load_balancer; + lb_group->lbs = xzalloc(lb_group->n * sizeof *lb_group->lbs); + lb_group->ods = xzalloc(hmap_count(datapaths) * sizeof *lb_group->ods); for (size_t i = 0; i < nbrec_lb_group->n_load_balancer; i++) { const struct uuid *lb_uuid = @@ -3910,19 +3911,25 @@ build_lbs(struct northd_input *input_data, struct hmap *datapaths, const struct uuid *lb_uuid = &od->nbs->load_balancer[i]->header_.uuid; lb = ovn_northd_lb_find(lbs, lb_uuid); - ovn_northd_lb_add_ls(lb, od); + ovn_northd_lb_add_ls(lb, 1, &od); } for (size_t i = 0; i < od->nbs->n_load_balancer_group; i++) { nbrec_lb_group = od->nbs->load_balancer_group[i]; lb_group = ovn_lb_group_find(lb_groups, &nbrec_lb_group->header_.uuid); - for (size_t j = 0; j < lb_group->n; j++) { - ovn_northd_lb_add_ls(lb_group->lbs[j], od); - } + lb_group->ods[lb_group->n_od++] = od; } } + HMAP_FOR_EACH (lb_group, hmap_node, lb_groups) { + for (size_t j = 0; j < lb_group->n; j++) { + ovn_northd_lb_add_ls(lb_group->lbs[j], lb_group->n_od, + lb_group->ods); + } + lb_group->n_od = 0; + } + HMAP_FOR_EACH (od, key_node, datapaths) { if (!od->nbr) { continue; @@ -3932,7 +3939,7 @@ build_lbs(struct northd_input *input_data, struct hmap *datapaths, const struct uuid *lb_uuid = &od->nbr->load_balancer[i]->header_.uuid; lb = ovn_northd_lb_find(lbs, lb_uuid); - ovn_northd_lb_add_lr(lb, od); + ovn_northd_lb_add_lr(lb, 1, &od); build_lrouter_lb_ips(od, lb); } @@ -3940,12 +3947,20 @@ build_lbs(struct northd_input *input_data, struct hmap *datapaths, nbrec_lb_group = od->nbr->load_balancer_group[i]; lb_group = ovn_lb_group_find(lb_groups, &nbrec_lb_group->header_.uuid); + lb_group->ods[lb_group->n_od++] = od; for (size_t j = 0; j < lb_group->n; j++) { - ovn_northd_lb_add_lr(lb_group->lbs[j], od); build_lrouter_lb_ips(od, lb_group->lbs[j]); } } } + + HMAP_FOR_EACH (lb_group, hmap_node, lb_groups) { + for (size_t j = 0; j < lb_group->n; j++) { + ovn_northd_lb_add_lr(lb_group->lbs[j], lb_group->n_od, + lb_group->ods); + } + lb_group->n_od = 0; + } } static void @@ -4130,7 +4145,7 @@ build_lswitch_lbs_from_lrouter(struct hmap *datapaths, struct hmap *lbs) } } if (!installed) { - ovn_northd_lb_add_ls(lb, od); + ovn_northd_lb_add_ls(lb, 1, &od); } if (lb->nlb) { od->has_lb_vip |= lb_has_vip(lb->nlb); @@ -15403,6 +15418,8 @@ northd_destroy(struct northd_data *data) struct ovn_lb_group *lb_group; HMAP_FOR_EACH_POP (lb_group, hmap_node, &data->lb_groups) { + free(lb_group->lbs); + free(lb_group->ods); free(lb_group); } hmap_destroy(&data->lb_groups); -- 2.34.3 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
