On Wed, Aug 31, 2016 at 01:51:51PM -0500, Ryan Moats wrote: > > > "dev" <dev-boun...@openvswitch.org> wrote on 08/31/2016 12:53:27 PM: > > > From: Ryan Moats/Omaha/IBM@IBMUS > > To: Ben Pfaff <b...@ovn.org> > > Cc: dev@openvswitch.org > > Date: 08/31/2016 12:53 PM > > Subject: Re: [ovs-dev] [ovs-dev, v2, 3/4] Unpersist data structures > > for address sets. > > Sent by: "dev" <dev-boun...@openvswitch.org> > > > > > > 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!! > > Er, let me say that more formally... > > Assuming that it compiles and all the unit test cases pass... > > Acked-by: Ryan Moats <rmo...@us.ibm.com> > > [Can I do that :) ]
Thanks, I applied this to master and branch-2.6. I took the additional liberty of splitting the memory leak fix into a separate patch for clarity. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev