[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