CPU Cache for Slab allocation

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
CRoemheld
Member
Member
Posts: 55
Joined: Wed May 02, 2018 1:26 pm
Freenode IRC: CRoemheld

CPU Cache for Slab allocation

Post by CRoemheld »

While implementing the Slab allocator for my system, I realized that Linux is using a dedicated struct for caches when allocating memory via its slab allocator:

Code: Select all

struct kmem_cache {
	struct array_cache __percpu *cpu_cache;
...

Code: Select all

struct array_cache {
	unsigned int avail;
	unsigned int limit;
	unsigned int batchcount;
	unsigned int touched;
	void *entry[];	/*
			 * Must have this definition in here for the proper
			 * alignment of array_cache. Also simplifies accessing
			 * the entries.
			 */
};
Unfortunately there don't seem much informations about it. While some sources (Gorman, Understanding the Linux Virtual Memory Manager, Maurer, Professional Linux Kernel Architecture, and some websites) explain the members of the struct array_cache, they don't explain what I'm assuming is more crucial to truly understand the reason behind this structure: How the cache is acting like a CPU cache. As far as I know the CPU caches aren't directly accessible. So given that information, I further assume that the structure is leveraging the fact that the caches are specially aligned to increase the cache hits for memory regions or objects in the slab allocator. Is that correct?

Also, while going in deeper into the Linux kernel I found out that the caches are ultimately being created by using the preallocator (mm/memblock.c). This also matches my observation about the CPU caches not directly but indirectly being used via alignment of the objects in the memory.

The members of the struct array_cache are statically initialized with batchcount = limit = 1. This also means that the array_cache structure only uses one entry in its void *entry[] array member. It seems that the batchcount and limit members aren't changed at anytime, except when calling mm/slab.c::do_tune_cpucache.

What I don't get is the connection between the members avail, limit and batchcount. While avail obviously informs about the available objects in its cache, the batchcount and the limit members irritate me a bit: Does the limit indicate the maximum amount of objects in the cache or does it refer to the maximum batchcount, meaning the number of objects to be taken from the slabs and added to the array_caches/CPU caches?

As you can see I am missing more detailed informations about the array_cache structure as it doesn't seem to be well documented or explained anywhere. I hope you can help me in this matter.
Post Reply