Allocating memory in the Linux Kernel Module – Kernel APIs

The current article tries to outline some of the memory allocation APIs that are used in the Linux kernel. There are more APIs present, however, this list should get the interested reader started in their journey for development on the Linux kernel. A list of some of the APIs are provided below for reference.

Kernel memory API

Description

void *kmalloc(size_t size, gfp_t flags)

Memory allocation function which allocates size_t bytes according to the flags provided. Usually used for memory allocation sizes up to a PAGE size of memory

void *kzalloc(size_t size, gfp_t flags)

Similar to kmalloc, sets the memory to zero

void *kmalloc_array(size_t n, size_t size, gfp_t flags)

Allocate memory for an array size of “n”

void *kcalloc(size_t n, size_t size, gfp_t flags)

Allocate memory for an array size of “n”. Set the memory value to zeroes

void kfree(const void * objp)

Free a previously allocated memory

kmem_cache_t *kmem_cache_create(const char *name, size_t size,  size_t offset,                               unsigned long flags,                                                  void (*constructor)(void *, kmem_cache_t *,                 unsigned long flags), void (*destructor)(void *, kmem_cache_t *,  unsigned long flags));

 

This is part of the kernel slab cache interface. This is used to create memory areas of size_t size which can be reused after the memory is used. Instead of the memory being freed after the memory is used, it is returned back to the cache for re-use. All the memory to be used should be of the same size. Refer the link below from linux device drivers for more information.

https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch08.html

void * kmem_cache_alloc(struct kmem_cache * cachep, gfp_t flags)

Allocate an object of memory once a cache of objects is created using kmem_cache_create API

void kmem_cache_free(struct kmem_cache * cachep, void * objp)

De-allocate the memory object

void * vmalloc(unsigned long size)

allocate virtually contiguous memory

void * vzalloc(unsigned long size)

allocate virtually contiguous memory with zero fill

void vfree(const void * addr)

release memory allocated by vmalloc()

For a more comprehensive list of APIs – refer the link – https://www.kernel.org/doc/html/latest/core-api/mm-api.html#mm-api-gfp-flags

Some of the above APIs provide flags which are of the form “GFP_*“. “GFP” stands for “Get Free Pages” . Some of the commonly seen flag names and their uses are listed below

Flag

Description

GFP_ATOMIC

This flag is used whenever the caller cannot sleep and must be serviced if at all possible. Any interrupt handler that requires memory must use this flag to avoid sleeping or performing IO. Many subsystems during init will use this system such as buffer_init() and inode_init()

GFP_KERNEL

The most liberal of the combined flags. It indicates that the caller is free to do whatever it pleases. Strictly speaking the difference between this flag and GFP_USER is that this could use emergency pools of pages but that is a no-op on 2.4.x kernels

GFP_USER

Another flag of historical significance. In the 2.2.x series, an allocation was given a LOW, MEDIUM or HIGH priority. If memory was tight, a request with GFP_USER (low) would fail where as the others would keep trying. Now it has no significance and is not treated any different to GFP_KERNEL

We shall re-visit Linux memory management later, however, an interested reader can gain information on memory management in the Linux kernel and the different flags and manner of memory management in the kernel by referring the links below

Example Linux Memory Allocation Code

Comments

  1. Pingback: Linux – Proc File system – Part 2 | Hitch Hiker's Guide to Learning

  2. Pingback: Example Linux Memory Allocation Code | Hitch Hiker's Guide to Learning

  3. Pingback: Linux Kernel – Adding Debugfs support to a Linux Kernel Module | Hitch Hiker's Guide to Learning

Leave a Reply

Your email address will not be published. Required fields are marked *