All the caches are allocated from the "cache_cache" structure. Obviously the cache_cache should be preallocated statically.
There are two types of objects: small and big.
For small objects the bufctl structure is used only partially. Only the "next" element of the hlist member is used because all that small objects needs is a way to link together free objects. The associated partial-bufctl is stored at the end of the the object buffer:
+----------+-------+ | object | *next | +----------+-------+
A small object is always smaller that a single page thus is easy to deduce the slabctl structure from the object.
slabctl = ALIGN_DOWN(obj, PAGE_SIZE) + (PAGE_SIZE - sizeof(struct slabctl));
For big objects the bufctl struct is used entirely.
The associatied bufctl is allocated from the
Because every slab_cache object is a small object we don't need to use the slab allocator to allocate separate bufctl/slabctl. The chicken and egg problem is avoided. (For x86 platforms the SMALL_MAX size is PAGE_SIZE/8=512 bytes)
A small object is one that: