doubts about virtual memory

Hi,

I've got a couple of doubts about the memory management of BSD, and in general of the vm layer. First of all I'm not sure I understood the aim of the slab allocator. If I'm getting right the slab allocator pre-allocates a set of often used objects, I suspect the vm_ set of structures are part of such objects, is it right?

Second, I guess parts of the kernel cannot be paged out, and I guess the vm layer is in such part, so the kernel must keep a set of resident pages. What happens if the physical memory is smaller than the size of the resident pages of the kernel? And is such resident part tunable in its size?

Thanks
 
If the resident part the kernel need at boot is not available, the thing will not boot.
Should during runtime the wired memory grow in such a manner as to come near all the RAM, the system will start paging and swapping, in the end some processes will be killed if need be just to keep the kernel running.

The idea behind the slab allocator is to fight memory fragmentation. If you allocate using a slab allocator, you may use more memory as really needed (when the allocator rounds up your allocation), but it will not fragment the memory. Use $SEARCH_ENGINE_OF_PREFERENCE and ask it about heap fragmentation. Long running programs tend to fragment the free memory so they may in the end not be able to find a suitable chunk, even when plenty is free. Since uptimes of some years can be reached, and by then one would have some serious memory fragmentation.

IIRC, the kernel image that is loaded at bootup is completely unpageable. So if you are really low on memory, building your own and only adding what is absolutely needed is your way to "tune" this.

Hope this helps, any correction is welcome ;)
 
Thanks, it becomes clearer now.
However I still don't understand when different allocators are used. For instance, the slab allocator is used only by the kernel for its structures or can be used also in user-space allocations? When the slab is preferred other the zone allocator?
 
Memory allocation mechanisms in kernel and userland are completely separate. Kernel uses slab allocator (see uma() for details); kernel malloc (see malloc(9)) is unrelated to the userland malloc (malloc(3)) and is, from what I remember, also backed by the slab allocator.
 
Ok, I begin to understand now. So for the kernel we can have a zone that handles a specific structure and that has ctor and dtor to initialize such structure as it is zalloc'ed, right? Instead for a userland malloc backed by the slab we don't have ctor and dtor because we are just reserving a bunch of bytes (initialized to zero). Does this sound correct?
 
Exactly. Also note that the kernel doesn't know about userland mallocs - from the kernel point of view, everything is just pages and ranges of pages. It's libc that splits these into malloced chunks.
 
A last question that regards the kernel usage of the slab: imagine the kernel has two structs that have the same size but different field arrangements. Does the kernel need to create different zones for each one? I guess the answer is yes since the two structures will be initialized differently, and therefore will have different ctors (and dtors). But if this is true, the kernel need to carefully set up each zone for each kind of internal structure or, at least, for the main ones, leaving initialized to zero all the others. Is this correct?
 
It's the consumer who chooses the zone, not the allocator itself. In other words, when you write some kernel code that needs to allocate stuff using slab, you explicitly create zone using uma_zcreate(9) and then pass the returned uma_zone_t pointer to uma_zalloc(9). The allocator doesn't have to distinguish between structs using their size; it uses the passed pointer.
 
Thanks, now it is clear.
As an example for the records I guess the following explains well how slab must be initialized:

Code:
     thread_zone = uma_zcreate("THREAD",   sched_sizeof_thread(),                         
            thread_ctor, thread_dtor, thread_init, thread_fini,                            
            16 - 1, 0);

As last question, you pointed me to a uma man page, does FreeBSD support numa allocations?
 
Back
Top