Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KMALLOC size allocation

Does KMALLOC allocates only in page size memory or it can allocate less ? What are the sizes that the kmalloc can allocate ? Where can I find description of it, as everywhere I looked it doesn't really say how much memory it allocates ? What I want to know is what are the actual sizes that KMALLOC allocates. Does it allocate size of power of 2 ? Does it just find free objects from the cache that is ready ?

like image 991
shd Avatar asked Sep 24 '12 15:09

shd


3 Answers

It all depends on the allocator used in your kernel. Slab, Slub or Slob. See Following kernel configuration variables:

CONFIG_SLAB
CONFIG_SLUB
CONFIG_SLOB

All above allocators use MAX_ORDER and PAGE_SHIFT to decide the maximum limit of kmalloc()

The largest kmalloc size supported by the SLAB allocators is 32 megabyte (2^25) or the maximum allocatable page order if that is less than 32 MB.

#define KMALLOC_SHIFT_HIGH      ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
  (MAX_ORDER + PAGE_SHIFT - 1) : 25)
#define KMALLOC_SHIFT_MAX       KMALLOC_SHIFT_HIGH

SLUB directly allocates requests fitting in to an order-1 page (PAGE_SIZE*2). Larger requests are passed to the page allocator.

#define KMALLOC_SHIFT_HIGH      (PAGE_SHIFT + 1)
#define KMALLOC_SHIFT_MAX       (MAX_ORDER + PAGE_SHIFT)

SLOB passes all requests larger than one page to the page allocator. No kmalloc array is necessary since objects of different sizes can be allocated from the same page.

#define KMALLOC_SHIFT_HIGH      PAGE_SHIFT
#define KMALLOC_SHIFT_MAX       30

Maximum allocatable size by kmalloc() is

#define KMALLOC_MAX_SIZE        (1UL << KMALLOC_SHIFT_MAX)

Minimum allocatable size from kmalloc() is

#define KMALLOC_MIN_SIZE (1 << KMALLOC_SHIFT_LOW)

Default KMALLOC_SHIFT_LOW for slab is 5, and for slub and slob it is 3.

like image 147
Cool Goose Avatar answered Oct 19 '22 06:10

Cool Goose


My understanding is as follows: the kernel is dealing with the physical memory of the system, which is available only in page-sized chunks; thus when you call kmalloc() you are going to get only certain predefined, fixed-size byte arrays.

The actual memory you get back is dependent on the system's architecture, but the smallest allocation that kmalloc can handle is as big as 32 or 64 bytes. You will get back from a call to kmalloc() at least as much memory as you asked for (usually more). Typically you will not get more than 128 KB (again, architecture dependent)

To get the page size (in bytes) of your system you can execute the command:

getconf PAGESIZE

or

getconf PAGE_SIZE

This information on max page size is in /usr/src/linux/include/linux/slab.h

And yes, the page sizes are generally powers of 2, but again, you're not going to get exactly what you ask for, but a little bit more.

You can use some code like this:

void * stuff;
stuff = kmalloc(1,GFP_KERNEL);
printk("I got: %zu bytes of memory\n", ksize(stuff));
kfree(stuff);

To show the actual amount of memory allocated:

[90144.702588] I got: 32 bytes of memory
like image 11
Mike Avatar answered Oct 19 '22 04:10

Mike


You can see some common sizes used by kmalloc() int your system with:

cat /proc/slabinfo  | grep kmalloc

More important than the consideration of whether kmalloc can allocate less than a page is the question of whether it can allocate more than a page: if you are calling kmalloc() in atomic context (with the GFP_ATOMIC flag), it can't and won't try very hard to find contiguous pages in memory, so if your memory is very fragmented, and the order of your allocation is high (allocation size → pagesize*2^(allocation order)), the allocation may fail. So, in atomic context, big allocations are likely to fail.

There is an example of a failed allocation of order 7 (512 Kb) at this other SO question about maximum AF_UNIX datagram size.

like image 3
ninjalj Avatar answered Oct 19 '22 06:10

ninjalj