[ovs-dev] [PATCH ovn] logical-fields: fix memory leak while initializing ovnfield_by_name
Dumitru Ceara
dceara at redhat.com
Wed Aug 7 11:57:38 UTC 2019
On Wed, Aug 7, 2019 at 12:50 PM Damijan Skvarc <damjan.skvarc at gmail.com> wrote:
>
> ovnfield_by_name is a hash table, intended to quicky find ovn_field by
> name from a list of supported ovn_fields. This hash table is initialized
> in ovn_init_symtab() function based on ovn_fields const array. In case
> ovn_init_symtab() function is called multiple times then hash table is
> reinitialized multiple times without deallocating previously allocated
> memory. This is actually what happens in ovn_controller by initializing
> lflow.symtab and ofctrl.symtab tables.
>
> Since ovnfield_by_name is initialized twice with same values I have
> introduced a flag indicating ovnfield_by_name is already initialized
> or not and based on this flag hash table is prevented to be initialized
> multiple times.
>
> Note that currently ovn_fields array is constituted from one single
> entry and thus searching a list of one entry by using helper hash table
> is somehow useless. Memory leak could be solved by simply removing
> ovnfield_by_name table and do a linear search through a list of single
> entry. However I want to keep previous functionality in case ovn_fields
> array will be extended somewhen in the future.
>
> Signed-off-by: Damijan Skvarc <damjan.skvarc at gmail.com>
> ---
> lib/logical-fields.c | 25 +++++++++++++++++++------
> 1 file changed, 19 insertions(+), 6 deletions(-)
>
> diff --git a/lib/logical-fields.c b/lib/logical-fields.c
> index 4ad5bf4..62b9a71 100644
> --- a/lib/logical-fields.c
> +++ b/lib/logical-fields.c
> @@ -57,6 +57,23 @@ add_ct_bit(const char *name, int index, struct shash *symtab)
> free(expansion);
> }
>
> +
> +static void
> +init_ovnfield_by_name()
> +{
This should actually be init_ovnfield_by_name(void)
> + static bool initialized = 0;
> +
> + if (0 == initialized) {
> + shash_init(&ovnfield_by_name);
> + for (int i = 0; i < OVN_FIELD_N_IDS; i++) {
> + const struct ovn_field *of = &ovn_fields[i];
> + ovs_assert(of->id == i); /* Fields must be in the enum order. */
> + shash_add_once(&ovnfield_by_name, of->name, of);
> + }
> + initialized=1;
I'd use "initialized = true/false" and if "(!initialized)" instead of
using 0 and 1.
> + }
> +}
Instead of adding this check here isn't it cleaner to just make sure
that we call init_ovnfield_by_name only once? I see there's
OVS_CONSTRUCTOR which should allow exactly what you're trying to do
with the check.
Thanks,
Dumitru
> +
> void
> ovn_init_symtab(struct shash *symtab)
> {
> @@ -218,12 +235,8 @@ ovn_init_symtab(struct shash *symtab)
> expr_symtab_add_field(symtab, "sctp.src", MFF_SCTP_SRC, "sctp", false);
> expr_symtab_add_field(symtab, "sctp.dst", MFF_SCTP_DST, "sctp", false);
>
> - shash_init(&ovnfield_by_name);
> - for (int i = 0; i < OVN_FIELD_N_IDS; i++) {
> - const struct ovn_field *of = &ovn_fields[i];
> - ovs_assert(of->id == i); /* Fields must be in the enum order. */
> - shash_add_once(&ovnfield_by_name, of->name, of);
> - }
> + init_ovnfield_by_name();
> +
> expr_symtab_add_ovn_field(symtab, "icmp4.frag_mtu", OVN_ICMP4_FRAG_MTU);
> }
>
> --
> 2.7.4
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
More information about the dev
mailing list