# Can malloc(9) return small chunks that cross a page boundary?



## Andrew Boyer (Feb 6, 2020)

From malloc(9):

```
IMPLEMENTATION NOTES
     The memory allocator allocates memory in chunks that have size a power of
     two for requests up to the size of a page of memory.  For larger
     requests, one or more pages is allocated.  While it should not be relied
     upon, this information may be useful for optimizing the efficiency of
     memory use.
```

For allocations larger than PAGE_SIZE, it is obviously possible (and likely!) for the returned pages to be physically noncontiguous.

Is it also possible for smaller chunks to be noncontiguous, or is it safe to assume that PAGE_SIZE and smaller allocations are contained within a single physical page?

-Andrew


----------



## Eric A. Borisch (Feb 6, 2020)

Andrew Boyer said:


> From malloc(9):
> `IMPLEMENTATION NOTES
> The memory allocator allocates memory in chunks that have size a power of
> two for requests up to the size of a page of memory.  For larger
> ...



You’re looking at the kernel malloc man page, you want malloc(3) if you’re talking about user space programs using libc’s malloc(). The answer there (at least by my reading) is that you are not guaranteed that small allocations are on a single page, as it indicates allocations are tightly packed, and pages are not evenly divisible by all class sizes.


----------



## mark_j (Feb 7, 2020)

Refer contigmalloc()
To quote the "Design & implementation of the Freebsd OS":


> The kernel memory allocator uses a hybrid strategy. Small allocations are done using a power-of-2 list strategy. Using the zone allocator, the kernel creates a set of zones with one for each power-of-two between 16 and the page size. The allocation simply requests a block of memory from the appropriate zone. Usually, the zone will have an available piece of memory in one of the buckets of the CPU on which it is running that it can return. Only if the CPUs buckets are both empty will the zone allocator have to do a full allocation. As described in the zone allocator subsection, when forced to do an additional allocation, it fills a whole bucket with the appropriately sized pieces. This strategy speeds future allocations because several pieces of memory become available as a result of the call into the allocator.


----------



## Andrew Boyer (Feb 7, 2020)

Eric A. Borisch said:


> You’re looking at the kernel malloc man page, you want malloc(3) if you’re talking about user space programs using libc’s malloc().



I also tagged it with 'kernel module'...


----------



## Andrew Boyer (Feb 7, 2020)

mark_j said:


> Refer contigmalloc()



Right now I am using contigmalloc(), but for selfish reasons I would love to be able to replace it with the linuxkpi kmalloc() for these small allocations. (It would let me reduce the diff between the linux and bsd versions of this driver.)


----------



## Eric A. Borisch (Feb 7, 2020)

Andrew Boyer said:


> I also tagged it with 'kernel module'...


Heh. I see that now. Nothing to see here....


----------



## ralphbsz (Feb 7, 2020)

Andrew Boyer said:


> (It would let me reduce the diff between the linux and bsd versions of this driver.)


For that it is probably cleaner to make a small adaptation layer: Define a function or macro myalloc(), which then is defined using an ifdef. Or admit that to write an idiomatic piece of kernel code that fits cleanly into the host kernel, you'll have to use different programming styles and idioms.


----------

