Skip to content

Commit 8ae49cb

Browse files
committed
Add kmem_cache explanation to memory allocation section
Introduces the kmem_cache for frequent, fixed-size allocations.
1 parent 7012c8a commit 8ae49cb

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

examples/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ obj-m += devicetree.o
4040
obj-m += dma.o
4141
obj-m += blkram.o
4242
obj-m += vnetloop.o
43+
obj-m += kmem_cache.o
4344

4445
KDIR ?= /lib/modules/$(shell uname -r)/build
4546
PWD := $(CURDIR)

examples/kmem_cache.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* kmem_cache_example.c - Demonstrates the use of the slab allocator.
3+
*/
4+
#include <linux/init.h>
5+
#include <linux/module.h>
6+
#include <linux/slab.h>
7+
8+
struct my_custom_struct {
9+
int id;
10+
char name[32];
11+
};
12+
13+
static struct kmem_cache *my_cachep;
14+
static struct my_custom_struct *obj1, *obj2;
15+
16+
static int __init kmem_cache_example_init(void)
17+
{
18+
pr_info("kmem_cache_example: Initializing module\n");
19+
20+
my_cachep =
21+
kmem_cache_create("my_custom_cache", sizeof(struct my_custom_struct), 0,
22+
SLAB_HWCACHE_ALIGN, NULL);
23+
24+
if (!my_cachep) {
25+
pr_err("kmem_cache_example: Failed to create cache\n");
26+
return -ENOMEM;
27+
}
28+
29+
obj1 = kmem_cache_alloc(my_cachep, GFP_KERNEL);
30+
obj2 = kmem_cache_alloc(my_cachep, GFP_KERNEL);
31+
32+
if (!obj1 || !obj2) {
33+
pr_err("kmem_cache_example: Failed to allocate objects\n");
34+
if (obj1)
35+
kmem_cache_free(my_cachep, obj1);
36+
if (obj2)
37+
kmem_cache_free(my_cachep, obj2);
38+
kmem_cache_destroy(my_cachep);
39+
return -ENOMEM;
40+
}
41+
42+
obj1->id = 1;
43+
obj2->id = 2;
44+
pr_info("kmem_cache_example: Allocated obj1 at %p (id: %d)\n", obj1,
45+
obj1->id);
46+
pr_info("kmem_cache_example: Allocated obj2 at %p (id: %d)\n", obj2,
47+
obj2->id);
48+
49+
return 0;
50+
}
51+
52+
static void __exit kmem_cache_example_exit(void)
53+
{
54+
if (obj1)
55+
kmem_cache_free(my_cachep, obj1);
56+
if (obj2)
57+
kmem_cache_free(my_cachep, obj2);
58+
59+
if (my_cachep)
60+
kmem_cache_destroy(my_cachep);
61+
62+
pr_info("kmem_cache_example: Cleaned up and exited\n");
63+
}
64+
65+
module_init(kmem_cache_example_init);
66+
module_exit(kmem_cache_example_exit);
67+
68+
MODULE_LICENSE("GPL");
69+
MODULE_AUTHOR("Kuan-Wei Chiu <visitorckw@gmail.com>");
70+
MODULE_DESCRIPTION("A simple example of kmem_cache");

lkmpg.tex

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2480,6 +2480,23 @@ \section{Memory Allocation and Ownership}
24802480
Similarly, driver authors should resist the temptation to guess at allocator
24812481
internals or to depend on low-level layout details that are not part of the API.
24822482

2483+
When a module needs to frequently allocate and free objects of the same size---such
2484+
as custom data structures, network packet descriptors, or state containers---using
2485+
\cpp|kmalloc()| repeatedly can lead to memory fragmentation and unnecessary overhead.
2486+
For these highly repetitive allocations, the slab allocator interface is the
2487+
correct tool.
2488+
Driver authors should use \cpp|kmem_cache_create()| during module initialization
2489+
to set up a dedicated cache for their specific structure.
2490+
Once the cache is created, \cpp|kmem_cache_alloc()| and \cpp|kmem_cache_free()|
2491+
provide extremely fast, fragmentation-resistant memory management for those objects.
2492+
It is crucial to symmetrically destroy the cache with \cpp|kmem_cache_destroy()|
2493+
during module cleanup to prevent memory leaks.
2494+
2495+
For a practical demonstration of creating a custom slab cache, allocating objects from
2496+
it, and ensuring proper cleanup, see the following example.
2497+
2498+
\samplec{examples/kmem_cache.c}
2499+
24832500
Ownership is just as important as allocation.
24842501
In Linux 5.10 and later, many drivers benefit from managed-resource helpers such as
24852502
\cpp|devm_kzalloc()| and friends when they are written as proper device-model

0 commit comments

Comments
 (0)