Hi all, I'm one of the Netatalk (OpenSource AFP fileserver) devs. We use Avahi via avahi_threaded_poll and friends in order to register the AFP server with mdns. We call the Avahi setup stuff once in our main process `afpd` here [1]. Handling user sessions is done by forking childs. As it seems, when calling the Avahi setup functions, a big chunk of memory is taken: With Avahi registration: $ s pmap 14083 14083: /usr/local/netatalk/sbin/afpd -d -F /usr/local/netatalk/etc/afp.conf 0000000000400000 308K r-x-- /usr/local/netatalk/sbin/afpd 000000000064c000 24K rw--- /usr/local/netatalk/sbin/afpd 0000000000652000 116K rw--- [ anon ] 000000001fd34000 280K rw--- [ anon ] 000000004068d000 4K ----- [ anon ] 000000004068e000 10240K rw--- [ anon ] Without Avahi registration: $ s pmap 14233 14233: /usr/local/netatalk/sbin/afpd -d -F /usr/local/netatalk/etc/afp.conf 0000000000400000 308K r-x-- /usr/local/netatalk/sbin/afpd 000000000064c000 24K rw--- /usr/local/netatalk/sbin/afpd 0000000000652000 116K rw--- [ anon ] 0000000015cc8000 280K rw--- [ anon ] The difference is this 10 MB allocation: 000000004068e000 10240K rw--- [ anon ] Obviously, we didn't bother calling the Avahi free ressources() functions in the forked afpd session childs as the damage done by sbrk() can't be undone by free(). The main concern I have with this memory consumption is that is handed down to every afpd process. My questions are: - is the memory consumption of 10 MB as expected ? - do you see any way of preventing the inheritance of the memory consumption without running the Avahi registration in an dedicated process ? Thanks! -f [1] <http://netatalk.git.sourceforge.net/git/gitwe...>
On Tue, 10.04.12 15:23, Frank Lahm wrote: > Hi all, > > I'm one of the Netatalk (OpenSource AFP fileserver) devs. We use Avahi > via avahi_threaded_poll and friends in order to register the AFP > server with mdns. > We call the Avahi setup stuff once in our main process `afpd` here > [1]. Handling user sessions is done by forking childs. > > As it seems, when calling the Avahi setup functions, a big chunk of > memory is taken: > > Obviously, we didn't bother calling the Avahi free ressources() > functions in the forked afpd session childs as the damage done by > sbrk() can't be undone by free(). > > The main concern I have with this memory consumption is that is handed > down to every afpd process. > > My questions are: > - is the memory consumption of 10 MB as expected ? > - do you see any way of preventing the inheritance of the memory > consumption without running the Avahi registration in an dedicated > process ?I don't see where the Avahi client libraries cuould do such a big allocation. My only guess is that this is actually the D-Bus library that does this (it maintains a message cache). To figure this out it might be worth to plot the memory usage with a tool like valgrind's massif tool? Lennart
Am 10. April 2012 22:26 schrieb Lennart Poettering : > On Tue, 10.04.12 15:23, Frank Lahm wrote: > >> Hi all, >> >> I'm one of the Netatalk (OpenSource AFP fileserver) devs. We use Avahi >> via avahi_threaded_poll and friends in order to register the AFP >> server with mdns. >> We call the Avahi setup stuff once in our main process `afpd` here >> [1]. Handling user sessions is done by forking childs. >> >> As it seems, when calling the Avahi setup functions, a big chunk of >> memory is taken: >> >> Obviously, we didn't bother calling the Avahi free ressources() >> functions in the forked afpd session childs as the damage done by >> sbrk() can't be undone by free(). >> >> The main concern I have with this memory consumption is that is handed >> down to every afpd process. >> >> My questions are: >> - is the memory consumption of 10 MB as expected ? >> - do you see any way of preventing the inheritance of the memory >> consumption without running the Avahi registration in an dedicated >> process ? > > I don't see where the Avahi client libraries cuould do such a big > allocation. My only guess is that this is actually the D-Bus library > that does this (it maintains a message cache). To figure this out it > might be worth to plot the memory usage with a tool like valgrind's > massif tool?I had checked with Valgrind memcheck before to no avail. I've looked at massif as to your recommendation and that is indeed quite revealing (this requires the --pages-as-heap=yes option as the large allocation is apparently not done via malloc et al): $ sudo valgrind --tool=massif --pages-as-heap=yes --detailed-freq=1 /usr/local/netatalk/sbin/afpd -d ... ^C Looking at the last snapshot: $ ms_print ... ... -------------------------------------------------------------------------------- n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)-------------------------------------------------------------------------------- 61 1,283,953,675 84,291,584 84,291,584 0 0 100.00% (84,291,584B) (page allocation syscalls) mmap/mremap/brk, --alloc-fns, etc. ... ->12.45% (10,493,952B) 0x6B32F99: mmap (in /lib/libc-2.7.so) | ->12.44% (10,489,856B) 0x6848AEF: pthread_create@@GLIBC_2.2.5 (in/lib/libpthread-2.7.so) | | ->12.44% (10,489,856B) 0x5B45E96: avahi_threaded_poll_start (in /usr/lib/libavahi-common.so.3.5.0)| | ->12.44% (10,489,856B) 0x40BD5D: av_zeroconf_register (afp_avahi.c:307) | | ->12.44% (10,489,856B) 0x40F0FA: zeroconf_register (afp_zeroconf.c:36) | | ->12.44% (10,489,856B) 0x40C22D: configinit (afp_config.c:128) | | ->12.44% (10,489,856B) 0x42FCD2: main (main.c:338)
Am 11. April 2012 16:50 schrieb Frank Lahm :
> Am 10. April 2012 22:26 schrieb Lennart Poettering :
>> On Tue, 10.04.12 15:23, Frank Lahm wrote:
>>
>>> Hi all,
>>>
>>> I'm one of the Netatalk (OpenSource AFP fileserver) devs. We use Avahi
>>> via avahi_threaded_poll and friends in order to register the AFP
>>> server with mdns.
>>> We call the Avahi setup stuff once in our main process `afpd` here
>>> [1]. Handling user sessions is done by forking childs.
>>>
>>> As it seems, when calling the Avahi setup functions, a big chunk of
>>> memory is taken:
>>>
>>> Obviously, we didn't bother calling the Avahi free ressources()
>>> functions in the forked afpd session childs as the damage done by
>>> sbrk() can't be undone by free().
>>>
>>> The main concern I have with this memory consumption is that is handed
>>> down to every afpd process.
>>>
>>> My questions are:
>>> - is the memory consumption of 10 MB as expected ?
>>> - do you see any way of preventing the inheritance of the memory
>>> consumption without running the Avahi registration in an dedicated
>>> process ?
>>
>> I don't see where the Avahi client libraries cuould do such a big
>> allocation. My only guess is that this is actually the D-Bus library
>> that does this (it maintains a message cache). To figure this out it
>> might be worth to plot the memory usage with a tool like valgrind's
>> massif tool?
>
> I had checked with Valgrind memcheck before to no avail. I've looked
> at massif as to your recommendation and that is indeed quite revealing
> (this requires the --pages-as-heap=yes option as the large allocation
> is apparently not done via malloc et al):
>
> $ sudo valgrind --tool=massif --pages-as-heap=yes --detailed-freq=1
> /usr/local/netatalk/sbin/afpd -d
> ...
> ^C
>
> Looking at the last snapshot:
>
> $ ms_print ...
> ...
> --------------------------------------------------------------------------------
> n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
> --------------------------------------------------------------------------------
> 61 1,283,953,675 84,291,584 84,291,584 0 0
> 100.00% (84,291,584B) (page allocation syscalls) mmap/mremap/brk,
> --alloc-fns, etc.
> ...
> ->12.45% (10,493,952B) 0x6B32F99: mmap (in /lib/libc-2.7.so)
> | ->12.44% (10,489,856B) 0x6848AEF: pthread_create@@GLIBC_2.2.5 (in
> /lib/libpthread-2.7.so)
> | | ->12.44% (10,489,856B) 0x5B45E96: avahi_threaded_poll_start (in
> /usr/lib/libavahi-common.so.3.5.0)
> | | ->12.44% (10,489,856B) 0x40BD5D: av_zeroconf_register (afp_avahi.c:307)
> | | ->12.44% (10,489,856B) 0x40F0FA: zeroconf_register (afp_zeroconf.c:36)
> | | ->12.44% (10,489,856B) 0x40C22D: configinit (afp_config.c:128)
> | | ->12.44% (10,489,856B) 0x42FCD2: main (main.c:338)
> ...
>
> So it seems it's pthread_create(). Wonder why it allocates such a huge
> chunk of memory. I guess the only way avoiding this is completely
> redesigning our application such that the Avahi stuff is not done in
> the process that later forks and runs user AFP sessions. :(Would it make sense to extend the Avahi API so that a parameter could
be passed which is then used to call pthread_attr_setstacksize() for
the thread?
-f
On Wed, 11.04.12 17:41, Frank Lahm wrote: > > > > So it seems it's pthread_create(). Wonder why it allocates such a huge > > chunk of memory. I guess the only way avoiding this is completely > > redesigning our application such that the Avahi stuff is not done in > > the process that later forks and runs user AFP sessions. :( > > Would it make sense to extend the Avahi API so that a parameter could > be passed which is then used to call pthread_attr_setstacksize() for > the thread?As mentioned, this will only minimize address space, not memory usage. Allocating a biggre stack comes at virtually no cost -- as long as it is never accessed. Unless you turned off lazy allocation in Linux chasing this allocation is a waste of time. You are chasing a ghost. Have you turned off lazy allocation on Linux? (Note that the event loop logic in avahi is fully abstracted, you can implement your own logic, and run the stuff in your own thread with your own parameters. AvahiThreadedPoll is just one implementation, but nothing you actually have to use. Lennart
On Wed, 11.04.12 16:50, Frank Lahm wrote: > > I don't see where the Avahi client libraries cuould do such a big > > allocation. My only guess is that this is actually the D-Bus library > > that does this (it maintains a message cache). To figure this out it > > might be worth to plot the memory usage with a tool like valgrind's > > massif tool? > > I had checked with Valgrind memcheck before to no avail. I've looked > at massif as to your recommendation and that is indeed quite revealing > (this requires the --pages-as-heap=yes option as the large allocation > is apparently not done via malloc et al): > So it seems it's pthread_create(). Wonder why it allocates such a huge > chunk of memory. I guess the only way avoiding this is completely > redesigning our application such that the Avahi stuff is not done in > the process that later forks and runs user AFP sessions. :(This might simply be the stack for the thread, which you can influence with "ulimit -s" in its size. However, note that having a large stack doesn't actually mean that this uses a lot of memory, it just reserves address space, which is only backed when needed. Hence, most likely this is really a non-issue. (i.e. don't confuse reservation of memory with reservation of address space!) Lennart
Am 11. April 2012 17:44 schrieb Lennart Poettering : > On Wed, 11.04.12 16:50, Frank Lahm wrote: > >> > I don't see where the Avahi client libraries cuould do such a big >> > allocation. My only guess is that this is actually the D-Bus library >> > that does this (it maintains a message cache). To figure this out it >> > might be worth to plot the memory usage with a tool like valgrind's >> > massif tool? >> >> I had checked with Valgrind memcheck before to no avail. I've looked >> at massif as to your recommendation and that is indeed quite revealing >> (this requires the --pages-as-heap=yes option as the large allocation >> is apparently not done via malloc et al): > >> So it seems it's pthread_create(). Wonder why it allocates such a huge >> chunk of memory. I guess the only way avoiding this is completely >> redesigning our application such that the Avahi stuff is not done in >> the process that later forks and runs user AFP sessions. :( > > This might simply be the stack for the thread, which you can influence > with "ulimit -s" in its size.This limits the size of the stack of the main thread in the first place and then that value is used by pthread_create() for the size of the stack allocation. I've tried setting setrlimit(RLIMIT_STACK,...) to a smaller value before calling avahi_threaded_poll_new|start(), but that doesn't alter the allocation.> However, note that having a large stack doesn't actually mean that this > uses a lot of memory, it just reserves address space, which is only > backed when needed. Hence, most likely this is really a > non-issue. (i.e. don't confuse reservation of memory with reservation of > address space!)Yes. Regards! -f