vmalloc() and vmap()¶
Purpose¶
vmalloc() allocates virtually contiguous kernel memory.
Unlike kmalloc(), which allocates physically contiguous memory, vmalloc() maps independently allocated physical pages into a contiguous virtual address range.
Header¶
APIs¶
vmalloc()¶
Allocates virtually contiguous kernel memory.
Parameters¶
| Parameter | Description |
|---|---|
size |
Number of bytes to allocate. |
Return Value¶
Returns a virtual address on success, or NULL on failure.
Example¶
void *buffer;
buffer = vmalloc(PAGE_SIZE * 4);
if (!buffer)
return -ENOMEM;
/* Use the buffer */
vfree(buffer);
vzalloc()¶
Allocates virtually contiguous memory and initializes the entire region to zero.
Equivalent to:
vfree()¶
Releases memory previously allocated by vmalloc() or vzalloc().
Example:
vmap()¶
Creates a virtually contiguous mapping for an existing array of physical pages.
Unlike vmalloc(), vmap() does not allocate backing pages. The caller provides an array of struct page *.
The Linux kernel provides additional mapping flags and page protection attributes. In the learning labs, these parameters are simplified to focus on the virtual mapping mechanism.
Parameters¶
| Parameter | Description |
|---|---|
pages |
Array of backing physical pages. |
count |
Number of pages. |
flags |
Mapping flags. |
prot |
Page protection attributes. |
Return Value¶
Returns a virtually contiguous address on success, or NULL on failure.
Example¶
struct page *pages[4];
void *addr;
addr = vmap(pages, 4, VM_MAP, PAGE_KERNEL);
if (!addr)
return -ENOMEM;
/* Access mapped memory */
vunmap(addr);
vunmap()¶
Removes a mapping created by vmap().
Unlike vfree(), vunmap() only removes the virtual mapping. The backing pages remain owned by the caller.
Example¶
vmalloc_to_page()¶
Translates a virtual address within a vmalloc area to its backing physical page.
Parameters¶
| Parameter | Description |
|---|---|
addr |
Address within a vmalloc allocation. |
Return Value¶
Returns the backing struct page, or NULL if the address is invalid.
Example¶
struct page *page;
unsigned long pfn;
page = vmalloc_to_page(buffer);
if (page) {
pfn = page_to_pfn(page);
pr_info("PFN = %lu\n", pfn);
}
Notes¶
vmalloc()allocates backing pages and creates a virtual mapping.vfree()removes the mapping and releases the backing pages.vmap()creates a virtual mapping for existing pages.vunmap()removes only the virtual mapping.- The caller remains responsible for releasing pages supplied to
vmap(). vmalloc()may sleep and must not be used in atomic context.
vmalloc() vs kmalloc()¶
| Feature | kmalloc() |
vmalloc() |
vmap() |
|---|---|---|---|
| Virtual Address | Contiguous | Contiguous | Contiguous |
| Physical Memory | Contiguous | Not required | Existing pages |
| Backing Allocation | SLUB | Buddy + Virtual Mapping | Caller |
| Frees Pages | kfree() |
vfree() |
Caller |
| Suitable for DMA | Yes | Generally No | Depends on backing pages |
| Allocation Speed | Faster | Slower | Faster than vmalloc() |
Common Usage Pattern¶
vmalloc()¶
vmap()¶
struct page *pages[N];
void *addr;
addr = vmap(pages, N, ...);
...
vunmap(addr);
...
free_pages(...);