Ben Pfaff <b...@ovn.org> wrote on 08/31/2016 12:38:34 PM: > From: Ben Pfaff <b...@ovn.org> > To: Ryan Moats/Omaha/IBM@IBMUS > Cc: dev@openvswitch.org > Date: 08/31/2016 12:38 PM > Subject: Re: [ovs-dev,v2,3/4] Unpersist data structures for address sets. > > On Wed, Aug 31, 2016 at 03:22:45PM +0000, Ryan Moats wrote: > > With the removal of incremental processing, it is no longer > > necessary to persist the data structures for storing address > > sets. Simplify things by removing this complexity. > > > > Side effect: fixed a memory leak in expr_macros_destroy that > > is evidenced by this change. > > > > Signed-off-by: Ryan Moats <rmo...@us.ibm.com> > > I think that this was still doing a lot more work than necessary. The > "struct address_set"s were being created and destroyed but not used for > anything in between. > > Here's my proposal. Comments? > > --8<--------------------------cut here-------------------------->8-- > > From: Ryan Moats <rmo...@us.ibm.com> > Date: Wed, 31 Aug 2016 15:22:45 +0000 > Subject: [PATCH] Unpersist data structures for address sets. > > With the removal of incremental processing, it is no longer > necessary to persist the data structures for storing address > sets. Simplify things by removing this complexity. > > Side effect: fixed a memory leak in expr_macros_destroy that > is evidenced by this change. > > Signed-off-by: Ryan Moats <rmo...@us.ibm.com> > Signed-off-by: Ben Pfaff <b...@ovn.org> > --- > ovn/controller/lflow.c | 176 ++++++ > +------------------------------------------ > ovn/lib/expr.c | 1 + > 2 files changed, 25 insertions(+), 152 deletions(-) > > diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c > index a9c3137..efac5b3 100644 > --- a/ovn/controller/lflow.c > +++ b/ovn/controller/lflow.c > @@ -38,159 +38,24 @@ VLOG_DEFINE_THIS_MODULE(lflow); > /* Contains "struct expr_symbol"s for fields supported by OVN lflows. */ > static struct shash symtab; > > -/* Contains an internal expr datastructure that represents an address set. */ > -static struct shash expr_address_sets; > - > void > lflow_init(void) > { > ovn_init_symtab(&symtab); > - shash_init(&expr_address_sets); > -} > - > -/* Details of an address set currently in address_sets. We keep a cached > - * copy of sets still in their string form here to make it easier to compare > - * with the current values in the OVN_Southbound database. */ > -struct address_set { > - char **addresses; > - size_t n_addresses; > -}; > - > -/* struct address_set instances for address sets currently in the symtab, > - * hashed on the address set name. */ > -static struct shash local_address_sets = > SHASH_INITIALIZER(&local_address_sets); > - > -static int > -addr_cmp(const void *p1, const void *p2) > -{ > - const char *s1 = p1; > - const char *s2 = p2; > - return strcmp(s1, s2); > -} > - > -/* Return true if the address sets match, false otherwise. */ > -static bool > -address_sets_match(const struct address_set *addr_set, > - const struct sbrec_address_set *addr_set_rec) > -{ > - char **addrs1; > - char **addrs2; > - > - if (addr_set->n_addresses != addr_set_rec->n_addresses) { > - return false; > - } > - size_t n_addresses = addr_set->n_addresses; > - > - addrs1 = xmemdup(addr_set->addresses, > - n_addresses * sizeof addr_set->addresses[0]); > - addrs2 = xmemdup(addr_set_rec->addresses, > - n_addresses * sizeof addr_set_rec->addresses[0]); > - > - qsort(addrs1, n_addresses, sizeof *addrs1, addr_cmp); > - qsort(addrs2, n_addresses, sizeof *addrs2, addr_cmp); > - > - bool res = true; > - size_t i; > - for (i = 0; i < n_addresses; i++) { > - if (strcmp(addrs1[i], addrs2[i])) { > - res = false; > - break; > - } > - } > - > - free(addrs1); > - free(addrs2); > - > - return res; > } > > +/* Iterate address sets in the southbound database. Create and update the > + * corresponding symtab entries as necessary. */ > static void > -address_set_destroy(struct address_set *addr_set) > -{ > - size_t i; > - for (i = 0; i < addr_set->n_addresses; i++) { > - free(addr_set->addresses[i]); > - } > - if (addr_set->n_addresses) { > - free(addr_set->addresses); > - } > - free(addr_set); > -} > +update_address_sets(struct controller_ctx *ctx, > + struct shash *expr_address_sets_p) > > -static void > -update_address_sets(struct controller_ctx *ctx) > { > - /* Remember the names of all address sets currently in expr_address_sets > - * so we can detect address sets that have been deleted. */ > - struct sset cur_addr_set_names = SSET_INITIALIZER (&cur_addr_set_names); > - > - struct shash_node *node; > - SHASH_FOR_EACH (node, &local_address_sets) { > - sset_add(&cur_addr_set_names, node->name); > + const struct sbrec_address_set *as; > + SBREC_ADDRESS_SET_FOR_EACH (as, ctx->ovnsb_idl) { > + expr_macros_add(expr_address_sets_p, as->name, > + (const char *const *) as->addresses, > as->n_addresses); > } > - > - /* Iterate address sets in the southbound database. Create andupdate the > - * corresponding symtab entries as necessary. */ > - const struct sbrec_address_set *addr_set_rec; > - SBREC_ADDRESS_SET_FOR_EACH (addr_set_rec, ctx->ovnsb_idl) { > - struct address_set *addr_set = > - shash_find_data(&local_address_sets, addr_set_rec->name); > - > - bool create_set = false; > - if (addr_set) { > - /* This address set has already been added. We must determine > - * if the symtab entry needs to be updated due to a change. */ > - sset_find_and_delete(&cur_addr_set_names, addr_set_rec-> name); > - if (!address_sets_match(addr_set, addr_set_rec)) { > - shash_find_and_delete(&local_address_sets, > addr_set_rec->name); > - expr_macros_remove(&expr_address_sets, addr_set_rec-> name); > - address_set_destroy(addr_set); > - addr_set = NULL; > - create_set = true; > - } > - } else { > - /* This address set is not yet in the symtab, so add it. */ > - create_set = true; > - } > - > - if (create_set) { > - /* The address set is either new or has changed. Create a symbol > - * that resolves to the full set of addresses. Store it in > - * address_sets to remember that we created this symbol. */ > - addr_set = xzalloc(sizeof *addr_set); > - addr_set->n_addresses = addr_set_rec->n_addresses; > - if (addr_set_rec->n_addresses) { > - addr_set->addresses = xmalloc(addr_set_rec->n_addresses > - * sizeof > addr_set->addresses[0]); > - size_t i; > - for (i = 0; i < addr_set_rec->n_addresses; i++) { > - addr_set->addresses[i] = > xstrdup(addr_set_rec->addresses[i]); > - } > - } > - shash_add(&local_address_sets, addr_set_rec->name, addr_set); > - > - expr_macros_add(&expr_address_sets, addr_set_rec->name, > - (const char * const *) addr_set->addresses, > - addr_set->n_addresses); > - } > - } > - > - /* Anything remaining in cur_addr_set_names refers to an address set that > - * has been deleted from the southbound database. We should delete > - * the corresponding symtab entry. */ > - const char *cur_node, *next_node; > - SSET_FOR_EACH_SAFE (cur_node, next_node, &cur_addr_set_names) { > - expr_macros_remove(&expr_address_sets, cur_node); > - > - struct address_set *addr_set > - = shash_find_and_delete(&local_address_sets, cur_node); > - address_set_destroy(addr_set); > - > - struct sset_node *sset_node = SSET_NODE_FROM_NAME(cur_node); > - sset_delete(&cur_addr_set_names, sset_node); > - } > - > - sset_destroy(&cur_addr_set_names); > } > > struct lookup_port_aux { > @@ -209,7 +74,8 @@ static void consider_logical_flow(const struct > lport_index *lports, > struct hmap *dhcp_opts_p, > struct hmap *dhcpv6_opts_p, > uint32_t *conj_id_ofs_p, > - struct hmap *flow_table); > + struct hmap *flow_table, > + struct shash *expr_address_sets_p); > > static bool > lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp) > @@ -248,7 +114,8 @@ add_logical_flows(struct controller_ctx *ctx, > const struct lport_index *lports, > const struct hmap *patched_datapaths, > struct group_table *group_table, > const struct simap *ct_zones, > - struct hmap *flow_table) > + struct hmap *flow_table, > + struct shash *expr_address_sets_p) > { > uint32_t conj_id_ofs = 1; > const struct sbrec_logical_flow *lflow; > @@ -272,7 +139,7 @@ add_logical_flows(struct controller_ctx *ctx, > const struct lport_index *lports, > consider_logical_flow(lports, mcgroups, lflow, local_datapaths, > patched_datapaths, group_table, ct_zones, > &dhcp_opts, &dhcpv6_opts, &conj_id_ofs, > - flow_table); > + flow_table, expr_address_sets_p); > } > > dhcp_opts_destroy(&dhcp_opts); > @@ -290,7 +157,8 @@ consider_logical_flow(const struct lport_index *lports, > struct hmap *dhcp_opts_p, > struct hmap *dhcpv6_opts_p, > uint32_t *conj_id_ofs_p, > - struct hmap *flow_table) > + struct hmap *flow_table, > + struct shash *expr_address_sets_p) > { > /* Determine translation of logical table IDs to physical table IDs. */ > bool ingress = !strcmp(lflow->pipeline, "ingress"); > @@ -399,7 +267,7 @@ consider_logical_flow(const struct lport_index *lports, > struct expr *expr; > > expr = expr_parse_string(lflow->match, &symtab, > - &expr_address_sets, &error); > + expr_address_sets_p, &error); > if (!error) { > if (prereqs) { > expr = expr_combine(EXPR_T_AND, expr, prereqs); > @@ -554,10 +422,16 @@ lflow_run(struct controller_ctx *ctx, const > struct lport_index *lports, > const struct simap *ct_zones, > struct hmap *flow_table) > { > - update_address_sets(ctx); > + struct shash expr_address_sets = SHASH_INITIALIZER (&expr_address_sets); > + > + update_address_sets(ctx, &expr_address_sets); > add_logical_flows(ctx, lports, mcgroups, local_datapaths, > - patched_datapaths, group_table, ct_zones, flow_table); > + patched_datapaths, group_table, ct_zones, flow_table, > + &expr_address_sets); > add_neighbor_flows(ctx, lports, flow_table); > + > + expr_macros_destroy(&expr_address_sets); > + shash_destroy(&expr_address_sets); > } > > void > @@ -565,6 +439,4 @@ lflow_destroy(void) > { > expr_symtab_destroy(&symtab); > shash_destroy(&symtab); > - expr_macros_destroy(&expr_address_sets); > - shash_destroy(&expr_address_sets); > } > diff --git a/ovn/lib/expr.c b/ovn/lib/expr.c > index e0a14ec..4ae6b0b 100644 > --- a/ovn/lib/expr.c > +++ b/ovn/lib/expr.c > @@ -964,6 +964,7 @@ expr_macros_destroy(struct shash *macros) > > shash_delete(macros, node); > expr_constant_set_destroy(cs); > + free(cs); > } > } > > -- > 2.1.3 >
Assuming that it compiles and all the unit test cases pass - roll with it!! Ryan _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev