Re: [ovs-dev] [PATCH ovn] logical-fields: fix memory leak while initializing ovnfield_by_name
On Wed, Aug 7, 2019 at 12:50 PM Damijan Skvarc 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 > --- > 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(_by_name); > +for (int i = 0; i < OVN_FIELD_N_IDS; i++) { > +const struct ovn_field *of = _fields[i]; > +ovs_assert(of->id == i); /* Fields must be in the enum order. */ > +shash_add_once(_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(_by_name); > -for (int i = 0; i < OVN_FIELD_N_IDS; i++) { > -const struct ovn_field *of = _fields[i]; > -ovs_assert(of->id == i); /* Fields must be in the enum order. */ > -shash_add_once(_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 > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH ovn] logical-fields: fix memory leak while initializing ovnfield_by_name
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() ^
[ovs-dev] [PATCH ovn] logical-fields: fix memory leak while initializing ovnfield_by_name
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 --- 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() +{ +static bool initialized = 0; + +if (0 == initialized) { +shash_init(_by_name); +for (int i = 0; i < OVN_FIELD_N_IDS; i++) { +const struct ovn_field *of = _fields[i]; +ovs_assert(of->id == i); /* Fields must be in the enum order. */ +shash_add_once(_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(_by_name); -for (int i = 0; i < OVN_FIELD_N_IDS; i++) { -const struct ovn_field *of = _fields[i]; -ovs_assert(of->id == i); /* Fields must be in the enum order. */ -shash_add_once(_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 d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev