[ovs-dev] [PATCH ovn] logical-fields: fix memory leak caused by initialize ovnfield_by_name twice
Mark Michelson
mmichels at redhat.com
Fri Feb 28 20:49:55 UTC 2020
On 2/28/20 5:40 AM, Damijan Skvarc wrote:
> Hi Mark
>
> and thanks you made review of suggested patch.
>
> just a few words of myself...
> I don't work professionally on this project, I started to look into this
> code in my free hours just to satisfy my curiosity about how other
> people work. I am following a couple of other projects just to learn
> about different processes, tools and to keep my brains in good condition
> while studying some others work. And if you get some things/knowledge it
> is also kind to give back something. In case of ovs/ovn I found a nice
> suite of automatic tests,. Unfortunately, by running them under valgrind
> control the apparent reports become useless because of flood of memory
> leaks. Mostly, these are small non-important leaks, however in a flood
> of duplicated reports you can miss some serious issue. And here I found
> my personal goal what I can give back. Unfortunately, I don't have much
> knowledge about networking, nor about original design. And if you don't
> have that knowledge then from the experience I know it is better not to
> touch anything for what you don't know why it has been designed for. So
> every my patch is done in a way that nothing has been changed in a
> design, just memory leak in valgrind reports disappears.
Yep, and contributions like yours are very much appreciated. If my
criticism of your contribution came across as harsh, I apologize.
>
>
> On Thu, Feb 27, 2020 at 10:24 PM Mark Michelson <mmichels at redhat.com
> <mailto:mmichels at redhat.com>> wrote:
>
> Hi Damijan,
>
> Thanks for finding the memory leak and patching it. To me,
> ovnfield_by_name is a really strangely handled structure. There is an
> explicit function to destroy the ovnfield_by_name structure, but its
> creation is a side effect from ovn_symtab_init. The result is that
> lflow.c calls ovn_symtab_init() and ovn_destroy_ovnfields(). But ofctrl
> only calls ovn_symtab_init(). It doesn't call ovn_destroy_ovnfields()
> because it would result in double-freeing ovnfield_by_name.
>
>
> yes, I noticed that asymmetry.
>
> This lack of symmetry shows a poor design.
>
> Your patch fixes the memory
> leak, but it doesn't fix the lack of symmetry, and it still allows for
> potential double-freeing.
>
> I have a couple of suggestions for a better design:
>
> 1) Instead of calling ovn_symbtab_init() in multiple places, call it
> once in ovn_controller's main() function. Then when ovn_controller
> exits, call ovn_destroy_ovnfields(). Then, pass the created symtab as a
> parameter when it is necessary to. This works because the symtabs
> created by lflow.c and ofctrl.c are identical, and their use of the
> symtabs occurs in the same thread.
>
> 2) Initialize ovnfield_by_name in a separate function from
> ovn_symtab_init(). You can call this new ovnfield_by_name_init()
> function in ovn-controller's main function and then call the already
> existing ovn_destroy_ovnfields() function when ovn-controller exits.
> This works because ovnfield_by_name does not rely on any data from the
> created symtab. It exists completely independently.
>
> What do you think about this?
>
>
> What is strange also is that (If I see correctly) the ovnfield_by_name
> is a hash of one single entry.
> I wouldn't use hash at all in this case. But since I don't know about
> the design, probably some entries
> were deleted in the past and only one remained or probably there is a
> plan some more entries will be
> added in the future. So let's assume we should not get rid of
> ovnfield_by_name hash.
>
> I found very similar functionality in meta_flow.c file (ovs). There
> mf_by_name hash is more rational, it is filled with
> plenty of strings. Also initialization of this hash is more rational. It
> is initialized only if it is needed (initialization is hidden
> in mf_from_name() and mf_from_name_len() functions and using the same
> "pthread_once" approach as in my case). What is strange there is that
> there is no destroy action for mf_by_name and valgrind does not report
> any leak there. Probably test suite does not cover this functionality
That is an interesting data point. My guess is that the lack of a
destructor for mf_by_name is an oversight. I'm not sure why valgrind
doesn't report the leak.
>
> I believe some more alternatives are available, however to reduce the
> number of changes I would vote for
> - automatic and optional initialization similar as in meta_flow case
> - to solve asymmetry issue I would propose atexit() approach, similar as
> it is implemented in ovs/lib/stopwatch.c
That's an excellent suggestion. That contains the allocation and
destruction all within logical-fields.c without any other code having to
know about its internals.
> btw, I didn't understand your first proposal. ovn_symbtab_init()
> function need to be called twice since two different
> symtab entities are initialized. Is this probably also a design issue
> that we could live with single symtab?
That's what I was thinking. Since the symtabs are identical and are
treated as read-only (I think...), we could just have lflow and ofctrl
share the same symtab. But I like your suggestion above better.
>
> thanks,
> damijan
>
>
More information about the dev
mailing list