kmalloc vs vmalloc
When working with device drivers in the Linux kernel, you often need to allocate memory dynamically. Two primary functions are used for this purpose: kmalloc and vmalloc. Each serves a different purpose and is suited to specific scenarios, depending on the size and nature of the memory you need to allocate. Understanding when and how to use each is essential for writing efficient and reliable drivers.
kmalloc_example.c
12345678910111213141516171819202122232425262728293031323334#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/slab.h> // For kmalloc and kfree static int __init kmalloc_demo_init(void) { char *buffer; // Allocate 128 bytes of physically contiguous memory buffer = kmalloc(128, GFP_KERNEL); if (!buffer) { pr_alert("kmalloc failed\n"); return -ENOMEM; } strcpy(buffer, "Memory allocated with kmalloc!"); pr_info("%s\n", buffer); kfree(buffer); return 0; } static void __exit kmalloc_demo_exit(void) { pr_info("kmalloc demo module exit\n"); } module_init(kmalloc_demo_init); module_exit(kmalloc_demo_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kernel Student"); MODULE_DESCRIPTION("Simple kmalloc example");
The kmalloc function is used to allocate physically contiguous memory in the kernel space. In the example above, kmalloc is called to allocate 128 bytes, and the returned pointer is used like a normal memory buffer. Because the memory is physically contiguous, kmalloc is ideal for small allocations or for memory that must be accessible by hardware devices (such as DMA buffers). However, kmalloc is limited by the largest contiguous block of physical memory available, so it is not suitable for large allocations, especially on systems with fragmented memory.
On the other hand, vmalloc is designed for larger memory allocations. It provides virtually contiguous memory, which means the memory appears contiguous to the kernel, but it may be scattered physically. This approach allows allocation of larger blocks of memory, but with a slight performance cost due to additional address translation. Unlike kmalloc, memory allocated by vmalloc is not suitable for hardware that requires physical contiguity.
vmalloc_example.c
12345678910111213141516171819202122232425262728293031323334#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/vmalloc.h> // For vmalloc and vfree static int __init vmalloc_demo_init(void) { char *vbuffer; // Allocate 1 MB of virtually contiguous memory vbuffer = vmalloc(1024 * 1024); if (!vbuffer) { pr_alert("vmalloc failed\n"); return -ENOMEM; } strcpy(vbuffer, "Memory allocated with vmalloc!"); pr_info("%s\n", vbuffer); vfree(vbuffer); return 0; } static void __exit vmalloc_demo_exit(void) { pr_info("vmalloc demo module exit\n"); } module_init(vmalloc_demo_init); module_exit(vmalloc_demo_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kernel Student"); MODULE_DESCRIPTION("Simple vmalloc example");
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
Incrível!
Completion taxa melhorada para 3.85
kmalloc vs vmalloc
Deslize para mostrar o menu
When working with device drivers in the Linux kernel, you often need to allocate memory dynamically. Two primary functions are used for this purpose: kmalloc and vmalloc. Each serves a different purpose and is suited to specific scenarios, depending on the size and nature of the memory you need to allocate. Understanding when and how to use each is essential for writing efficient and reliable drivers.
kmalloc_example.c
12345678910111213141516171819202122232425262728293031323334#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/slab.h> // For kmalloc and kfree static int __init kmalloc_demo_init(void) { char *buffer; // Allocate 128 bytes of physically contiguous memory buffer = kmalloc(128, GFP_KERNEL); if (!buffer) { pr_alert("kmalloc failed\n"); return -ENOMEM; } strcpy(buffer, "Memory allocated with kmalloc!"); pr_info("%s\n", buffer); kfree(buffer); return 0; } static void __exit kmalloc_demo_exit(void) { pr_info("kmalloc demo module exit\n"); } module_init(kmalloc_demo_init); module_exit(kmalloc_demo_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kernel Student"); MODULE_DESCRIPTION("Simple kmalloc example");
The kmalloc function is used to allocate physically contiguous memory in the kernel space. In the example above, kmalloc is called to allocate 128 bytes, and the returned pointer is used like a normal memory buffer. Because the memory is physically contiguous, kmalloc is ideal for small allocations or for memory that must be accessible by hardware devices (such as DMA buffers). However, kmalloc is limited by the largest contiguous block of physical memory available, so it is not suitable for large allocations, especially on systems with fragmented memory.
On the other hand, vmalloc is designed for larger memory allocations. It provides virtually contiguous memory, which means the memory appears contiguous to the kernel, but it may be scattered physically. This approach allows allocation of larger blocks of memory, but with a slight performance cost due to additional address translation. Unlike kmalloc, memory allocated by vmalloc is not suitable for hardware that requires physical contiguity.
vmalloc_example.c
12345678910111213141516171819202122232425262728293031323334#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/vmalloc.h> // For vmalloc and vfree static int __init vmalloc_demo_init(void) { char *vbuffer; // Allocate 1 MB of virtually contiguous memory vbuffer = vmalloc(1024 * 1024); if (!vbuffer) { pr_alert("vmalloc failed\n"); return -ENOMEM; } strcpy(vbuffer, "Memory allocated with vmalloc!"); pr_info("%s\n", vbuffer); vfree(vbuffer); return 0; } static void __exit vmalloc_demo_exit(void) { pr_info("vmalloc demo module exit\n"); } module_init(vmalloc_demo_init); module_exit(vmalloc_demo_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kernel Student"); MODULE_DESCRIPTION("Simple vmalloc example");
Obrigado pelo seu feedback!