What is the relation between the smallest kmalloc() allocation and memory page size?

702 Views Asked by At

From this post I realized that:

the smallest allocation that kmalloc can handle is as big as 32 or 64 bytes

and

The actual memory you get back is dependent on the system's architecture

But also memory page size is mentioned there and on other sites. I can't figure out how the page size is related to smallest kmalloc() allocation? The page size is usually 4096 bytes, but the smallest allocation is 32 or 64 bytes (depending on arch).

So what is the relation between the smallest kmalloc() allocation and page size? And why is the smallest allocation is 32 or 64 bytes but not 16 (e.g.)?

1

There are 1 best solutions below

7
Marco Bonelli On

So what is the relation between the smallest kmalloc() allocation and page size?

None. They are unrelated.

As you can see from the source code:

#ifdef CONFIG_SLAB
// ...
#ifndef KMALLOC_SHIFT_LOW
#define KMALLOC_SHIFT_LOW   5
#endif

#ifdef CONFIG_SLUB
// ...
#ifndef KMALLOC_SHIFT_LOW
#define KMALLOC_SHIFT_LOW   3
#endif
#endif

#ifdef CONFIG_SLOB
// ...
#ifndef KMALLOC_SHIFT_LOW
#define KMALLOC_SHIFT_LOW   3
#endif
#endif

// ...

#ifndef KMALLOC_MIN_SIZE
#define KMALLOC_MIN_SIZE (1 << KMALLOC_SHIFT_LOW)
#endif

None of the macros that end up defining KMALLOC_MIN_SIZE for different allocators depends on the page size, so there's no relation between page size and kmalloc() minimum allocation size.

On some architectures though, the minimum size can be different if kmalloc() memory is also used for direct memory access. That's why you see the various #ifndef above. It's still not related to page size though.

/*
 * Some archs want to perform DMA into kmalloc caches and need a guaranteed
 * alignment larger than the alignment of a 64-bit integer.
 * Setting ARCH_KMALLOC_MINALIGN in arch headers allows that.
 */
#if defined(ARCH_DMA_MINALIGN) && ARCH_DMA_MINALIGN > 8
#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN
#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN
#define KMALLOC_SHIFT_LOW ilog2(ARCH_DMA_MINALIGN)
#else
#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
#endif

The value of ARCH_DMA_MINALIGN is architecture-specific and is usually related to the processor L1 cache size, as you can see for example for ARM:

#define L1_CACHE_SHIFT      CONFIG_ARM_L1_CACHE_SHIFT
#define L1_CACHE_BYTES      (1 << L1_CACHE_SHIFT)

/*
 * Memory returned by kmalloc() may be used for DMA, so we must make
 * sure that all such allocations are cache aligned. Otherwise,
 * unrelated code may cause parts of the buffer to be read into the
 * cache before the transfer is done, causing old data to be seen by
 * the CPU.
 */
#define ARCH_DMA_MINALIGN   L1_CACHE_BYTES