Re: generic aging layer on top of slab allocator?

James Mastros (
Fri, 11 Jul 1997 01:17:03 -0400

At 05:13 PM 7/10/97 -0700, Linus Torvalds wrote:
>On 10 Jul 1997, Kevin Buhr wrote:
>> On a related topic, it occurs to me that it might be nice to have
>> another layer sitting on top of the slab allocator to provide
>> reasonably generic aging support for the slab caches. Under this
>> scheme, "kmem_cache_reap" wouldn't just destruct slabs of free
>> objects; it would also use a set of cache-dependent functions to
>> locate and age "freeable" objects, so they'd eventually be
>> automagically freed (and the slabs destructed).
>Thomas Schoebel has been looking into a generic kind of "hashed cache with
>aging", because a lot of kernel problems tend to fall into that category.
>I certainly agree that it might be something interesting to look into. At
>the same time I'm a bit nervous about trying to be too generic - in many
>cases we can know what kinds of allocation patterns certain objects have,
>and maybe do a better job by having a specialized garbage-collector that
>has innate knowledge of what it is working with.
> Linus

OK, before I spout my Mostly Master Plan, some notes:
1) I am by no means an experienced kernel-hacker.
2) I'm pulling these names out of by head, there are likely existing
functions that look almost exactly like this.
3) This is pseudo-code, I know that bool isn't a type in C, and am
assuming int-'o-infinite-size.
4) If I try to implement this, a totally stable Linux 3.1.x will come
before this is done (no, that wasn't a typo)

When something needs to free some mem (IE space in the shared swap+RAM
continuum that is mapped into the 4 GB pointer-space), it would call
try_to_free_mem(int size, int priority, int sleep_style). Size is the
amount of memory it wants, priority is how important it is (lower number ->
less important, no limit to how high priority can be, but a lower limit of
0) that it doesn't fail (so we don't throw away the console-driver so that
tetris has enough memory to load), and sleep_style is so that we know
wether to sleep if we can't get the memory, or to return failure (as
opposed to sleeping in whatever called it, which just feels bad to me), or
to loop (if the system will die without this memory, and we can't sleep in
this context.

try_to_free_mem() would first call an ageing function for everything. This
could be a generic function, or it could be mem-type-specific (the term
mem-type includes file-cache pages, dcache, running programs, etc.)(like
the VFS calls). Then, it would ask each memtype below it how much memory
it could free up. It would start with level 0 (
(cache-ish stuff that hasn't been used in a really long time, etc). If the
total memory freeable is >=size, then try_to_free_mem() would free it, then
return success. Otherwise, it would retry with level 1, etc, up to the
priority requested. Then, if it still couldn't free enough memory, it
would do whatever was specified be sleep_style: return failure, sleep, or,
if necessary, loop through the process again (probably printing a warning
message when (i && 0xF00)=1, it would printk a warning message: "Been
trying to get memory for 0xF00 cycles, size=<size>, priority=<priority>
(almost definitely real high, if it was looping in the first place), buy
more RAM."
(In reality, I would be quite surprised to see this, the kernel checks for
at least 4MB of RAM before you get even close to here, and you will
completely clear everything but kernel before failing if priority is high

That's it, I think...

-=- James Mastros