Operating-System Kernels

kmalloc and vmalloc

/ KAY-mal-ock / VEE-mal-ock /

Inside the kernel you cannot call the ordinary malloc() that user programs use - that lives in the C library, which is user-space code. The kernel has its own allocators for grabbing memory on the fly, and the two you meet first are kmalloc and vmalloc. They both hand you a block of memory, but they make a different promise about how that memory is laid out in physical RAM, and that difference decides when to use which.

kmalloc returns memory that is physically contiguous: the bytes you get occupy consecutive locations in real RAM, not just consecutive virtual addresses. That contiguity is essential for things like buffers handed to hardware doing direct memory access, since a device sees physical addresses and often needs one unbroken run. The cost is that finding a large physically-contiguous block can fail when memory is fragmented, so kmalloc is best for small-to-moderate allocations. vmalloc instead returns memory that is contiguous only in virtual address space: behind the scenes the kernel may stitch together physically scattered pages and map them to look like one continuous region. This succeeds for large allocations even under fragmentation (it does not need a big contiguous physical run), but it is slower to set up, uses extra page-table entries, and the result is NOT safe to give to a device expecting physical contiguity.

The practical rule of thumb: reach for kmalloc by default - it is faster and contiguous - and especially when hardware will touch the memory; reach for vmalloc when you need a large buffer and only the kernel itself will use it, so virtual contiguity is enough. Note also that small kmalloc requests are actually served by the slab/SLUB allocator carving up pages from the buddy page allocator underneath, so these names sit on top of the lower-level machinery rather than replacing it. And in interrupt context you must pass a flag like GFP_ATOMIC so the allocation never sleeps - a normal sleeping allocation there would be the classic context bug.

char *buf = kmalloc(256, GFP_KERNEL); // small, physically contiguous -- good for DMA. char *big = vmalloc(8 * 1024 * 1024); // 8 MiB, virtually contiguous, scattered physical pages -- kernel-only, not for a device.

kmalloc = small, physically contiguous (safe for hardware DMA); vmalloc = large, only virtually contiguous (kernel-only).

vmalloc memory is contiguous only in virtual addresses - its physical pages may be scattered, so never hand a vmalloc buffer to a device that expects physical contiguity for DMA. Also, in interrupt context you must use GFP_ATOMIC; a default sleeping allocation there can deadlock the machine.

Also called
kmalloc()vmalloc()kernel memory allocation核心記憶體配置