[OpenAFS-devel] vmalloc memory leak in 1.3.84/85?

Jeffrey Hutzelman jhutz@cmu.edu
Mon, 24 Oct 2005 12:03:46 -0400


On Monday, October 24, 2005 05:05:08 PM +0200 Peter Somogyi 
<psomogyi@gamax.hu> wrote:

> We've encountered into the same bug (vmalloc leak in afs client when klog
> many users, openafs-1.4.0-rc4). Is the need to call "sysctl -w
> afs.GCPAGs=1" - when you don't want memleak - a bug, or it's by design?

It's not actually a leak, and turning on GCPAGs is a performance tradeoff.
Let me try to describe what's going on here...


A PAG itself does not occupy any storage -- it's just a number, used to 
label processes which are members of that PAG, and also tokens, 
connections, and cached access rights belonging to that PAG.  It is these 
things which take up space.  These objects are cleaned up by background 
daemon which performs several checks at different intervals.

Every three minutes, the background thread sweeps the token cache, looking 
for tokens which are expired or have been discarded.  Any in finds in this 
state are deleted (freeing the storage they occupy), as are cached access 
rights for the PAG containing them.


Every ten minutes, the background thread does a sweep of all PAGs for which 
we have tokens or active Rx connections.  For any which either have no 
tokens or whose tokens have expired (within a short grace period), all 
connections are destroyed, and the structure used to track them is freed.

So, after a short delay, no resources are used by a PAG whose tokens have 
expired or been deleted.  This is done reasonably efficiently, by 
traversing a list of data structures which exist only for active PAGs.



The problem that comes up is in a situation where you frequently create a 
PAG, put some tokens in it, use it briefly, and then forget about it 
without bothering to delete its tokens.  The ideal thing to do here is to 
fix either the "frequently" or the "without bothering to delete its tokens" 
parts.  Lacking that, you can turn on the PAG garbage collector.

When enabled, the garbage collector runs every hour.  What this does is 
scan the process table, setting an in-use flag on each PAG which has at 
least one process in it (*).  Then, it marks as expired the tokens of any 
PAG which has no members, which causes the sweeps described above to throw 
away those tokens after a short time.  This is not quite as racy as it 
sounds, but it does have the potential to miss a process and thus nuke 
tokens which are actually in use.  It's also a performance hit, and is 
completely unnecessary in the majority of cases.  Thus, it is not enabled 
by default.


(*) Note that as mentioned above, PAGs don't actually occupy any storage.
The flag described is actually set on the structure used to manage tokens 
and connections for a PAG, which exists only if there is anything to manage.


-- Jeff