[ovs-dev,ovn] logical-fields: fix memory leak while initializing ovnfield_by_name
diff mbox series

Message ID 1565174977-9439-1-git-send-email-damjan.skvarc@gmail.com
State New
Headers show
Series
  • [ovs-dev,ovn] logical-fields: fix memory leak while initializing ovnfield_by_name
Related show

Commit Message

Damijan Skvarc Aug. 7, 2019, 10:49 a.m. UTC
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@gmail.com>
---
 lib/logical-fields.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

Comments

0-day Robot Aug. 7, 2019, 11:07 a.m. UTC | #1
Bleep bloop.  Greetings Damijan Skvarc, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Line lacks whitespace around operator
WARNING: Line lacks whitespace around operator
#52 FILE: lib/logical-fields.c:73:
        initialized=1;

Lines checked: 76, Warnings: 2, Errors: 0


build:
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./ovs/include -I ./ovs/include -I ./ovs/lib -I ./ovs/lib -I ./ovs -I ./ovs -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT lib/mcast-group-index.lo -MD -MP -MF lib/.deps/mcast-group-index.Tpo -c lib/mcast-group-index.c -o lib/mcast-group-index.o
depbase=`echo lib/lex.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.   -I ./include  -I ./ovs/include -I ./ovs/include -I ./ovs/lib -I ./ovs/lib -I ./ovs -I ./ovs -I ./lib -I ./lib    -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror   -g -O2 -MT lib/lex.lo -MD -MP -MF $depbase.Tpo -c -o lib/lex.lo lib/lex.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./ovs/include -I ./ovs/include -I ./ovs/lib -I ./ovs/lib -I ./ovs -I ./ovs -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT lib/lex.lo -MD -MP -MF lib/.deps/lex.Tpo -c lib/lex.c -o lib/lex.o
depbase=`echo lib/ovn-util.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.   -I ./include  -I ./ovs/include -I ./ovs/include -I ./ovs/lib -I ./ovs/lib -I ./ovs -I ./ovs -I ./lib -I ./lib    -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror   -g -O2 -MT lib/ovn-util.lo -MD -MP -MF $depbase.Tpo -c -o lib/ovn-util.lo lib/ovn-util.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./ovs/include -I ./ovs/include -I ./ovs/lib -I ./ovs/lib -I ./ovs -I ./ovs -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT lib/ovn-util.lo -MD -MP -MF lib/.deps/ovn-util.Tpo -c lib/ovn-util.c -o lib/ovn-util.o
depbase=`echo lib/logical-fields.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ./libtool  --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I.   -I ./include  -I ./ovs/include -I ./ovs/include -I ./ovs/lib -I ./ovs/lib -I ./ovs -I ./ovs -I ./lib -I ./lib    -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror   -g -O2 -MT lib/logical-fields.lo -MD -MP -MF $depbase.Tpo -c -o lib/logical-fields.lo lib/logical-fields.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I ./include -I ./ovs/include -I ./ovs/include -I ./ovs/lib -I ./ovs/lib -I ./ovs -I ./ovs -I ./lib -I ./lib -Wstrict-prototypes -Wall -Wextra -Wno-sign-compare -Wpointer-arith -Wformat -Wformat-security -Wswitch-enum -Wunused-parameter -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -fno-strict-aliasing -Wshadow -Werror -Werror -g -O2 -MT lib/logical-fields.lo -MD -MP -MF lib/.deps/logical-fields.Tpo -c lib/logical-fields.c -o lib/logical-fields.o
lib/logical-fields.c:62:1: error: function declaration isn't a prototype [-Werror=strict-prototypes]
 init_ovnfield_by_name()
 ^
lib/logical-fields.c: In function 'init_ovnfield_by_name':
lib/logical-fields.c:62:1: error: old-style function definition [-Werror=old-style-definition]
cc1: all warnings being treated as errors
make[2]: *** [lib/logical-fields.lo] Error 1
make[2]: Leaving directory `/var/lib/jenkins/jobs/upstream_build_from_pw/workspace/OVN'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/var/lib/jenkins/jobs/upstream_build_from_pw/workspace/OVN'
make: *** [all] Error 2


Please check this out.  If you feel there has been an error, please email aconole@bytheb.org

Thanks,
0-day Robot
Dumitru Ceara Aug. 7, 2019, 11:57 a.m. UTC | #2
On Wed, Aug 7, 2019 at 12:50 PM Damijan Skvarc <damjan.skvarc@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@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@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Patch
diff mbox series

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()
+{
+    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;
+    }
+}
+
 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);
 }