On Fri, 2007-02-16 at 01:06 -0800, Dan Price wrote:
More data: watching another user suffer from this and watching just the mmap's, I see:
vvvvvvvv
mmap64(0x00000000, 16973824, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON... mmap64(0x00000000, 16982016, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,... mmap64(0x00000000, 16990208, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,... mmap64(0x00000000, 16998400, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,... .... mmap64(0x00000000, 20602880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,... mmap64(0x00000000, 20611072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,... mmap64(0x00000000, 20619264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON,... ... mmap64(0x00000000, 25067520, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON... ...
So this sure looks serious-- it's almost like a memory leak.
How large is the dovecot.index.cache file for that user? The anonymous mmaps are created so that Dovecot can "mmap" the dovecot.index.cache file into memory without actually using mmap().
The munmapping happens because Dovecot wants to grow the mmaped area, and since Solaris doesn't have mremap() call it fakes it by doing another larger mmap() and moving the data in 1MB blocks while unmapping the old memory at the same time.
So.. Hmm. Could the problem simply be that the mmap-copy-growing is too slow? If the user really has some 25MB cache file, that could be it. I think I could change the code so that it mmap()s immediately enough memory to fit the whole cache file. Probably a good idea to do anyway.